<?php

namespace classes;

class replication_schema_bootstrap
{
    private static bool $initialized = false;

    public static function ensureTables(): void
    {
        if (self::$initialized) {
            return;
        }

        global $db;

        $queries = [
            "CREATE TABLE IF NOT EXISTS replication_hosts (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                kind VARCHAR(16) NOT NULL,
                label VARCHAR(128) NOT NULL,
                host VARCHAR(255) NOT NULL,
                port INT UNSIGNED NOT NULL,
                database_name VARCHAR(128) NULL,
                database_index INT NULL,
                username VARCHAR(128) NULL,
                password_secret TEXT NULL,
                admin_username VARCHAR(128) NULL,
                admin_password_secret TEXT NULL,
                replication_username VARCHAR(128) NULL,
                replication_password_secret TEXT NULL,
                role VARCHAR(16) NOT NULL DEFAULT 'replica',
                status VARCHAR(16) NOT NULL DEFAULT 'unknown',
                replication_source_id BIGINT UNSIGNED NULL,
                ssl_mode VARCHAR(32) NULL,
                options_json LONGTEXT NULL,
                last_status_json LONGTEXT NULL,
                last_checked_at DATETIME NULL,
                created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                deleted_at DATETIME NULL,
                INDEX idx_replication_hosts_kind_role (kind, role),
                INDEX idx_replication_hosts_kind_status (kind, status),
                INDEX idx_replication_hosts_source (replication_source_id),
                INDEX idx_replication_hosts_deleted_at (deleted_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
            "CREATE TABLE IF NOT EXISTS replication_operations (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                kind VARCHAR(16) NOT NULL,
                host_id BIGINT UNSIGNED NOT NULL,
                operation VARCHAR(32) NOT NULL,
                status VARCHAR(16) NOT NULL,
                progress_percent DECIMAL(5,2) NOT NULL DEFAULT 0.00,
                message VARCHAR(512) NULL,
                error_message TEXT NULL,
                context_json LONGTEXT NULL,
                actor_user_id INT NULL,
                started_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                completed_at DATETIME NULL,
                created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                INDEX idx_replication_operations_host (host_id),
                INDEX idx_replication_operations_kind_status (kind, status),
                INDEX idx_replication_operations_operation (operation)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
            "CREATE TABLE IF NOT EXISTS replication_status_snapshots (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                host_id BIGINT UNSIGNED NOT NULL,
                kind VARCHAR(16) NOT NULL,
                status VARCHAR(16) NOT NULL,
                replication_percent DECIMAL(5,2) NOT NULL DEFAULT 0.00,
                lag_seconds INT NULL,
                blockers_json LONGTEXT NULL,
                raw_status_json LONGTEXT NULL,
                checked_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_replication_status_host_checked (host_id, checked_at),
                INDEX idx_replication_status_kind_checked (kind, checked_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
            "CREATE TABLE IF NOT EXISTS replication_audit_logs (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                kind VARCHAR(16) NOT NULL,
                host_id BIGINT UNSIGNED NULL,
                action VARCHAR(64) NOT NULL,
                actor_user_id INT NULL,
                severity VARCHAR(16) NOT NULL DEFAULT 'info',
                context_json LONGTEXT NULL,
                created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_replication_audit_kind_host (kind, host_id),
                INDEX idx_replication_audit_action (action),
                INDEX idx_replication_audit_created_at (created_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
        ];

        foreach ($queries as $sql) {
            $db->query($sql);
        }

        self::ensureColumn('replication_operations', 'progress_percent', "DECIMAL(5,2) NOT NULL DEFAULT 0.00");
        self::ensureColumn('replication_operations', 'message', 'VARCHAR(512) NULL');
        self::ensureColumn('replication_operations', 'context_json', 'LONGTEXT NULL');

        self::$initialized = true;
    }

    private static function ensureColumn(string $table, string $column, string $definition): void
    {
        global $db;

        $table = preg_replace('/[^a-zA-Z0-9_]/', '', $table);
        $column = preg_replace('/[^a-zA-Z0-9_]/', '', $column);
        if ($table === '' || $column === '') {
            return;
        }

        $result = $db->query("SHOW COLUMNS FROM `$table` LIKE '$column'");
        if ($result !== false && $result->num_rows > 0) {
            return;
        }

        $db->query("ALTER TABLE `$table` ADD COLUMN `$column` $definition");
    }
}
