<?php
/**
 * API optimizada para generar códigos de prueba
 * USA TABLA EXCLUSIVA trialspublic para los trials de la web pública
 */

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();
}

// ======================
// 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 (SEPARADA de la otra)
    $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,
            UNIQUE(phone, ip)
        );
    ");
    
    // 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)");

    // ======================
    // 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
    // ======================
    $stmt = $pdo->prepare("
        SELECT block_until_ts FROM trialspublic 
        WHERE (phone = :phone OR ip = :ip)
        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()) {
        sendResponse([
            'success' => false,
            'message' => 'Ya generaste un código, intenta más tarde'
        ], 429);
    }

    // ======================
    // VERIFICAR SI YA TIENE UN TRIAL ACTIVO
    // ======================
    $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);
    }

    // ======================
    // EXPIRACIÓN (5 HORAS)
    // ======================
    $seconds = 5 * 3600;
    $expires = date('Y-m-d H:i:s', time() + $seconds);

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

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

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

        // ======================
        // 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' => time(),
            ':expires_at' => $expires,
            ':block_until_ts' => time() + (3 * 86400) // 30 días de bloqueo
        ]);

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

        // ======================
        // RESPUESTA EXITOSA
        // ======================
        sendResponse([
            'success' => true,
            'code' => $code,
            'expires_at' => $expires,
            'message' => 'Código de prueba generado exitosamente'
        ]);

    } 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;
    }
}
?>