<?php

class URLShortener {
    private $db;
    private $logger;
    private $baseUrl;

    public function __construct() {
        require_once __DIR__ . '/../config/database.php';
        require_once __DIR__ . '/Logger.php';

        $this->db = new Database();
        $this->logger = new Logger();

        // Detectar la URL base correctamente incluyendo subdirectorio
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
            || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
            ? 'https://' : 'http://';
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';

        // Detectar subdirectorio basado en la ubicación del script
        $scriptPath = $_SERVER['SCRIPT_NAME'] ?? '';
        $subPath = '';

        // Extraer subdirectorio del script path
        if (strpos($scriptPath, '/') !== false) {
            $parts = explode('/', trim($scriptPath, '/'));
            // Si hay partes antes del archivo .php, es un subdirectorio
            if (count($parts) > 1) {
                array_pop($parts); // Remover el nombre del archivo
                $subPath = '/' . $parts[0]; // Tomar solo el primer nivel (segurosapi)
            }
        }

        $this->baseUrl = $protocol . $host . $subPath;
    }

    /**
     * Genera un token seguro único para descarga de póliza
     */
    public function generarTokenDescarga($transactionId, $expirationHours = 720) {
        try {
            // Generar token único
            $token = bin2hex(random_bytes(16));
            $expiresAt = date('Y-m-d H:i:s', strtotime("+{$expirationHours} hours"));

            // Guardar en base de datos
            $conn = $this->db->connect();
            $stmt = $conn->prepare("
                INSERT INTO tokens_descarga (token, transaccion_id, expira_at, created_at)
                VALUES (?, ?, ?, NOW())
                ON DUPLICATE KEY UPDATE token = VALUES(token), expira_at = VALUES(expira_at)
            ");
            $stmt->execute([$token, $transactionId, $expiresAt]);

            $this->logger->info('Token de descarga generado', [
                'transaction_id' => $transactionId,
                'token' => substr($token, 0, 8) . '...',
                'expira_at' => $expiresAt
            ], $transactionId);

            return $token;

        } catch (Exception $e) {
            $this->logger->error('Error generando token de descarga', [
                'error' => $e->getMessage(),
                'transaction_id' => $transactionId
            ], $transactionId);
            throw $e;
        }
    }

    /**
     * Valida un token de descarga
     */
    public function validarToken($token) {
        try {
            $conn = $this->db->connect();
            $stmt = $conn->prepare("
                SELECT transaccion_id, expira_at, usado
                FROM tokens_descarga
                WHERE token = ? AND expira_at > NOW()
            ");
            $stmt->execute([$token]);
            $result = $stmt->fetch();

            if (!$result) {
                $this->logger->warning('Token inválido o expirado', [
                    'token' => substr($token, 0, 8) . '...'
                ]);
                return false;
            }

            return $result;

        } catch (Exception $e) {
            $this->logger->error('Error validando token', [
                'error' => $e->getMessage()
            ]);
            return false;
        }
    }

    /**
     * Marca un token como usado
     */
    public function marcarTokenUsado($token) {
        try {
            $conn = $this->db->connect();
            $stmt = $conn->prepare("
                UPDATE tokens_descarga
                SET usado = usado + 1, ultimo_uso = NOW()
                WHERE token = ?
            ");
            $stmt->execute([$token]);

        } catch (Exception $e) {
            $this->logger->error('Error marcando token usado', [
                'error' => $e->getMessage()
            ]);
        }
    }

    /**
     * Genera URL corta para descarga de póliza
     */
    public function generarURLCorta($transactionId) {
        $token = $this->generarTokenDescarga($transactionId);
        return $this->baseUrl . '/p/' . $token;
    }

    /**
     * Genera URL corta alternativa (por si /p/ no funciona)
     */
    public function generarURLCortaAlternativa($transactionId) {
        $token = $this->generarTokenDescarga($transactionId);
        return $this->baseUrl . '/download.php?t=' . $token;
    }
}
