<?php
/**
 * @package Hafenstudios\Wellenbrecher
 */

namespace Hafenstudios\Wellenbrecher\Install;

use Hafenstudios\Core\Db\Migrator;
use Hafenstudios\Core\Support\Capabilities;
use Hafenstudios\Wellenbrecher\Db\Schema;
use Hafenstudios\Wellenbrecher\Rules\RuleRegistry;

defined( 'ABSPATH' ) || exit;

/**
 * Aktivierung, Deaktivierung und Deinstallation.
 *
 * Aktivierung: Capabilities (inkl. neuem hs_manage_spam, idempotent nachziehbar
 * fuer Bestandsinstallationen der Flotte), Migrationen ueber den Core-Migrator
 * (hs_spam_log, hs_spam_stats), Default-Einstellungen, taeglicher Purge-Cron,
 * Start des Beobachtungsfensters.
 * Deaktivierung: nur Cron aufraeumen, Daten bleiben erhalten.
 * Deinstallation: loescht Daten NUR bei Setting privacy.delete_on_uninstall.
 */
final class Installer {

	public const CRON_HOOK = 'wellenbrecher_daily_purge';

	public const SETTINGS_OPTION = 'hs_wellenbrecher_settings';

	/**
	 * Default-Einstellungen des Plugins (Basis fuer den Core-Settings-Speicher).
	 *
	 * Zonen 0-39 durchlassen, 40-79 Quarantaene, ab 80 Block (Bauplan Kap. 6).
	 * Beobachtungsmodus Default AN fuer 7 Tage. Trusted-Proxy-Header Default
	 * leer = REMOTE_ADDR (ASB-2.11.4-Lehre). Jede Regel einzeln schalt- und
	 * gewichtbar unter rules.{id}.
	 *
	 * @return array<string, mixed>
	 */
	public static function default_settings(): array {
		return array(
			'zones'       => array(
				'quarantine' => 40,
				'block'      => 80,
			),
			'observation' => array(
				'enabled' => true,
				'days'    => 7,
			),
			'retention'   => array(
				'block_log_days'  => 7,
				'quarantine_days' => 30,
			),
			'proxy'       => array(
				'trusted_header' => '',
			),
			'xmlrpc'      => array(
				// Entfernt pingback.ping + wp.newComment (Bauplan Kap. 7.1).
				'disable_comments' => false,
			),
			// Rehabilitations-Allowlist: E-Mail-HMAC => Ablauf-Unix-Zeit (TTL 90 Tage).
			'allowlist'   => array(),
			'lists'       => array(
				// Fremde Schriftsysteme fuer die Skript-Analyse (konfigurierbar).
				'foreign_scripts' => array( 'Cyrillic', 'Han', 'Arabic', 'Hebrew', 'Thai' ),
				// Eigene Keyword-Liste des Betreibers (einfache Strings, Free).
				'custom_keywords' => array(),
			),
			'rules'       => RuleRegistry::default_rule_settings(),
			// Pro-Paket (W5a). Nur wirksam bei aktivem Pro-Gate (Support\ProGate);
			// mit inaktivem Gate bleiben diese Werte unbenutzt.
			'pro'         => array(
				// Bayes: lernt aus Moderation, aktiv erst ab 50 Ham + 50 Spam.
				'bayes' => array(
					'enabled'       => true,
					'ham_messages'  => 0,
					'spam_messages' => 0,
				),
				// Eskalierender Proof-of-Work: Opt-in (Default aus), nur fuer
				// vorbelastete IPs. difficulty = fuehrende Hex-Nullen.
				'pow'   => array(
					'enabled'    => false,
					'difficulty' => 4,
				),
				// W5b Opt-in-Externa. JEDES Feature einzeln Opt-in, Default AUS.
				// Ohne Opt-in verlaesst kein Byte die Site (Datenfluss-Hinweise in
				// der Admin-Seite "Externe Dienste"). Wirksam nur bei Pro-Gate.
				// DB-IP GeoIP/ASN (Technik A8): Opt-in-Download nach uploads,
				// Monats-Cron, Pflicht-Attribution "IP Geolocation by DB-IP".
				// Laenderliste Default LEER = CountryRule inaktiv (nie Hard-Block);
				// die Datacenter-ASN-Regel nutzt eine eingebettete Startliste.
				'geoip'      => array(
					'enabled'       => false,
					'countries'     => array(),
					'last_download' => 0,
				),
				// AbuseIPDB (Technik A9): BYO-Key (verschluesselt via Core-Secrets),
				// Abfrage nur im Graubereich, IP-Adresse geht an AbuseIPDB (USA).
				'abuseipdb'  => array(
					'enabled'       => false,
					'key_encrypted' => '',
				),
				// KI-Zweitmeinung (Bauplan 4.5 Nr. 2): eigenes Opt-in ZUSAETZLICH
				// zum Core-KI-Hauptschalter (hs_core_ai). Nutzt Core::instance()->ai().
				'ai'         => array(
					'enabled' => false,
				),
				// Disposable-Auto-Update (Technik A7): Wochen-Cron laedt die
				// strict-Liste und legt sie als Merge neben die gebundelte Liste.
				'disposable' => array(
					'enabled'     => false,
					'last_update' => 0,
				),
			),
			'privacy'     => array(
				'delete_on_uninstall' => false,
			),
		);
	}

	/**
	 * Plugin-Aktivierung.
	 *
	 * @return void
	 */
	public static function activate(): void {
		// Capabilities erneut installieren: idempotent, traegt hs_manage_spam
		// auch in Bestandsinstallationen von Leadlotse/Kurato nach (W0).
		Capabilities::install();

		// Eigene Tabellen ueber den Core-Migrator.
		self::migrate();

		// Default-Einstellungen nur setzen, wenn noch keine existieren.
		if ( false === get_option( self::SETTINGS_OPTION, false ) ) {
			add_option( self::SETTINGS_OPTION, self::default_settings() );
		}

		// Taeglicher Purge (DSGVO-Fristen, Default AN).
		if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
			wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', self::CRON_HOOK );
		}

		// Startpunkt des Beobachtungsfensters (7 Tage nur loggen).
		if ( false === get_option( 'wellenbrecher_activated_at', false ) ) {
			update_option( 'wellenbrecher_activated_at', time() );
		}
	}

	/**
	 * Fuehrt die Datenbank-Migrationen aus (auch bei Updates aufrufbar).
	 *
	 * @return void
	 */
	public static function migrate(): void {
		$migrator = new Migrator( 'wellenbrecher', Schema::DB_VERSION );
		Schema::register_migrations( $migrator );
		$migrator->run();
	}

	/**
	 * Plugin-Deaktivierung: Cron aufraeumen, Daten bleiben erhalten.
	 *
	 * @return void
	 */
	public static function deactivate(): void {
		wp_clear_scheduled_hook( self::CRON_HOOK );
		// W5b Opt-in-Externa-Crons (falls per Opt-in geplant).
		wp_clear_scheduled_hook( \Hafenstudios\Wellenbrecher\Pro\GeoIp\GeoDownloader::CRON_HOOK );
		wp_clear_scheduled_hook( \Hafenstudios\Wellenbrecher\Pro\Disposable\DisposableUpdater::CRON_HOOK );
	}

	/**
	 * Deinstallation (Aufruf aus uninstall.php). Loescht Daten nur, wenn das
	 * Setting privacy.delete_on_uninstall aktiv ist (Default aus).
	 *
	 * @return void
	 */
	public static function uninstall(): void {
		$settings = get_option( self::SETTINGS_OPTION, array() );
		$settings = is_array( $settings ) ? $settings : array();

		if ( empty( $settings['privacy']['delete_on_uninstall'] ) ) {
			return;
		}

		Schema::drop();
		( new Migrator( 'wellenbrecher', Schema::DB_VERSION ) )->reset();

		delete_option( self::SETTINGS_OPTION );
		delete_option( 'hs_wellenbrecher_logging' );
		delete_option( 'wellenbrecher_activated_at' );
		delete_option( 'wellenbrecher_ip_salt' );
		delete_option( 'wellenbrecher_swap_last_render' );

		// Capabilities/Rolle nur entfernen, wenn kein anderes Flotten-Plugin aktiv ist.
		if ( ! defined( 'KURATO_VERSION' ) && ! defined( 'LEADLOTSE_VERSION' ) ) {
			Capabilities::uninstall();
		}
	}
}
