<?php
/**
 * API optimizada para generar códigos de prueba
 * USA TABLA EXCLUSIVA trialspublic para los trials de la web pública
 * CORREGIDA: Solo considera trials NO CONVERTIDOS para bloqueos
 */

error_reporting(E_ALL);
ini_set('display_errors', '0'); // poner en 1 solo para debug

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// ======================
// CONFIGURACIÓN
// ======================
$TRIAL_HOURS = 5;      // Duración de la demo en horas
$BLOCK_DAYS = 3;       // Días bloqueado después de expirar

// ======================
// RESPUESTA JSON
// ======================
function sendResponse($data, $code = 200) {
    http_response_code($code);
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

// ======================
// VALIDAR MÉTODO
// ======================
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    sendResponse([
        'success' => false,
        'message' => 'Método no permitido'
    ], 405);
}

// ======================
// DATOS
// ======================
$name  = trim($_POST['name'] ?? '');
$phone = preg_replace('/\D+/', '', $_POST['phone'] ?? '');
$ip    = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';

// ======================
// VALIDACIONES
// ======================
if (strlen($name) < 2 || strlen($name) > 60) {
    sendResponse(['success' => false, 'message' => 'Nombre inválido'], 400);
}

if (strlen($phone) < 10 || strlen($phone) > 15) {
    sendResponse(['success' => false, 'message' => 'Teléfono inválido'], 400);
}

// ======================
// DB
// ======================
$dbFile = __DIR__ . '/.db.db';

try {
    $pdo = new PDO('sqlite:' . $dbFile, null, null, [
        PDO::ATTR_TIMEOUT => 3
    ]);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // ======================
    // CREAR TABLAS
    // ======================
    
    // Tabla codes (códigos generados)
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS codes (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            code TEXT UNIQUE,
            expires_at TEXT,
            owner TEXT NOT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            client_name TEXT,
            client_whatsapp TEXT,
            status TEXT DEFAULT 'active'
        );
    ");
    
    // Tabla EXCLUSIVA para trials públicos
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS trialspublic (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            phone TEXT NOT NULL,
            ip TEXT NOT NULL,
            name TEXT NOT NULL,
            code TEXT NOT NULL UNIQUE,
            created_ts INTEGER NOT NULL,
            expires_at TEXT NOT NULL,
            block_until_ts INTEGER DEFAULT 0,
            converted INTEGER DEFAULT 0,
            converted_at DATETIME,
            converted_to_owner TEXT
        );
    ");
    
    // Crear índices para mejorar rendimiento
    $pdo->exec("CREATE INDEX IF NOT EXISTS idx_trialspublic_ip ON trialspublic(ip)");
    $pdo->exec("CREATE INDEX IF NOT EXISTS idx_trialspublic_phone ON trialspublic(phone)");
    $pdo->exec("CREATE INDEX IF NOT EXISTS idx_trialspublic_code ON trialspublic(code)");
    $pdo->exec("CREATE INDEX IF NOT EXISTS idx_trialspublic_created ON trialspublic(created_ts)");

    // ======================
    // LIMPIAR REGISTROS MUY ANTIGUOS (más de 60 días)
    // ======================
    $pdo->exec("DELETE FROM trialspublic WHERE created_ts < " . (time() - (60 * 86400)));

    // ======================
    // ANTI-SPAM POR IP (máx 5 por minuto)
    // ======================
    $stmt = $pdo->prepare("
        SELECT COUNT(*) FROM trialspublic 
        WHERE ip = :ip 
        AND created_ts > :time
    ");
    $stmt->execute([
        ':ip' => $ip,
        ':time' => time() - 60
    ]);

    if ($stmt->fetchColumn() > 5) {
        sendResponse([
            'success' => false,
            'message' => 'Demasiadas solicitudes, intenta en un momento'
        ], 429);
    }

    // ======================
    // BLOQUEO POR TELÉFONO/IP (SOLO PARA TRIALS NO CONVERTIDOS)
    // ======================
    $stmt = $pdo->prepare("
        SELECT block_until_ts FROM trialspublic 
        WHERE (phone = :phone OR ip = :ip)
        AND converted = 0
        AND block_until_ts > :now
        ORDER BY id DESC LIMIT 1
    ");
    $stmt->execute([
        ':phone' => $phone,
        ':ip' => $ip,
        ':now' => time()
    ]);

    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($row && $row['block_until_ts'] > time()) {
        $remainingSeconds = $row['block_until_ts'] - time();
        $remainingDays = ceil($remainingSeconds / 86400);
        $remainingHours = ceil($remainingSeconds / 3600);
        
        $waitMessage = ($remainingDays > 0) 
            ? "Tu demo ya expiró. Debes esperar {$remainingDays} día(s) para solicitar una nueva demo."
            : "Tu demo ya expiró. Debes esperar {$remainingHours} hora(s) para solicitar una nueva demo.";
        
        sendResponse([
            'success' => false,
            'message' => $waitMessage,
            'blocked_until' => date('Y-m-d H:i:s', $row['block_until_ts']),
            'remaining_days' => $remainingDays,
            'remaining_hours' => $remainingHours
        ], 429);
    }

    // ======================
    // VERIFICAR SI YA TIENE UN TRIAL ACTIVO (NO EXPIRADO Y NO CONVERTIDO)
    // ======================
    $stmt = $pdo->prepare("
        SELECT code, expires_at FROM trialspublic 
        WHERE (phone = :phone OR ip = :ip)
        AND expires_at > datetime('now')
        AND converted = 0
        LIMIT 1
    ");
    $stmt->execute([
        ':phone' => $phone,
        ':ip' => $ip
    ]);
    
    $existingTrial = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if ($existingTrial) {
        sendResponse([
            'success' => true,
            'code' => $existingTrial['code'],
            'expires_at' => $existingTrial['expires_at'],
            'message' => 'Ya tienes un trial activo. Usa tu código existente.',
            'existing' => true
        ], 200);
    }

    // ======================
    // GENERAR CÓDIGO
    // ======================
    $code = null;

    for ($i = 0; $i < 10; $i++) {
        $temp = random_int(100000, 999999);

        $stmt = $pdo->prepare("SELECT id FROM codes WHERE code = :c");
        $stmt->execute([':c' => $temp]);

        if (!$stmt->fetch()) {
            $code = $temp;
            break;
        }
    }

    if (!$code) {
        sendResponse([
            'success' => false,
            'message' => 'Error generando código'
        ], 500);
    }

    // ======================
    // CALCULAR FECHAS
    // expires_at = cuando expira la demo (ahora + 5 horas)
    // block_until_ts = cuando termina el bloqueo (ahora + 5 horas + 3 días)
    // ======================
    $now = time();
    $expires = date('Y-m-d H:i:s', $now + ($TRIAL_HOURS * 3600));
    $blockUntil = $now + ($TRIAL_HOURS * 3600) + ($BLOCK_DAYS * 86400);

    // ======================
    // INICIAR TRANSACCIÓN
    // ======================
    $pdo->beginTransaction();

    try {
        // ======================
        // INSERTAR CÓDIGO EN TABLA CODES
        // ======================
        $stmt = $pdo->prepare("
            INSERT INTO codes (code, expires_at, owner, created_at, client_name, client_whatsapp, status) 
            VALUES (:code, :exp, :owner, :created_at, :client_name, :client_whatsapp, 'active')
        ");

        $stmt->execute([
            ':code' => $code,
            ':exp' => $expires,
            ':owner' => 'trial',
            ':created_at' => date('Y-m-d H:i:s'),
            ':client_name' => $name,
            ':client_whatsapp' => $phone
        ]);

        // ======================
        // INSERTAR REGISTRO EN TABLA TRIALSPUBLIC
        // ======================
        $stmt = $pdo->prepare("
            INSERT INTO trialspublic (
                phone, ip, name, code, created_ts, expires_at, block_until_ts, converted
            ) VALUES (
                :phone, :ip, :name, :code, :created_ts, :expires_at, :block_until_ts, 0
            )
        ");

        $stmt->execute([
            ':phone' => $phone,
            ':ip' => $ip,
            ':name' => $name,
            ':code' => $code,
            ':created_ts' => $now,
            ':expires_at' => $expires,
            ':block_until_ts' => $blockUntil
        ]);

        // ======================
        // CONFIRMAR TRANSACCIÓN
        // ======================
        $pdo->commit();

        // ======================
        // RESPUESTA EXITOSA
        // ======================
        sendResponse([
            'success' => true,
            'code' => $code,
            'expires_at' => $expires,
            'trial_hours' => $TRIAL_HOURS,
            'block_days' => $BLOCK_DAYS,
            'message' => "Demo generada. Válida por {$TRIAL_HOURS} horas. Luego quedarás bloqueado {$BLOCK_DAYS} días."
        ]);

    } catch (Exception $e) {
        // ======================
        // REVERTIR EN CASO DE ERROR
        // ======================
        $pdo->rollBack();
        throw $e;
    }

} catch (Exception $e) {
    // ======================
    // MANEJO DE ERRORES
    // ======================
    error_log("Error en generate_trial_code: " . $e->getMessage());
    
    sendResponse([
        'success' => false,
        'message' => 'Error interno del servidor'
    ], 500);

} finally {
    if (isset($pdo)) {
        $pdo = null;
    }
}
?>