<?php
declare(strict_types=1);

require_once __DIR__ . '/../includes/bootstrap.php';
require_once __DIR__ . '/../includes/KorrespondAgent.php';

dbnToolsRequireMethod('POST');
dbnToolsRequireAuth();

@ini_set('output_buffering', '0');
@ini_set('zlib.output_compression', '0');
@ini_set('implicit_flush', '1');
while (ob_get_level() > 0) { @ob_end_clean(); }
ob_implicit_flush(true);

header('Content-Type: application/x-ndjson; charset=utf-8');
header('Cache-Control: no-store');
header('X-Accel-Buffering: no');

$startTime = microtime(true);
$language  = 'en';

$emit = function (string $event, array $payload = []) use ($startTime): void {
    $payload['event'] = $event;
    $payload['t_ms']  = (int)round((microtime(true) - $startTime) * 1000);
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
    @flush();
};

try {
    $raw = file_get_contents('php://input');
    if ($raw === false || strlen($raw) > 200000) {
        throw new DbnToolsHttpException('Request body unreadable or too large.', 413, 'body_too_large');
    }
    $input = json_decode((string)$raw, true);
    if (!is_array($input)) {
        throw new DbnToolsHttpException('Request body must be valid JSON.', 400, 'invalid_json');
    }

    $language        = dbnToolsNormalizeLanguage($input['language'] ?? 'en');
    $jurisdiction    = $input['jurisdiction'] ?? 'norwegian';
    if (!in_array($jurisdiction, ['norwegian', 'echr', 'both'], true)) {
        throw new DbnToolsHttpException('Invalid jurisdiction.', 422, 'invalid_jurisdiction');
    }
    $originalDraftNo = trim((string)($input['original_draft_no'] ?? ''));
    if ($originalDraftNo === '') {
        throw new DbnToolsHttpException('original_draft_no is required.', 422, 'missing_original_draft');
    }
    if (mb_strlen($originalDraftNo, 'UTF-8') > 12000) {
        throw new DbnToolsHttpException('original_draft_no is too large.', 413, 'original_too_large');
    }
    $classify = is_array($input['classify'] ?? null) ? $input['classify'] : [];
    $intake   = is_array($input['intake']   ?? null) ? $input['intake']   : [];

    // Sanitise intake to expected fields only
    $allowedBodies = ['barnehage','school_1_10','sfo','nav','bufdir','barnevernet',
        'kommune_other','statsforvalter','trygderetten','tingrett','other'];
    $allowedOutput = ['email','formal','filing','call_prep'];
    $allowedTone   = ['cooperative','neutral','firm','adversarial','warm'];

    $intake = [
        'recipient_body' => in_array($intake['recipient_body'] ?? '', $allowedBodies, true) ? $intake['recipient_body'] : 'other',
        'output_type'    => in_array($intake['output_type']    ?? '', $allowedOutput, true) ? $intake['output_type']    : 'email',
        'tone'           => in_array($intake['tone']           ?? '', $allowedTone,   true) ? $intake['tone']           : 'neutral',
        'language'       => $language,
        'goal'           => mb_substr(trim((string)($intake['goal'] ?? '')), 0, 600, 'UTF-8'),
    ];

    // Credit gate (refine is a paid pass)
    $ftUid = dbnToolsFreeTierCheck('korrespond_refine');
    $ftRemaining = dbnToolsFreeTierDeduct($ftUid, 'korrespond_refine');
    if ($ftRemaining >= 0) {
        header('X-Credits-Remaining: ' . $ftRemaining);
    }

    $emit('start', [
        'jurisdiction' => $jurisdiction,
        'body'         => $intake['recipient_body'],
        'language'     => $language,
    ]);

    $agent  = new DbnKorrespondAgent();
    $result = $agent->refine($intake, $classify, $originalDraftNo, $jurisdiction, $emit);
    $result['ok']         = true;
    $result['latency_ms'] = (int)round((microtime(true) - $startTime) * 1000);

    dbnToolsLogMetadata([
        'tool'         => 'korrespond_refine',
        'language'     => $language,
        'ok'           => true,
        'latency_ms'   => $result['latency_ms'],
        'source_count' => is_array($result['cited_law'] ?? null) ? count($result['cited_law']) : 0,
        'deployment'   => 'gpt-4o',
        'jurisdiction' => $jurisdiction,
    ]);

    $emit('final', ['result' => $result]);

} catch (DbnToolsHttpException $e) {
    $latency = (int)round((microtime(true) - $startTime) * 1000);
    dbnToolsLogMetadata([
        'tool'       => 'korrespond_refine',
        'language'   => $language,
        'ok'         => false,
        'latency_ms' => $latency,
        'error_code' => $e->errorCode,
    ]);
    $emit('error', ['code' => $e->errorCode, 'message' => $e->getMessage(), 'status' => $e->status]);
} catch (Throwable $e) {
    error_log('Korrespond refine fatal: ' . $e->getMessage());
    $latency = (int)round((microtime(true) - $startTime) * 1000);
    dbnToolsLogMetadata([
        'tool'       => 'korrespond_refine',
        'language'   => $language,
        'ok'         => false,
        'latency_ms' => $latency,
        'error_code' => 'internal_error',
    ]);
    $emit('error', ['code' => 'internal_error', 'message' => 'Korrespond refine could not complete this request.']);
}
