<?php

if (!defined('ABSPATH')) {
    exit;
}

final class SPP_Activator
{
    private const DB_VERSION = '0.7.0';

    public static function activate(): void
    {
        self::install_schema();
        self::seed_templates();

        add_option('spp_proxmox_mode', 'mock');
        add_option('spp_proxmox_node', 'pve-01');
        add_option('spp_lxc_rootfs_storage', '');
        add_option('spp_lxc_bridge', 'vmbr0');
        add_option('spp_mock_next_vm_id', 10000);
        add_option('spp_quota_user_memory_mb', 0);
        add_option('spp_quota_global_memory_mb', 0);
        self::schedule_expiration_check();
        update_option('spp_db_version', self::DB_VERSION, false);
    }

    public static function deactivate(): void
    {
        wp_clear_scheduled_hook('spp_expire_deployments');
    }

    public static function maybe_upgrade(): void
    {
        if (get_option('spp_db_version') === self::DB_VERSION) {
            return;
        }

        self::install_schema();
        self::seed_templates();
        add_option('spp_quota_user_memory_mb', 0);
        add_option('spp_quota_global_memory_mb', 0);
        self::schedule_expiration_check();
        update_option('spp_db_version', self::DB_VERSION, false);
    }

    private static function install_schema(): void
    {
        global $wpdb;

        require_once ABSPATH . 'wp-admin/includes/upgrade.php';

        $charset_collate = $wpdb->get_charset_collate();
        $templates = self::table('templates');
        $deployments = self::table('deployments');
        $deployment_shares = self::table('deployment_shares');
        $audit_logs = self::table('audit_logs');

        dbDelta("CREATE TABLE {$templates} (
            id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            template_key varchar(80) NOT NULL,
            name varchar(160) NOT NULL,
            description text NOT NULL,
            os_type varchar(24) NOT NULL,
            cpu_cores int unsigned NOT NULL,
            memory_mb int unsigned NOT NULL,
            disk_gb int unsigned NOT NULL,
            default_ttl_hours int unsigned NOT NULL,
            provisioning_type varchar(16) NOT NULL DEFAULT 'qemu',
            proxmox_template_id int unsigned NOT NULL,
            proxmox_template_ref varchar(255) NULL,
            is_active tinyint(1) NOT NULL DEFAULT 1,
            created_at datetime NOT NULL,
            updated_at datetime NOT NULL,
            PRIMARY KEY  (id),
            UNIQUE KEY template_key (template_key)
        ) {$charset_collate};");

        dbDelta("CREATE TABLE {$deployments} (
            id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            name varchar(160) NOT NULL,
            status varchar(32) NOT NULL,
            provisioning_type varchar(16) NOT NULL DEFAULT 'qemu',
            proxmox_vm_id int unsigned DEFAULT NULL,
            ip_addresses longtext NULL,
            error_message text NULL,
            expires_at datetime NULL,
            created_at datetime NOT NULL,
            updated_at datetime NOT NULL,
            template_id bigint(20) unsigned NOT NULL,
            requested_by bigint(20) unsigned NOT NULL,
            PRIMARY KEY  (id),
            KEY status (status),
            KEY expires_at (expires_at),
            KEY template_id (template_id),
            KEY requested_by (requested_by)
        ) {$charset_collate};");

        $wpdb->query("ALTER TABLE {$deployments} MODIFY expires_at datetime NULL");

        self::add_column_if_missing($templates, 'provisioning_type', "ALTER TABLE {$templates} ADD COLUMN provisioning_type varchar(16) NOT NULL DEFAULT 'qemu' AFTER default_ttl_hours");
        self::add_column_if_missing($templates, 'proxmox_template_ref', "ALTER TABLE {$templates} ADD COLUMN proxmox_template_ref varchar(255) NULL AFTER proxmox_template_id");
        self::add_column_if_missing($deployments, 'provisioning_type', "ALTER TABLE {$deployments} ADD COLUMN provisioning_type varchar(16) NOT NULL DEFAULT 'qemu' AFTER status");

        $ip_column = $wpdb->get_var($wpdb->prepare("SHOW COLUMNS FROM {$deployments} LIKE %s", 'ip_addresses'));
        if ($ip_column === null) {
            $wpdb->query("ALTER TABLE {$deployments} ADD COLUMN ip_addresses longtext NULL AFTER proxmox_vm_id");
        }

        dbDelta("CREATE TABLE {$deployment_shares} (
            id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            deployment_id bigint(20) unsigned NOT NULL,
            user_id bigint(20) unsigned NOT NULL,
            created_by bigint(20) unsigned NOT NULL,
            created_at datetime NOT NULL,
            PRIMARY KEY  (id),
            UNIQUE KEY deployment_user (deployment_id, user_id),
            KEY deployment_id (deployment_id),
            KEY user_id (user_id)
        ) {$charset_collate};");

        dbDelta("CREATE TABLE {$audit_logs} (
            id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            action varchar(80) NOT NULL,
            entity_type varchar(80) NOT NULL,
            entity_id bigint(20) unsigned NOT NULL,
            actor_id bigint(20) unsigned NOT NULL,
            metadata longtext NULL,
            created_at datetime NOT NULL,
            PRIMARY KEY  (id),
            KEY entity_lookup (entity_type, entity_id),
            KEY created_at (created_at)
        ) {$charset_collate};");

    }

    private static function schedule_expiration_check(): void
    {
        if (!wp_next_scheduled('spp_expire_deployments')) {
            wp_schedule_event(time() + 5 * MINUTE_IN_SECONDS, 'hourly', 'spp_expire_deployments');
        }
    }

    public static function table(string $name): string
    {
        global $wpdb;

        return $wpdb->prefix . 'spp_' . $name;
    }

    private static function add_column_if_missing(string $table, string $column, string $sql): void
    {
        global $wpdb;

        $exists = $wpdb->get_var($wpdb->prepare("SHOW COLUMNS FROM {$table} LIKE %s", $column));
        if ($exists === null) {
            $wpdb->query($sql);
        }
    }

    private static function seed_templates(): void
    {
        global $wpdb;

        $table = self::table('templates');
        $now = current_time('mysql');
        $templates = [
            [
                'template_key' => 'turnkey-pbx-test',
                'name' => 'Turnkey PBX Test Appliance',
                'description' => 'Small PBX appliance for call-flow reproduction and support testing.',
                'os_type' => 'APPLIANCE',
                'cpu_cores' => 2,
                'memory_mb' => 2048,
                'disk_gb' => 24,
                'default_ttl_hours' => 72,
                'provisioning_type' => 'qemu',
                'proxmox_template_id' => 9001,
                'proxmox_template_ref' => null,
            ],
            [
                'template_key' => 'windows-support-client',
                'name' => 'Windows Support Client',
                'description' => 'Standard Windows client VM with support tooling pre-installed.',
                'os_type' => 'WINDOWS',
                'cpu_cores' => 4,
                'memory_mb' => 8192,
                'disk_gb' => 80,
                'default_ttl_hours' => 48,
                'provisioning_type' => 'qemu',
                'proxmox_template_id' => 9002,
                'proxmox_template_ref' => null,
            ],
            [
                'template_key' => 'linux-utility-vm',
                'name' => 'Linux Utility VM',
                'description' => 'Lightweight Linux host for network checks, packet capture, and diagnostics.',
                'os_type' => 'LINUX',
                'cpu_cores' => 2,
                'memory_mb' => 2048,
                'disk_gb' => 32,
                'default_ttl_hours' => 168,
                'provisioning_type' => 'qemu',
                'proxmox_template_id' => 9003,
                'proxmox_template_ref' => null,
            ],
        ];

        foreach ($templates as $template) {
            $exists = (int) $wpdb->get_var(
                $wpdb->prepare("SELECT id FROM {$table} WHERE template_key = %s", $template['template_key'])
            );

            $data = array_merge($template, [
                'is_active' => 1,
                'updated_at' => $now,
            ]);

            if ($exists > 0) {
                continue;
            }

            $wpdb->insert($table, array_merge($data, ['created_at' => $now]));
        }
    }
}
