<?php

namespace classes;

/**
 * Ensures additive schema for XL Vask usage-log review state.
 */
class xlvask_usage_logs_schema_bootstrap
{
    private static bool $initialized = false;

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

        global $db;

        if (!isset($db) || !is_object($db) || !method_exists($db, 'query')) {
            return;
        }

        if (!self::tableExists($db, 'xlvask_usage_logs')) {
            return;
        }

        self::addColumnIfMissing($db, 'xlvask_usage_logs', 'ignored_at', 'DATETIME NULL AFTER WashItems');
        self::addColumnIfMissing($db, 'xlvask_usage_logs', 'ignored_by', 'INT NULL AFTER ignored_at');
        self::addColumnIfMissing($db, 'xlvask_usage_logs', 'ignored_reason', 'TEXT NULL AFTER ignored_by');
        self::addColumnIfMissing($db, 'xlvask_usage_logs', 'cached_total_net_amount', 'DECIMAL(12,2) NULL AFTER ignored_reason');
        self::addColumnIfMissing($db, 'xlvask_usage_logs', 'cached_primary_product_name', 'VARCHAR(255) NULL AFTER cached_total_net_amount');
        self::addColumnIfMissing($db, 'xlvask_usage_logs', 'cached_amount_at', 'DATETIME NULL AFTER cached_primary_product_name');
        self::ensureAutomationTables($db);

        self::$initialized = true;
    }

    private static function ensureAutomationTables(object $db): void
    {
        $db->query(
            "CREATE TABLE IF NOT EXISTS `xlvask_automation_suggestions` (
                `id` INT NOT NULL AUTO_INCREMENT,
                `usage_log_id` INT NOT NULL,
                `wash_id` VARCHAR(128) NOT NULL,
                `signature_hash` CHAR(64) NOT NULL,
                `signature_json` LONGTEXT NULL,
                `action` VARCHAR(32) NOT NULL,
                `status` VARCHAR(32) NOT NULL DEFAULT 'suggested',
                `confidence` DECIMAL(5,4) NOT NULL DEFAULT 0.0000,
                `source` VARCHAR(32) NOT NULL DEFAULT 'deterministic',
                `matched_order_id` INT NULL,
                `created_order_id` INT NULL,
                `proposed_order_json` LONGTEXT NULL,
                `candidate_order_json` LONGTEXT NULL,
                `reason` TEXT NULL,
                `created_by` INT NULL,
                `decided_by` INT NULL,
                `decided_at` DATETIME NULL,
                `executed_at` DATETIME NULL,
                `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (`id`),
                KEY `idx_xlvask_automation_usage` (`usage_log_id`),
                KEY `idx_xlvask_automation_wash` (`wash_id`),
                KEY `idx_xlvask_automation_signature` (`signature_hash`),
                KEY `idx_xlvask_automation_status` (`status`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
        );

        $db->query(
            "CREATE TABLE IF NOT EXISTS `xlvask_automation_feedback` (
                `id` INT NOT NULL AUTO_INCREMENT,
                `usage_log_id` INT NULL,
                `wash_id` VARCHAR(128) NULL,
                `signature_hash` CHAR(64) NOT NULL,
                `signature_json` LONGTEXT NULL,
                `action` VARCHAR(32) NOT NULL,
                `decision` VARCHAR(32) NOT NULL,
                `order_id` INT NULL,
                `reason` TEXT NULL,
                `created_by` INT NULL,
                `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (`id`),
                KEY `idx_xlvask_feedback_signature_action` (`signature_hash`, `action`),
                KEY `idx_xlvask_feedback_usage` (`usage_log_id`),
                KEY `idx_xlvask_feedback_decision` (`decision`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
        );

        $db->query(
            "CREATE TABLE IF NOT EXISTS `xlvask_automation_openai_cache` (
                `id` INT NOT NULL AUTO_INCREMENT,
                `cache_key` CHAR(64) NOT NULL,
                `schema_name` VARCHAR(96) NOT NULL,
                `input_json` LONGTEXT NOT NULL,
                `result_json` LONGTEXT NOT NULL,
                `hits` INT NOT NULL DEFAULT 0,
                `last_hit_at` DATETIME NULL,
                `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (`id`),
                UNIQUE KEY `uniq_xlvask_openai_cache_key` (`cache_key`),
                KEY `idx_xlvask_openai_cache_schema` (`schema_name`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
        );
    }

    private static function addColumnIfMissing(object $db, string $table, string $column, string $definition): void
    {
        if (!self::columnExists($db, $table, $column)) {
            $db->query("ALTER TABLE `{$table}` ADD COLUMN `{$column}` {$definition}");
        }
    }

    private static function tableExists(object $db, string $table): bool
    {
        $table = self::escapeIdentifier($table);
        $result = $db->query("SHOW TABLES LIKE '{$table}'");

        if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
            return false;
        }

        return (int)$result->num_rows > 0;
    }

    private static function columnExists(object $db, string $table, string $column): bool
    {
        $table = self::escapeIdentifier($table);
        $column = self::escapeIdentifier($column);
        $result = $db->query("SHOW COLUMNS FROM `{$table}` LIKE '{$column}'");

        if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
            return false;
        }

        return (int)$result->num_rows > 0;
    }

    private static function escapeIdentifier(string $value): string
    {
        return str_replace(['\\', "'", '`'], ['\\\\', "\\'", ''], $value);
    }
}
