<?php

namespace App\Models;

use App\Core\Database;
use App\Core\Security;

/**
 * ConversationState Model
 * Manages conversation states for multi-step bot flows.
 */
class ConversationState extends BaseModel
{
    protected static string $table = 'conversation_states';

    /**
     * Find active conversation state for a company and contact phone
     */
    public static function findActive(int $companyId, string $phone): ?array
    {
        self::ensureTableExists();
        $hash = Security::blindIndex($phone);
        $now = date('Y-m-d H:i:s');
        $state = Database::selectOne(
            "SELECT * FROM " . static::$table . " WHERE company_id = ? AND contact_phone_hash = ? AND expires_at > ? LIMIT 1",
            [$companyId, $hash, $now]
        );
        return self::decryptState($state);
    }

    /**
     * Save or update conversation state securely
     */
    public static function saveState(array $data): string
    {
        self::ensureTableExists();

        if (!empty($data['contact_phone'])) {
            $data['contact_phone_hash'] = Security::blindIndex($data['contact_phone']);
            $data['contact_phone'] = Security::encrypt($data['contact_phone']);
        }

        $existing = Database::selectOne(
            "SELECT id FROM " . static::$table . " WHERE company_id = ? AND contact_phone_hash = ? LIMIT 1",
            [$data['company_id'], $data['contact_phone_hash']]
        );

        if ($existing) {
            self::update($existing['id'], $data);
            return $existing['id'];
        } else {
            return self::create($data);
        }
    }

    /**
     * Delete conversation state by ID
     */
    public static function deleteState(int $id): int
    {
        self::ensureTableExists();
        return self::delete($id);
    }

    /**
     * Clean up all expired states
     */
    public static function cleanExpired(): void
    {
        self::ensureTableExists();
        try {
            $now = date('Y-m-d H:i:s');
            Database::execute("DELETE FROM " . static::$table . " WHERE expires_at < ?", [$now]);
        } catch (\Exception $e) {
            error_log("Failed to clean expired conversation states: " . $e->getMessage());
        }
    }

    /**
     * Helper to decrypt sensitive fields
     */
    private static function decryptState(?array $state): ?array
    {
        if ($state) {
            $state['contact_phone'] = !empty($state['contact_phone']) ? Security::decrypt($state['contact_phone']) : null;
        }
        return $state;
    }

    /**
     * Ensure the conversation_states table exists in the database
     */
    public static function ensureTableExists(): void
    {
        static $checked = false;
        if ($checked) return;

        try {
            Database::execute("
                CREATE TABLE IF NOT EXISTS `conversation_states` (
                    `id` INT AUTO_INCREMENT PRIMARY KEY,
                    `company_id` INT NOT NULL,
                    `contact_phone` VARCHAR(512) NOT NULL,
                    `contact_phone_hash` VARCHAR(64) NOT NULL,
                    `flow_name` VARCHAR(100) NOT NULL,
                    `current_step` VARCHAR(100) NOT NULL,
                    `context_data` JSON DEFAULT NULL,
                    `expires_at` TIMESTAMP NOT NULL,
                    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                    UNIQUE KEY `unique_company_contact` (`company_id`, `contact_phone_hash`),
                    FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE,
                    INDEX `idx_conv_expires` (`expires_at`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
            ");
            $checked = true;
        } catch (\Exception $e) {
            error_log("Failed to ensure conversation_states table: " . $e->getMessage());
        }
    }
}
