<?php
defined('ABSPATH') || exit;

// ══════════════════════════════════════════════════════════════════════════════
// IV1 WP Tools – Datei-Monitor: Cronjob, E-Mail-Benachrichtigung,
//                                Auto-Update-Erkennung (Pro only)
// ══════════════════════════════════════════════════════════════════════════════

define('IV1WPT_FILEMONITOR_SCHEDULE_OPTION', 'iv1wpt_filemonitor_schedule');
define('IV1WPT_FILEMONITOR_EMAIL_OPTION',    'iv1wpt_filemonitor_email');

// ─────────────────────────────────────────────────────────────────────────────
// Standard-Werte
// ─────────────────────────────────────────────────────────────────────────────

function iv1wpt_filemonitor_default_schedule(): array {
    return [
        'enabled'  => false,
        'interval' => 'daily',   // hourly | twicedaily | daily | weekly
        'hour'     => 6,          // Uhrzeit (0–23) für tägliche / wöchentliche Ausführung
    ];
}

function iv1wpt_filemonitor_default_email(): array {
    return [
        'recipient' => '',        // leer = WordPress-Admin-E-Mail
    ];
}

// ─────────────────────────────────────────────────────────────────────────────
// Cron-Hook registrieren / synchronisieren
// ─────────────────────────────────────────────────────────────────────────────

add_action('init', 'iv1wpt_filemonitor_sync_cron');

function iv1wpt_filemonitor_sync_cron(): void {
    if (!iv1wpt_has_pro()) {
        // Cron bei Pro-Downgrade sauber entfernen
        wp_clear_scheduled_hook('iv1wpt_cron_filemonitor');
        return;
    }

    $opts = get_option(IV1WPT_FILEMONITOR_SCHEDULE_OPTION, iv1wpt_filemonitor_default_schedule());

    if (empty($opts['enabled'])) {
        wp_clear_scheduled_hook('iv1wpt_cron_filemonitor');
        return;
    }

    $interval = $opts['interval'];
    $current  = wp_get_schedule('iv1wpt_cron_filemonitor');

    // Intervall geändert → neu planen
    if ($current && $current !== $interval) {
        wp_clear_scheduled_hook('iv1wpt_cron_filemonitor');
        $current = false;
    }

    if (!$current) {
        $start = iv1wpt_filemonitor_next_start((int) ($opts['hour'] ?? 6), $interval);
        wp_schedule_event($start, $interval, 'iv1wpt_cron_filemonitor');
    }
}

/**
 * Nächsten Startzeitpunkt berechnen.
 * Für hourly/twicedaily wird auf die nächste volle Stunde gerundet.
 * Für daily/weekly auf die eingestellte Uhrzeit.
 */
function iv1wpt_filemonitor_next_start(int $hour, string $interval): int {
    $tz   = wp_timezone();
    $now  = new DateTime('now', $tz);
    $next = clone $now;

    if (in_array($interval, ['hourly', 'twicedaily'], true)) {
        $next->modify('+1 hour');
        $next->setTime((int) $next->format('G'), 0, 0);
    } else {
        $next->setTime($hour, 0, 0);
        if ($next <= $now) {
            $next->modify('+1 day');
        }
    }

    return $next->getTimestamp();
}

// ─────────────────────────────────────────────────────────────────────────────
// Cron-Callback: Scan + E-Mail
// ─────────────────────────────────────────────────────────────────────────────

add_action('iv1wpt_cron_filemonitor', 'iv1wpt_filemonitor_cron_run');

function iv1wpt_filemonitor_cron_run(): void {
    if (!iv1wpt_has_pro()) {
        return;
    }

    $stored = get_option(IV1WPT_FILE_MONITOR_OPTION, []);

    // Noch keine Baseline → nur Baseline erstellen, keine E-Mail
    if (empty($stored['files']) || !is_array($stored['files'])) {
        $snapshot = iv1wpt_filemonitor_create_snapshot();
        update_option(IV1WPT_FILE_MONITOR_OPTION, [
            'created_at' => time(),
            'files'      => $snapshot,
        ], false);
        iv1wpt_plugin_log(__('File Monitor: No baseline found, created initial baseline automatically.', 'iv1-wp-tools'));
        return;
    }

    $old_snapshot = $stored['files'];
    $new_snapshot = iv1wpt_filemonitor_create_snapshot();
    $result       = iv1wpt_filemonitor_compare_snapshots($old_snapshot, $new_snapshot);

    $total_changes = count($result['added']) + count($result['changed']) + count($result['deleted']);

    if ($total_changes === 0) {
        iv1wpt_plugin_log(__('File Monitor Cron: No changes detected.', 'iv1-wp-tools'));
        return;
    }

    // Änderungen gefunden → E-Mail senden
    iv1wpt_filemonitor_send_alert($result);

    iv1wpt_plugin_log(sprintf(
        /* translators: %d: number of changed files */
        __('File Monitor Cron: %d change(s) detected, alert email sent.', 'iv1-wp-tools'),
        $total_changes
    ));
}

// ─────────────────────────────────────────────────────────────────────────────
// E-Mail-Benachrichtigung bei Änderungen
// ─────────────────────────────────────────────────────────────────────────────

function iv1wpt_filemonitor_send_alert(array $result): void {
    $email_opts = get_option(IV1WPT_FILEMONITOR_EMAIL_OPTION, iv1wpt_filemonitor_default_email());
    $to         = !empty($email_opts['recipient'])
        ? sanitize_email($email_opts['recipient'])
        : get_option('admin_email');

    if (empty($to)) {
        return;
    }

    $site_name = get_bloginfo('name');
    $site_url  = home_url();
    $time      = wp_date('d.m.Y H:i:s');

    /* translators: %s: site name */
    $subject = sprintf(__('[%s] File Monitor – Changes detected', 'iv1-wp-tools'), $site_name);

    $added   = $result['added']   ?? [];
    $changed = $result['changed'] ?? [];
    $deleted = $result['deleted'] ?? [];

    $body  = __('IV1 WP Tools – File Monitor Alert', 'iv1-wp-tools') . "\n";
    $body .= str_repeat('─', 50) . "\n\n";
    /* translators: %s: site name */
    $body .= sprintf(__('Website:   %s', 'iv1-wp-tools'), $site_name) . "\n";
    /* translators: %s: site URL */
    $body .= sprintf(__('URL:       %s', 'iv1-wp-tools'), $site_url) . "\n";
    /* translators: %s: date and time */
    $body .= sprintf(__('Time:      %s', 'iv1-wp-tools'), $time) . "\n\n";

    /* translators: %d: number of new files */
    $body .= sprintf(__('New files:     %d', 'iv1-wp-tools'), count($added)) . "\n";
    /* translators: %d: number of changed files */
    $body .= sprintf(__('Changed files: %d', 'iv1-wp-tools'), count($changed)) . "\n";
    /* translators: %d: number of deleted files */
    $body .= sprintf(__('Deleted files: %d', 'iv1-wp-tools'), count($deleted)) . "\n";
    $body .= "\n" . str_repeat('─', 50) . "\n\n";

    // Neue Dateien
    if (!empty($added)) {
        $body .= __('NEW FILES', 'iv1-wp-tools') . "\n";
        foreach (array_slice(array_keys($added), 0, 30) as $path) {
            $body .= "  + {$path}\n";
        }
        if (count($added) > 30) {
            /* translators: %d: number of additional files not shown */
            $body .= sprintf(__('  … and %d more.', 'iv1-wp-tools'), count($added) - 30) . "\n";
        }
        $body .= "\n";
    }

    // Geänderte Dateien
    if (!empty($changed)) {
        $body .= __('CHANGED FILES', 'iv1-wp-tools') . "\n";
        foreach (array_slice(array_keys($changed), 0, 30) as $path) {
            $body .= "  ~ {$path}\n";
        }
        if (count($changed) > 30) {
            $body .= sprintf(__('  … and %d more.', 'iv1-wp-tools'), count($changed) - 30) . "\n";
        }
        $body .= "\n";
    }

    // Gelöschte Dateien
    if (!empty($deleted)) {
        $body .= __('DELETED FILES', 'iv1-wp-tools') . "\n";
        foreach (array_slice(array_keys($deleted), 0, 30) as $path) {
            $body .= "  - {$path}\n";
        }
        if (count($deleted) > 30) {
            $body .= sprintf(__('  … and %d more.', 'iv1-wp-tools'), count($deleted) - 30) . "\n";
        }
        $body .= "\n";
    }

    $body .= str_repeat('─', 50) . "\n";
    /* translators: %s: plugin version */
    $body .= sprintf(__('IV1 WP Tools v%s', 'iv1-wp-tools'), IV1WPT_VERSION) . "\n";

    $headers = ['Content-Type: text/plain; charset=UTF-8'];
    $sent    = wp_mail($to, $subject, $body, $headers);

    if (!$sent) {
        iv1wpt_plugin_log(sprintf(
            /* translators: %s: recipient email address */
            __('File Monitor: Email sending failed to %s', 'iv1-wp-tools'),
            $to
        ));
    }
}

// ─────────────────────────────────────────────────────────────────────────────
// Automatische Baseline nach WordPress- oder Plugin-Updates
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Hook: Nach automatischem WordPress-Core-Update → neue Baseline
 * Wird von wp_automatic_updates_complete gefeuert, wenn mindestens
 * ein Core-Update durchgelaufen ist.
 */
add_action('automatic_updates_complete', 'iv1wpt_filemonitor_auto_baseline_after_update');

function iv1wpt_filemonitor_auto_baseline_after_update($results): void {
    if (!iv1wpt_has_pro()) {
        return;
    }

    // Prüfen ob tatsächlich etwas aktualisiert wurde
    $has_core   = !empty($results['core'])   && is_array($results['core']);
    $has_plugin = !empty($results['plugin']) && is_array($results['plugin']);
    $has_theme  = !empty($results['theme'])  && is_array($results['theme']);

    if (!$has_core && !$has_plugin && !$has_theme) {
        return;
    }

    iv1wpt_filemonitor_rebuild_baseline('auto_update');
}

/**
 * Hook: Nach manuellen Plugin-Updates über den Upgrader
 * (gilt auch für manuelle Bulk-Updates im Backend)
 */
add_action('upgrader_process_complete', 'iv1wpt_filemonitor_auto_baseline_after_upgrader', 10, 2);

function iv1wpt_filemonitor_auto_baseline_after_upgrader($upgrader, array $hook_extra): void {
    if (!iv1wpt_has_pro()) {
        return;
    }

    $type   = $hook_extra['type']   ?? '';
    $action = $hook_extra['action'] ?? '';

    // Nur bei Updates, nicht bei Neuinstallationen
    if ($action !== 'update') {
        return;
    }

    if (!in_array($type, ['plugin', 'theme', 'core'], true)) {
        return;
    }

    iv1wpt_filemonitor_rebuild_baseline('upgrader');
}

/**
 * Neue Baseline erstellen und im Log vermerken.
 *
 * @param string $trigger  Auslöser (für das Log): 'auto_update' | 'upgrader'
 */
function iv1wpt_filemonitor_rebuild_baseline(string $trigger): void {
    // Kurze Verzögerung damit der Upgrader alle Dateien fertig geschrieben hat.
    // Da wir im Cron-Kontext oder im Admin-Request sind, können wir sleep nutzen;
    // alternativ wird die Baseline beim nächsten Request gebaut – wir planen
    // einen einmaligen Cron-Event 30 Sekunden in der Zukunft.
    wp_schedule_single_event(time() + 30, 'iv1wpt_cron_filemonitor_rebuild_baseline');

    iv1wpt_plugin_log(sprintf(
        /* translators: %s: trigger source (auto_update or upgrader) */
        __('File Monitor: Baseline rebuild scheduled after update (trigger: %s).', 'iv1-wp-tools'),
        $trigger
    ));
}

// Einmaliger Cron-Callback für verzögertes Baseline-Rebuild
add_action('iv1wpt_cron_filemonitor_rebuild_baseline', 'iv1wpt_filemonitor_do_rebuild_baseline');

function iv1wpt_filemonitor_do_rebuild_baseline(): void {
    if (!iv1wpt_has_pro()) {
        return;
    }

    $snapshot = iv1wpt_filemonitor_create_snapshot();

    update_option(IV1WPT_FILE_MONITOR_OPTION, [
        'created_at'     => time(),
        'files'          => $snapshot,
        'auto_rebuilt'   => true,    // Markierung: automatisch neu erstellt
        'auto_rebuilt_at'=> time(),
    ], false);

    iv1wpt_plugin_log(sprintf(
        /* translators: %d: number of files in new baseline */
        __('File Monitor: Baseline automatically rebuilt after update (%d files).', 'iv1-wp-tools'),
        count($snapshot)
    ));
}

// ─────────────────────────────────────────────────────────────────────────────
// AJAX: Filemonitor-Schedule speichern
// ─────────────────────────────────────────────────────────────────────────────

add_action('wp_ajax_iv1wpt_save_filemonitor_schedule', 'iv1wpt_ajax_save_filemonitor_schedule');

function iv1wpt_ajax_save_filemonitor_schedule(): void {
    check_ajax_referer('iv1wpt_ajax', '_ajax_nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(__('No permission.', 'iv1-wp-tools'));
    }

    if (!iv1wpt_has_pro()) {
        wp_send_json_error(__('This feature requires IV1 WP Tools Pro.', 'iv1-wp-tools'));
    }

    $allowed_intervals = ['hourly', 'twicedaily', 'daily', 'weekly'];
    $interval          = sanitize_text_field($_POST['filemonitor_interval'] ?? 'daily');

    if (!in_array($interval, $allowed_intervals, true)) {
        $interval = 'daily';
    }

    $opts = [
        'enabled'  => !empty($_POST['filemonitor_enabled']),
        'interval' => $interval,
        'hour'     => min(23, max(0, absint($_POST['filemonitor_hour'] ?? 6))),
    ];

    update_option(IV1WPT_FILEMONITOR_SCHEDULE_OPTION, $opts);

    // Cron neu synchronisieren
    wp_clear_scheduled_hook('iv1wpt_cron_filemonitor');
    iv1wpt_filemonitor_sync_cron();

    $next_ts  = wp_next_scheduled('iv1wpt_cron_filemonitor');
    $next_str = $next_ts ? wp_date('d.m.Y H:i', $next_ts) : '—';

    wp_send_json_success([
        'message'  => __('File Monitor schedule saved.', 'iv1-wp-tools'),
        'next_run' => $next_str,
    ]);
}

// ─────────────────────────────────────────────────────────────────────────────
// AJAX: Filemonitor-E-Mail-Einstellungen speichern
// ─────────────────────────────────────────────────────────────────────────────

add_action('wp_ajax_iv1wpt_save_filemonitor_email', 'iv1wpt_ajax_save_filemonitor_email');

function iv1wpt_ajax_save_filemonitor_email(): void {
    check_ajax_referer('iv1wpt_ajax', '_ajax_nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(__('No permission.', 'iv1-wp-tools'));
    }

    if (!iv1wpt_has_pro()) {
        wp_send_json_error(__('This feature requires IV1 WP Tools Pro.', 'iv1-wp-tools'));
    }

    $email_opts = [
        'recipient' => sanitize_email($_POST['filemonitor_email_recipient'] ?? ''),
    ];

    update_option(IV1WPT_FILEMONITOR_EMAIL_OPTION, $email_opts);

    wp_send_json_success([
        'message' => __('File Monitor email settings saved.', 'iv1-wp-tools'),
    ]);
}

// ─────────────────────────────────────────────────────────────────────────────
// Deaktivierung: Cron-Events aufräumen
// ─────────────────────────────────────────────────────────────────────────────

add_action('iv1wpt_plugin_deactivate', function (): void {
    wp_clear_scheduled_hook('iv1wpt_cron_filemonitor');
    wp_clear_scheduled_hook('iv1wpt_cron_filemonitor_rebuild_baseline');
});
