<?php
/**
 * Small database schema helpers used by authentication flows.
 *
 * The methods are idempotent so they can safely run before generating
 * verification records in older installations.
 */
class DatabaseSchema {
    public static function verificacionDeUsuariosTableSql() {
        return "
            CREATE TABLE IF NOT EXISTS verificacion_de_usuarios (
                id INT AUTO_INCREMENT PRIMARY KEY,
                id_de_usuario INT NOT NULL,
                codigo VARCHAR(6) NULL,
                token VARCHAR(128) NULL,
                enlace_verificacion VARCHAR(512) NULL,
                expira_el DATETIME NOT NULL,
                consumido_el DATETIME NULL,
                creado_el DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_verificacion_usuario (id_de_usuario),
                INDEX idx_verificacion_codigo (codigo),
                INDEX idx_verificacion_token (token)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
        ";
    }

    public static function ensureVerificacionDeUsuariosTable($db) {
        $db->query(self::verificacionDeUsuariosTableSql());

        self::addColumnIfMissing($db, 'verificacion_de_usuarios', 'codigo', "ALTER TABLE verificacion_de_usuarios ADD COLUMN codigo VARCHAR(6) NULL AFTER id_de_usuario");
        self::addColumnIfMissing($db, 'verificacion_de_usuarios', 'token', "ALTER TABLE verificacion_de_usuarios ADD COLUMN token VARCHAR(128) NULL AFTER codigo");
        self::addColumnIfMissing($db, 'verificacion_de_usuarios', 'enlace_verificacion', "ALTER TABLE verificacion_de_usuarios ADD COLUMN enlace_verificacion VARCHAR(512) NULL AFTER token");
        self::addColumnIfMissing($db, 'verificacion_de_usuarios', 'expira_el', "ALTER TABLE verificacion_de_usuarios ADD COLUMN expira_el DATETIME NULL AFTER enlace_verificacion");
        self::addColumnIfMissing($db, 'verificacion_de_usuarios', 'consumido_el', "ALTER TABLE verificacion_de_usuarios ADD COLUMN consumido_el DATETIME NULL AFTER expira_el");
        self::addColumnIfMissing($db, 'verificacion_de_usuarios', 'creado_el', "ALTER TABLE verificacion_de_usuarios ADD COLUMN creado_el DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");

        self::addIndexIfMissing($db, 'verificacion_de_usuarios', 'idx_verificacion_usuario', "ALTER TABLE verificacion_de_usuarios ADD INDEX idx_verificacion_usuario (id_de_usuario)");
        self::addIndexIfMissing($db, 'verificacion_de_usuarios', 'idx_verificacion_codigo', "ALTER TABLE verificacion_de_usuarios ADD INDEX idx_verificacion_codigo (codigo)");
        self::addIndexIfMissing($db, 'verificacion_de_usuarios', 'idx_verificacion_token', "ALTER TABLE verificacion_de_usuarios ADD INDEX idx_verificacion_token (token)");
    }

    public static function ensureFirmasElectronicSignatureColumns($db) {
        self::addColumnIfMissing($db, 'firmas', 'tipo_de_firma', "ALTER TABLE firmas ADD COLUMN tipo_de_firma VARCHAR(40) NOT NULL DEFAULT 'electronica_pdf' AFTER estado_de_documento");
        self::addColumnIfMissing($db, 'firmas', 'hash_documento_original', "ALTER TABLE firmas ADD COLUMN hash_documento_original CHAR(64) NULL AFTER user_agent");
        self::addColumnIfMissing($db, 'firmas', 'hash_documento_firmado', "ALTER TABLE firmas ADD COLUMN hash_documento_firmado CHAR(64) NULL AFTER hash_documento_original");
        self::addColumnIfMissing($db, 'firmas', 'evidencia_firma', "ALTER TABLE firmas ADD COLUMN evidencia_firma LONGTEXT NULL AFTER hash_documento_firmado");

        self::addIndexIfMissing($db, 'firmas', 'idx_tipo_de_firma', "ALTER TABLE firmas ADD INDEX idx_tipo_de_firma (tipo_de_firma)");
        self::addIndexIfMissing($db, 'firmas', 'idx_hash_documento_firmado', "ALTER TABLE firmas ADD INDEX idx_hash_documento_firmado (hash_documento_firmado)");
    }

    private static function addColumnIfMissing($db, $table, $column, $sql) {
        if (self::columnExists($db, $table, $column)) {
            return;
        }
        $db->query($sql);
    }

    private static function addIndexIfMissing($db, $table, $index, $sql) {
        if (self::indexExists($db, $table, $index)) {
            return;
        }
        $db->query($sql);
    }

    private static function columnExists($db, $table, $column) {
        $stmt = $db->prepare("
            SELECT COUNT(*) AS total
            FROM INFORMATION_SCHEMA.COLUMNS
            WHERE TABLE_SCHEMA = DATABASE()
              AND TABLE_NAME = ?
              AND COLUMN_NAME = ?
        ");
        if (!$stmt) {
            return false;
        }
        $stmt->bind_param('ss', $table, $column);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        return !empty($row['total']);
    }

    private static function indexExists($db, $table, $index) {
        $stmt = $db->prepare("
            SELECT COUNT(*) AS total
            FROM INFORMATION_SCHEMA.STATISTICS
            WHERE TABLE_SCHEMA = DATABASE()
              AND TABLE_NAME = ?
              AND INDEX_NAME = ?
        ");
        if (!$stmt) {
            return false;
        }
        $stmt->bind_param('ss', $table, $index);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        return !empty($row['total']);
    }
}

function ensureDatabaseSchema($db) {
    DatabaseSchema::ensureVerificacionDeUsuariosTable($db);
    DatabaseSchema::ensureFirmasElectronicSignatureColumns($db);
}
?>
