<?php

declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    http_response_code(403);
    exit(1);
}

require_once __DIR__ . '/../src/config.php';
require_once __DIR__ . '/../src/storage.php';
require_once __DIR__ . '/../src/history.php';

if (chatStoreIsSplit()) {
    $count = 0;
    foreach (chatStoreIterate() as $chat) $count++;
    echo json_encode(['ok' => true, 'repaired' => false, 'source' => 'split_json', 'chats' => $count]) . PHP_EOL;
    exit(0);
}

$file = (string) config('CHAT_HISTORY_FILE');
$raw = is_file($file) ? file_get_contents($file) : '';
if (!is_string($raw) || trim($raw) === '') {
    writeJsonFile($file, ['chats' => []]);
    echo json_encode(['ok' => true, 'repaired' => true, 'source' => 'empty'], JSON_PRETTY_PRINT) . PHP_EOL;
    exit(0);
}

$decoded = json_decode($raw, true);
if (is_array($decoded)) {
    echo json_encode([
        'ok' => true,
        'repaired' => false,
        'source' => 'valid_json',
        'chats' => count((array) ($decoded['chats'] ?? [])),
    ], JSON_PRETTY_PRINT) . PHP_EOL;
    exit(0);
}

$backup = $file . '.corrupt.' . date('Ymd_His');
if (!copy($file, $backup)) {
    throw new RuntimeException('Cannot back up corrupted chat history: ' . $backup);
}
@chmod($backup, 0664);

$recovered = recoverCompleteJsonPrefix($raw);
$source = 'complete_prefix';
if ($recovered === null) {
    $recovered = recoverChatsFromOperationalStates();
    $source = 'operational_states';
}

writeJsonFile($file, $recovered);
echo json_encode([
    'ok' => true,
    'repaired' => true,
    'source' => $source,
    'backup' => $backup,
    'chats' => count((array) ($recovered['chats'] ?? [])),
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;

function recoverCompleteJsonPrefix(string $raw): ?array
{
    $depth = 0;
    $started = false;
    $inString = false;
    $escaped = false;
    $length = strlen($raw);

    for ($index = 0; $index < $length; $index++) {
        $character = $raw[$index];
        if ($inString) {
            if ($escaped) {
                $escaped = false;
            } elseif ($character === '\\') {
                $escaped = true;
            } elseif ($character === '"') {
                $inString = false;
            }
            continue;
        }

        if ($character === '"') {
            $inString = true;
            continue;
        }
        if ($character === '{' || $character === '[') {
            $started = true;
            $depth++;
            continue;
        }
        if ($character !== '}' && $character !== ']') {
            continue;
        }

        $depth--;
        if (!$started || $depth !== 0) {
            continue;
        }

        $candidate = json_decode(substr($raw, 0, $index + 1), true);
        if (is_array($candidate)) {
            return $candidate;
        }
    }

    return null;
}

function recoverChatsFromOperationalStates(): array
{
    $chats = [];
    foreach (glob(followupOperationalStateDirectory() . '/*.json') ?: [] as $stateFile) {
        $raw = file_get_contents($stateFile);
        $stored = is_string($raw) ? json_decode($raw, true) : null;
        if (!is_array($stored)) {
            continue;
        }

        $chatKey = trim((string) ($stored['chat_key'] ?? ''));
        $chat = (array) ($stored['chat'] ?? []);
        if ($chatKey !== '' && $chat !== []) {
            $chats[$chatKey] = $chat;
        }
    }

    return ['chats' => $chats];
}
