<?php
header('Content-Type: application/json; charset=utf-8');

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

if (!file_exists($dbFile)) {
    echo json_encode(["ok" => false, "reason" => "db_not_found"]);
    exit;
}

$code = isset($_POST['code']) ? trim($_POST['code']) : (isset($_GET['code']) ? trim($_GET['code']) : '');
if ($code === '') {
    echo json_encode(["ok" => false, "reason" => "missing_code"]);
    exit;
}

function request_value(array $names): string {
    foreach ($names as $n) {
        if (isset($_POST[$n]) && trim((string)$_POST[$n]) !== '') return trim((string)$_POST[$n]);
        if (isset($_GET[$n]) && trim((string)$_GET[$n]) !== '') return trim((string)$_GET[$n]);
    }
    return '';
}

try {
    $pdo = new PDO('sqlite:' . $dbFile);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

    $pdo->exec("CREATE TABLE IF NOT EXISTS code_devices (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        code_id INTEGER NOT NULL,
        code TEXT NOT NULL,
        device_id TEXT NOT NULL,
        ip TEXT,
        user_agent TEXT,
        first_seen TEXT DEFAULT CURRENT_TIMESTAMP,
        last_seen TEXT DEFAULT CURRENT_TIMESTAMP,
        UNIQUE(code_id, device_id)
    )");

    $cols = $pdo->query("PRAGMA table_info(codes)")->fetchAll();
    $hasMax = false;
    foreach ($cols as $col) {
        if (($col['name'] ?? '') === 'max_devices') $hasMax = true;
    }
    if (!$hasMax) {
        $pdo->exec("ALTER TABLE codes ADD COLUMN max_devices INTEGER DEFAULT 5");
        $pdo->exec("UPDATE codes SET max_devices = 5 WHERE max_devices IS NULL OR max_devices < 1");
    }

    $stmt = $pdo->prepare("SELECT id, code, expires_at, status, max_devices, is_demo, demo_hours FROM codes WHERE code = :code LIMIT 1");
    $stmt->execute([':code' => $code]);
    $row = $stmt->fetch();

    if (!$row) {
        echo json_encode(["ok" => false, "reason" => "not_found"]);
        exit;
    }

    if (($row['status'] ?? 'active') === 'blocked') {
        echo json_encode(["ok" => false, "reason" => "blocked"], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $expiresAt = trim((string)$row['expires_at']);
    $zona = new DateTimeZone('America/Guayaquil');
    $now = new DateTime('now', $zona);
    $exp = null;

    if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $expiresAt)) {
        $exp = DateTime::createFromFormat('Y-m-d H:i:s', $expiresAt . ' 23:59:59', $zona);
    } else {
        try { $exp = new DateTime($expiresAt, $zona); } catch (Throwable $e) { $exp = null; }
    }

    if (!$exp) {
        echo json_encode(["ok" => false, "reason" => "invalid_exp_date"], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $secondsLeft = $exp->getTimestamp() - $now->getTimestamp();
    $daysLeft = (int)floor($secondsLeft / 86400);
    $hoursLeft = (int)floor($secondsLeft / 3600);

    if ($secondsLeft < 0) {
        echo json_encode([
            "ok" => false,
            "reason" => "expired",
            "expires_at" => $expiresAt,
            "days_left" => $daysLeft,
            "hours_left" => $hoursLeft,
            "seconds_left" => $secondsLeft,
        ], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    if (strpos($ip, ',') !== false) $ip = trim(explode(',', $ip)[0]);
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
    $deviceId = request_value(['device_id','device','serial','mac','udid','android_id','id']);
    if ($deviceId === '') {
        $deviceId = hash('sha256', $ip . '|' . $ua);
    } else {
        $deviceId = hash('sha256', $deviceId);
    }

    $maxDevices = max(1, (int)($row['max_devices'] ?? 5));

    $pdo->beginTransaction();

    $stmt = $pdo->prepare("SELECT id FROM code_devices WHERE code_id = :code_id AND device_id = :device_id LIMIT 1");
    $stmt->execute([':code_id' => (int)$row['id'], ':device_id' => $deviceId]);
    $existingDevice = $stmt->fetch();

    if ($existingDevice) {
        $stmt = $pdo->prepare("UPDATE code_devices SET ip = :ip, user_agent = :ua, last_seen = :last_seen WHERE id = :id");
        $stmt->execute([
            ':ip' => $ip,
            ':ua' => $ua,
            ':last_seen' => date('Y-m-d H:i:s'),
            ':id' => (int)$existingDevice['id']
        ]);
    } else {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM code_devices WHERE code_id = :code_id");
        $stmt->execute([':code_id' => (int)$row['id']]);
        $activeDevicesBefore = (int)$stmt->fetchColumn();

        if ($activeDevicesBefore >= $maxDevices) {
            $pdo->rollBack();
            echo json_encode([
                "ok" => false,
                "reason" => "device_limit_reached",
                "active_devices" => $activeDevicesBefore,
                "max_devices" => $maxDevices
            ], JSON_UNESCAPED_UNICODE);
            exit;
        }

        $stmt = $pdo->prepare("INSERT INTO code_devices (code_id, code, device_id, ip, user_agent, first_seen, last_seen) VALUES (:code_id, :code, :device_id, :ip, :ua, :first_seen, :last_seen)");
        $nowStr = date('Y-m-d H:i:s');
        $stmt->execute([
            ':code_id' => (int)$row['id'],
            ':code' => (string)$row['code'],
            ':device_id' => $deviceId,
            ':ip' => $ip,
            ':ua' => $ua,
            ':first_seen' => $nowStr,
            ':last_seen' => $nowStr
        ]);
    }

    $stmt = $pdo->prepare("SELECT COUNT(*) FROM code_devices WHERE code_id = :code_id");
    $stmt->execute([':code_id' => (int)$row['id']]);
    $activeDevices = (int)$stmt->fetchColumn();

    $pdo->commit();

    echo json_encode([
        "ok" => true,
        "expires_at" => $expiresAt,
        "days_left" => $daysLeft,
        "hours_left" => $hoursLeft,
        "seconds_left" => $secondsLeft,
        "is_demo" => (int)($row['is_demo'] ?? 0),
        "demo_hours" => (int)($row['demo_hours'] ?? 0),
        "active_devices" => $activeDevices,
        "max_devices" => $maxDevices
    ], JSON_UNESCAPED_UNICODE);

} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    echo json_encode(["ok" => false, "reason" => "server_error"]);
}
?>
