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

namespace Hafenstudios\Kurato\Install;

use Hafenstudios\Core\Consent\ConsentLog;
use Hafenstudios\Core\Core;
use Hafenstudios\Core\Db\Migrator;
use Hafenstudios\Core\Support\Capabilities;
use Hafenstudios\Kurato\Booking\BookingReminders;
use Hafenstudios\Kurato\Cockpit\CockpitRole;
use Hafenstudios\Kurato\Db\ListRepository;
use Hafenstudios\Kurato\Db\Schema;
use Hafenstudios\Kurato\Db\StageRepository;
use Hafenstudios\Kurato\Insight\OutcomeTracker;
use Hafenstudios\Kurato\Mail\QueueScheduler;
use Hafenstudios\Kurato\Site\BookingPage;

defined( 'ABSPATH' ) || exit;

/**
 * Aktivierung, Deaktivierung und Deinstallation von Kurato.
 *
 * Aktivierung: Flotten-Capabilities (inkl. der Kontakt-Rechte), Consent-Tabelle
 * des Core, Migrationen (CRM-Kern-Tabellen), Default-Pipeline-Stufen und
 * Default-Einstellungen. Deinstallation loescht Daten nur bei aktivem Setting
 * privacy.delete_on_uninstall (Default aus).
 */
final class Installer {

	public const SETTINGS_OPTION = 'hs_kurato_settings';

	public const CRON_HOOK = 'kurato_daily_maintenance';

	/**
	 * Default-Einstellungen des Plugins.
	 *
	 * @return array<string, mixed>
	 */
	public static function default_settings(): array {
		return array(
			'address_form' => 'sie', // "sie" oder "du".
			'intake'       => array(
				'from_leadlotse' => true, // Leadlotse-Anfragen automatisch uebernehmen.
			),
			'sender'       => array(
				'from_name'  => '',
				'from_email' => '',
			),
			'mail'         => array(
				'transport'     => 'wp_mail', // wp_mail | smtp | brevo | postmark | mailgun | smtp2go | ses.
				'rate_per_hour' => 200,       // Durchsatz-Drosselung der Marketing-Queue.
				'sender'        => array(
					'from_name'  => '',
					'from_email' => '',
				),
				'dkim_selector' => '',        // Freier DKIM-Selektor (v.a. fuer SMTP).
				'brevo'         => array( 'api_key' => '' ),
				'postmark'      => array( 'token' => '' ),
				'mailgun'       => array( 'api_key' => '', 'domain' => '', 'region' => 'us' ),
				'smtp2go'       => array( 'api_key' => '' ),
				'ses'           => array( 'access_key' => '', 'secret_key' => '', 'region' => 'eu-central-1' ),
				'smtp'          => array(),
			),
			'dns'          => array(
				'doh_enabled' => false, // DNS-over-HTTPS erst nach ausdruecklicher Freischaltung.
			),
			'tracking'     => array(
				'enabled' => false, // Site-Schalter Open-/Klick-Messung (K4e-2); Default aus (CNIL-Linie).
			),
			'welcome'      => array(
				'enabled' => false, // Willkommensmail bei Abo-Bestaetigung (K4e-2); Default aus.
				'post_id' => 0,     // hs_mail-Post als Inhalt der Willkommensmail.
			),
			'webhook'      => array(
				'brevo_secret' => '', // Bei Aktivierung erzeugt; sichert den Inbound-Webhook.
			),
			'privacy'      => array(
				'delete_on_uninstall'  => false,
				'retention_months'     => 0,
				'event_retention_days' => 365, // Aufbewahrung der Mail-Ereignisse (K4e-1).
			),
			'booking'      => array(
				'reminder_hours'  => 24,   // Erinnerung X h vor dem Termin (0 = aus).
				'reminder_host'   => true, // Erinnerung an Besucher UND Host (Inhaber-Entscheidung K5).
				'retention_days'  => 365,  // Aufbewahrung vergangener Buchungen.
				'stage_id'        => 0,    // 0 = Stufen-Automatik aus (Inhaber-Entscheidung K5).
			),
		);
	}

	/**
	 * Plugin-Aktivierung.
	 *
	 * @return void
	 */
	public static function activate(): void {
		Capabilities::install();
		ConsentLog::install();

		// Connector-Rolle kurato_agent (CP1). Idempotent und selbstheilend.
		CockpitRole::install();

		self::migrate();

		// Default-Pipeline-Stufen und Default-Newsletter-Liste anlegen (nur beim ersten Mal).
		( new StageRepository() )->install_defaults();
		( new ListRepository() )->ensure_default();

		if ( false === get_option( self::SETTINGS_OPTION, false ) ) {
			add_option( self::SETTINGS_OPTION, self::default_settings() );
		}

		// Einmaliges Secret fuer den Inbound-Webhook erzeugen (K4e-1). Wird in der
		// Webhook-URL mitgefuehrt und gegen dieses Setting per hash_equals geprueft.
		$settings = Core::instance()->settings( 'kurato', self::default_settings() );
		if ( '' === (string) $settings->get( 'webhook.brevo_secret', '' ) ) {
			$settings->set( 'webhook.brevo_secret', wp_generate_password( 40, false ) );
		}

		if ( false === get_option( 'kurato_activated_at', false ) ) {
			update_option( 'kurato_activated_at', time() );
			update_option( 'kurato_needs_onboarding', 1 );
		}

		// Taegliche Wartung (Aufbewahrungsfrist der Kontakte und Buchungen).
		if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
			wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', self::CRON_HOOK );
		}

		// Stuendlicher Erinnerungs-Cron des Buchungsmoduls (K5c).
		if ( ! wp_next_scheduled( BookingReminders::HOOK ) ) {
			wp_schedule_event( time() + HOUR_IN_SECONDS, 'hourly', BookingReminders::HOOK );
		}

		// Taeglicher Outcome-Mess-Cron der Empfehlungen (H2, Schicht 4).
		if ( ! wp_next_scheduled( OutcomeTracker::HOOK ) ) {
			wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', OutcomeTracker::HOOK );
		}

		// Rewrite-Regel `/termin/{slug}` registrieren und die Regeln neu schreiben,
		// damit die oeffentliche Buchungsseite sofort erreichbar ist (K5c).
		BookingPage::add_rewrite_rules();
		flush_rewrite_rules();
	}

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

	/**
	 * Plugin-Deaktivierung.
	 *
	 * @return void
	 */
	public static function deactivate(): void {
		wp_clear_scheduled_hook( self::CRON_HOOK );
		wp_clear_scheduled_hook( BookingReminders::HOOK );
		wp_clear_scheduled_hook( OutcomeTracker::HOOK );
		( new QueueScheduler() )->unschedule();
		flush_rewrite_rules();
	}

	/**
	 * Deinstallation (Aufruf aus uninstall.php).
	 *
	 * @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( 'kurato', Schema::DB_VERSION ) )->reset();

		delete_option( self::SETTINGS_OPTION );
		delete_option( 'kurato_activated_at' );
		delete_option( 'kurato_needs_onboarding' );
		delete_option( \Hafenstudios\Kurato\Admin\ProArea::OPTION );
		delete_option( \Hafenstudios\Kurato\Cockpit\Config::OPTION );

		// Connector-Rolle nur bei vollstaendiger Deinstallation entfernen.
		CockpitRole::remove();

		// Gemeinsame Capabilities nur entfernen, wenn kein weiteres Flotten-Plugin
		// mehr aktiv ist (Leadlotse haelt sie sonst weiter).
		if ( ! defined( 'LEADLOTSE_VERSION' ) ) {
			Capabilities::uninstall();
		}
	}
}
