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

namespace Hafenstudios\Wellenbrecher\Db;

defined( 'ABSPATH' ) || exit;

/**
 * Zentrale Schema-Definition fuer Wellenbrecher (WELLENBRECHER-BAUPLAN Kap. 5).
 *
 * Tabellen 1.0.0:
 * - hs_spam_log    Einzelereignisse, kurzlebig (Block-Log, Quarantaene, Beobachtung)
 * - hs_spam_stats  Langzeit-Tageszaehler ohne Personenbezug (ueberlebt jeden Purge)
 *
 * Tabellen 1.1.0 (W5a):
 * - hs_spam_tokens Bayes-Token-Zaehler (Pro), ohne PII (nur Domains statt Adressen)
 *
 * Datenschutz-Grundsatz: nie Klartext-IP (nur HMAC mit rotierendem Wochen-Salt),
 * nie komplette E-Mail-Adressen (nur Domain), Snippets gekuerzt.
 */
final class Schema {

	public const DB_VERSION = '1.1.0';

	/**
	 * Voller Tabellenname fuer einen Kurznamen (z.B. "spam_log").
	 *
	 * @param string $name Kurzname ohne Praefix und ohne hs_.
	 * @return string
	 */
	public static function table( string $name ): string {
		global $wpdb;
		return $wpdb->prefix . 'hs_' . $name;
	}

	/**
	 * Registriert alle Migrationen am Core-Migrator (Namespace wellenbrecher,
	 * Schemaversion in hs_wellenbrecher_db_version).
	 *
	 * @param \Hafenstudios\Core\Db\Migrator $migrator Core-Migrator.
	 * @return void
	 */
	public static function register_migrations( $migrator ): void {
		$migrator->register( '1.0.0', array( self::class, 'migrate_1_0_0' ) );
		$migrator->register( '1.1.0', array( self::class, 'migrate_1_1_0' ) );
	}

	/**
	 * Legt hs_spam_log und hs_spam_stats an.
	 *
	 * @param \wpdb  $wpdb            WordPress-Datenbank.
	 * @param string $charset_collate Charset/Collation-Klausel.
	 * @return void
	 */
	public static function migrate_1_0_0( $wpdb, string $charset_collate ): void {
		$log   = self::table( 'spam_log' );
		$stats = self::table( 'spam_stats' );

		dbDelta(
			"CREATE TABLE {$log} (
				id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
				channel VARCHAR(32) NOT NULL,
				verdict VARCHAR(16) NOT NULL,
				score SMALLINT NOT NULL,
				reasons TEXT NOT NULL,
				ip_hmac CHAR(64) NULL,
				email_domain VARCHAR(191) NULL,
				excerpt VARCHAR(500) NULL,
				payload LONGTEXT NULL,
				form_id BIGINT UNSIGNED NULL,
				comment_id BIGINT UNSIGNED NULL,
				created_at DATETIME NOT NULL,
				PRIMARY KEY  (id),
				KEY channel (channel),
				KEY verdict (verdict),
				KEY created_at (created_at)
			) {$charset_collate};"
		);

		dbDelta(
			"CREATE TABLE {$stats} (
				stat_date DATE NOT NULL,
				channel VARCHAR(32) NOT NULL,
				verdict VARCHAR(16) NOT NULL,
				cnt INT UNSIGNED NOT NULL DEFAULT 0,
				PRIMARY KEY  (stat_date, channel, verdict)
			) {$charset_collate};"
		);
	}

	/**
	 * Legt hs_spam_tokens an (Pro/Bayes, W5a). token als Primaerschluessel
	 * (VARCHAR(191) passt in einen utf8mb4-Index), ham/spam als Zaehler.
	 *
	 * @param \wpdb  $wpdb            WordPress-Datenbank.
	 * @param string $charset_collate Charset/Collation-Klausel.
	 * @return void
	 */
	public static function migrate_1_1_0( $wpdb, string $charset_collate ): void {
		$tokens = self::table( 'spam_tokens' );

		dbDelta(
			"CREATE TABLE {$tokens} (
				token VARCHAR(191) NOT NULL,
				ham_count INT UNSIGNED NOT NULL DEFAULT 0,
				spam_count INT UNSIGNED NOT NULL DEFAULT 0,
				PRIMARY KEY  (token)
			) {$charset_collate};"
		);
	}

	/**
	 * Entfernt die Tabellen (nur bei Deinstallation mit Datenloeschung).
	 *
	 * @return void
	 */
	public static function drop(): void {
		global $wpdb;
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Tabellennamen aus eigener Definition.
		$wpdb->query( 'DROP TABLE IF EXISTS ' . self::table( 'spam_log' ) );
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Tabellennamen aus eigener Definition.
		$wpdb->query( 'DROP TABLE IF EXISTS ' . self::table( 'spam_stats' ) );
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Tabellennamen aus eigener Definition.
		$wpdb->query( 'DROP TABLE IF EXISTS ' . self::table( 'spam_tokens' ) );
	}
}
