<?php

declare(strict_types=1);

require_once dirname(__DIR__) . '/_app_guard.php';
app_guard_validate();

header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, X-App-Token, Authorization");

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'OPTIONS') {
    http_response_code(204);
    exit;
}

function json_out(array $payload): void {
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function normalize_mac(string $mac): ?string {
    $clean = preg_replace('/[^A-Fa-f0-9]/', '', trim($mac));
    $clean = strtoupper(substr($clean, 0, 12));
    if (strlen($clean) !== 12) {
        return null;
    }
    return implode(':', str_split($clean, 2));
}

function normalize_device_type(string $value): string {
    $value = strtolower(trim($value));
    if (in_array($value, ['tv', 'android_tv', 'television'], true)) {
        return 'tv';
    }
    if (in_array($value, ['mobile', 'celular', 'phone', 'android'], true)) {
        return 'mobile';
    }
    return 'app';
}

function hasColumn(PDO $db, string $table, string $column): bool {
    $st = $db->query("PRAGMA table_info($table)");
    if (!$st) {
        return false;
    }
    foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $col) {
        if (($col['name'] ?? '') === $column) {
            return true;
        }
    }
    return false;
}

function ensure_message_views_schema(PDO $db): void {
    $db->exec("
        CREATE TABLE IF NOT EXISTS mac_message_views (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            message_id INTEGER NOT NULL,
            mac TEXT NOT NULL,
            device_type TEXT NOT NULL DEFAULT 'app',
            message_token TEXT NOT NULL,
            viewed_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
            UNIQUE(message_id, mac, device_type, message_token)
        )
    ");

    if (!hasColumn($db, 'mac_message_views', 'message_token')) {
        $db->exec("ALTER TABLE mac_message_views ADD COLUMN message_token TEXT NOT NULL DEFAULT ''");
        $db->exec("UPDATE mac_message_views SET message_token = CAST(message_id AS TEXT) WHERE message_token = '' OR message_token IS NULL");
    }

    $schema = (string)($db->query("SELECT sql FROM sqlite_master WHERE type='table' AND name='mac_message_views'")->fetchColumn() ?: '');
    $hasDeviceType = hasColumn($db, 'mac_message_views', 'device_type');
    $hasLegacyUnique = stripos($schema, 'UNIQUE(message_id, mac, message_token)') !== false;

    if (!$hasDeviceType || $hasLegacyUnique) {
        $db->exec("BEGIN IMMEDIATE");
        try {
            $db->exec("
                CREATE TABLE IF NOT EXISTS mac_message_views_new (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    message_id INTEGER NOT NULL,
                    mac TEXT NOT NULL,
                    device_type TEXT NOT NULL DEFAULT 'app',
                    message_token TEXT NOT NULL,
                    viewed_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
                    UNIQUE(message_id, mac, device_type, message_token)
                )
            ");
            $db->exec("
                INSERT OR IGNORE INTO mac_message_views_new (id, message_id, mac, device_type, message_token, viewed_at)
                SELECT id, message_id, mac, 'legacy', message_token, viewed_at
                FROM mac_message_views
            ");
            $db->exec("DROP TABLE mac_message_views");
            $db->exec("ALTER TABLE mac_message_views_new RENAME TO mac_message_views");
            $db->exec("COMMIT");
        } catch (Throwable $e) {
            $db->exec("ROLLBACK");
            throw $e;
        }
    }

    $db->exec("
        CREATE INDEX IF NOT EXISTS idx_mac_message_views_lookup
        ON mac_message_views(message_id, mac, device_type, message_token)
    ");
}

$dbPath = dirname(__DIR__) . '/db.db';

try {
    $db = new PDO('sqlite:' . $dbPath);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (Throwable $e) {
    json_out(['status' => 'erro']);
}

$macDb = normalize_mac((string)($_POST['mac'] ?? ''));
$messageId = (int)($_POST['message_id'] ?? 0);
$messageToken = trim((string)($_POST['message_token'] ?? ''));
$deviceType = normalize_device_type((string)($_POST['device_type'] ?? 'app'));

if ($macDb === null || $messageId <= 0 || $messageToken === '') {
    json_out(['status' => 'erro']);
}

try {
    ensure_message_views_schema($db);

    $stmt = $db->prepare("
        INSERT OR IGNORE INTO mac_message_views (message_id, mac, device_type, message_token, viewed_at)
        VALUES (:message_id, :mac, :device_type, :message_token, strftime('%s','now'))
    ");
    $stmt->execute([
        ':message_id' => $messageId,
        ':mac' => $macDb,
        ':device_type' => $deviceType,
        ':message_token' => $messageToken
    ]);

    json_out(['status' => 'ok']);
} catch (Throwable $e) {
    json_out(['status' => 'erro']);
}
