<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/admin_auth_lib.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/special_odds_engine.php';

mocker_admin_require_permission('special-odds');

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

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

try {
    $pdo = mocker_db();
} catch (Throwable $e) {
    http_response_code(503);
    echo json_encode(['ok' => false, 'error' => 'db'], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($method === 'GET') {
    $st = $pdo->query(
        'SELECT id, external_event_id, home_name, away_name, logo_home_url, logo_away_url, kickoff_at,
                odds_home, odds_draw, odds_away, prediction_text, admin_pick, odds_offered, max_participants,
                status, result, home_goals, away_goals, is_active,
                last_api_sync_at, created_at, updated_at
         FROM special_odds_matches ORDER BY kickoff_at DESC, id DESC LIMIT 200'
    );
    $rows = $st ? $st->fetchAll(PDO::FETCH_ASSOC) : [];
    $out = [];
    foreach ($rows as $r) {
        $out[] = [
            'id' => (int) $r['id'],
            'externalEventId' => (string) $r['external_event_id'],
            'homeName' => (string) $r['home_name'],
            'awayName' => (string) $r['away_name'],
            'logoHomeUrl' => $r['logo_home_url'] !== null ? (string) $r['logo_home_url'] : '',
            'logoAwayUrl' => $r['logo_away_url'] !== null ? (string) $r['logo_away_url'] : '',
            'kickoffAt' => (int) $r['kickoff_at'],
            'oddsHome' => (float) $r['odds_home'],
            'oddsDraw' => (float) $r['odds_draw'],
            'oddsAway' => (float) $r['odds_away'],
            'predictionText' => isset($r['prediction_text']) ? (string) $r['prediction_text'] : '',
            'adminPick' => isset($r['admin_pick']) ? (string) $r['admin_pick'] : 'home',
            'oddsOffered' => isset($r['odds_offered']) ? (float) $r['odds_offered'] : (float) $r['odds_home'],
            'maxParticipants' => isset($r['max_participants']) ? (int) $r['max_participants'] : 0,
            'status' => (string) $r['status'],
            'result' => $r['result'] !== null ? (string) $r['result'] : null,
            'homeGoals' => $r['home_goals'] !== null ? (int) $r['home_goals'] : null,
            'awayGoals' => $r['away_goals'] !== null ? (int) $r['away_goals'] : null,
            'isActive' => (int) ($r['is_active'] ?? 1) === 1,
            'lastApiSyncAt' => $r['last_api_sync_at'] !== null ? (int) $r['last_api_sync_at'] : null,
            'createdAt' => (int) $r['created_at'],
            'updatedAt' => (int) $r['updated_at'],
        ];
    }
    echo json_encode(['ok' => true, 'matches' => $out], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($method !== 'POST') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'error' => 'method'], JSON_UNESCAPED_UNICODE);
    exit;
}

mocker_require_csrf_post();

$input = json_decode((string) file_get_contents('php://input'), true) ?: [];
$action = strtolower(trim((string) ($input['action'] ?? '')));

$now = time();

if ($action === 'create') {
    $ext = trim((string) ($input['externalEventId'] ?? ''));
    $home = trim((string) ($input['homeName'] ?? ''));
    $away = trim((string) ($input['awayName'] ?? ''));
    $kick = (int) ($input['kickoffAt'] ?? 0);
    $pred = isset($input['predictionText']) ? trim((string) $input['predictionText']) : '';
    if (mocker_utf8_len($pred) > 4000) {
        $pred = function_exists('mb_substr') ? (string) mb_substr($pred, 0, 4000, 'UTF-8') : substr($pred, 0, 4000);
    }
    $adminPick = strtolower(trim((string) ($input['adminPick'] ?? 'home')));
    $oddsOffered = (float) ($input['oddsOffered'] ?? $input['oddsHome'] ?? 0);
    $lh = isset($input['logoHomeUrl']) ? trim((string) $input['logoHomeUrl']) : '';
    $la = isset($input['logoAwayUrl']) ? trim((string) $input['logoAwayUrl']) : '';
    if ($ext === '' || $home === '' || $away === '' || $kick <= 0) {
        echo json_encode(['ok' => false, 'error' => 'validate'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    if (!in_array($adminPick, ['home', 'draw', 'away'], true)) {
        echo json_encode(['ok' => false, 'error' => 'pick'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    if ($oddsOffered < SPECIAL_ODDS_MIN_ODDS || $oddsOffered > SPECIAL_ODDS_MAX_ODDS) {
        echo json_encode(['ok' => false, 'error' => 'odds'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $maxParticipants = isset($input['maxParticipants']) ? (int) $input['maxParticipants'] : 0;
    if ($maxParticipants < 0 || $maxParticipants > 100000) {
        echo json_encode(['ok' => false, 'error' => 'max_participants'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $min = SPECIAL_ODDS_MIN_ODDS;
    $oh = $adminPick === 'home' ? $oddsOffered : $min;
    $od = $adminPick === 'draw' ? $oddsOffered : $min;
    $oa = $adminPick === 'away' ? $oddsOffered : $min;
    $ins = $pdo->prepare(
        'INSERT INTO special_odds_matches (external_event_id, home_name, away_name, logo_home_url, logo_away_url,
            kickoff_at, odds_home, odds_draw, odds_away, prediction_text, admin_pick, odds_offered, max_participants, status, is_active, created_at, updated_at)
         VALUES (:e, :h, :a, :lh, :la, :k, :oh, :od, :oa, :pred, :ap, :oo, :mp, \'open\', 1, :t, :t2)'
    );
    $ins->execute([
        ':e' => $ext,
        ':h' => $home,
        ':a' => $away,
        ':lh' => $lh !== '' ? $lh : null,
        ':la' => $la !== '' ? $la : null,
        ':k' => $kick,
        ':oh' => $oh,
        ':od' => $od,
        ':oa' => $oa,
        ':pred' => $pred,
        ':ap' => $adminPick,
        ':oo' => $oddsOffered,
        ':mp' => $maxParticipants,
        ':t' => $now,
        ':t2' => $now,
    ]);
    echo json_encode(['ok' => true, 'id' => (int) $pdo->lastInsertId()], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($action === 'update') {
    $id = (int) ($input['id'] ?? 0);
    if ($id <= 0) {
        echo json_encode(['ok' => false, 'error' => 'id'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $st = $pdo->prepare('SELECT status FROM special_odds_matches WHERE id = :id LIMIT 1');
    $st->execute([':id' => $id]);
    $cur = $st->fetch(PDO::FETCH_ASSOC);
    if (!$cur || (string) $cur['status'] !== 'open') {
        echo json_encode(['ok' => false, 'error' => 'locked'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $ext = trim((string) ($input['externalEventId'] ?? ''));
    $home = trim((string) ($input['homeName'] ?? ''));
    $away = trim((string) ($input['awayName'] ?? ''));
    $kick = (int) ($input['kickoffAt'] ?? 0);
    $pred = isset($input['predictionText']) ? trim((string) $input['predictionText']) : '';
    if (mocker_utf8_len($pred) > 4000) {
        $pred = function_exists('mb_substr') ? (string) mb_substr($pred, 0, 4000, 'UTF-8') : substr($pred, 0, 4000);
    }
    $adminPick = strtolower(trim((string) ($input['adminPick'] ?? 'home')));
    $oddsOffered = (float) ($input['oddsOffered'] ?? $input['oddsHome'] ?? 0);
    $lh = isset($input['logoHomeUrl']) ? trim((string) $input['logoHomeUrl']) : '';
    $la = isset($input['logoAwayUrl']) ? trim((string) $input['logoAwayUrl']) : '';
    $isActive = array_key_exists('isActive', $input) ? ((bool) $input['isActive'] ? 1 : 0) : 1;
    if ($ext === '' || $home === '' || $away === '' || $kick <= 0) {
        echo json_encode(['ok' => false, 'error' => 'validate'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    if (!in_array($adminPick, ['home', 'draw', 'away'], true)) {
        echo json_encode(['ok' => false, 'error' => 'pick'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    if ($oddsOffered < SPECIAL_ODDS_MIN_ODDS || $oddsOffered > SPECIAL_ODDS_MAX_ODDS) {
        echo json_encode(['ok' => false, 'error' => 'odds'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $maxParticipants = isset($input['maxParticipants']) ? (int) $input['maxParticipants'] : 0;
    if ($maxParticipants < 0 || $maxParticipants > 100000) {
        echo json_encode(['ok' => false, 'error' => 'max_participants'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $pb = $pdo->prepare('SELECT COUNT(*) FROM special_odds_bets WHERE match_id = :id AND status = \'pending\'');
    $pb->execute([':id' => $id]);
    $pendingBets = (int) $pb->fetchColumn();
    if ($maxParticipants > 0 && $maxParticipants < $pendingBets) {
        echo json_encode(['ok' => false, 'error' => 'max_below_pending', 'pending' => $pendingBets], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $min = SPECIAL_ODDS_MIN_ODDS;
    $oh = $adminPick === 'home' ? $oddsOffered : $min;
    $od = $adminPick === 'draw' ? $oddsOffered : $min;
    $oa = $adminPick === 'away' ? $oddsOffered : $min;
    $u = $pdo->prepare(
        'UPDATE special_odds_matches SET external_event_id = :e, home_name = :h, away_name = :a,
            logo_home_url = :lh, logo_away_url = :la, kickoff_at = :k, odds_home = :oh, odds_draw = :od, odds_away = :oa,
            prediction_text = :pred, admin_pick = :ap, odds_offered = :oo, max_participants = :mp,
            is_active = :ia, updated_at = :t WHERE id = :id AND status = \'open\''
    );
    $u->execute([
        ':e' => $ext,
        ':h' => $home,
        ':a' => $away,
        ':lh' => $lh !== '' ? $lh : null,
        ':la' => $la !== '' ? $la : null,
        ':k' => $kick,
        ':oh' => $oh,
        ':od' => $od,
        ':oa' => $oa,
        ':pred' => $pred,
        ':ap' => $adminPick,
        ':oo' => $oddsOffered,
        ':mp' => $maxParticipants,
        ':ia' => $isActive,
        ':t' => $now,
        ':id' => $id,
    ]);
    echo json_encode(['ok' => $u->rowCount() > 0], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($action === 'delete') {
    $id = (int) ($input['id'] ?? 0);
    if ($id <= 0) {
        echo json_encode(['ok' => false, 'error' => 'id'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $c = $pdo->prepare('SELECT COUNT(*) FROM special_odds_bets WHERE match_id = :id');
    $c->execute([':id' => $id]);
    $n = (int) $c->fetchColumn();
    if ($n > 0) {
        echo json_encode(['ok' => false, 'error' => 'has_bets'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $d = $pdo->prepare('DELETE FROM special_odds_matches WHERE id = :id AND status = \'open\'');
    $d->execute([':id' => $id]);
    echo json_encode(['ok' => $d->rowCount() > 0], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($action === 'settle_manual') {
    $id = (int) ($input['id'] ?? 0);
    $result = strtolower(trim((string) ($input['result'] ?? '')));
    if ($id <= 0 || !in_array($result, ['home', 'draw', 'away'], true)) {
        echo json_encode(['ok' => false, 'error' => 'validate'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    try {
        special_odds_manual_settle($pdo, $id, $result);
        echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    } catch (Throwable $e) {
        http_response_code(500);
        echo json_encode(['ok' => false, 'error' => 'settle'], JSON_UNESCAPED_UNICODE);
    }
    exit;
}

if ($action === 'cancel') {
    $id = (int) ($input['id'] ?? 0);
    if ($id <= 0) {
        echo json_encode(['ok' => false, 'error' => 'id'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $ok = special_odds_cancel_match($pdo, $id);
    echo json_encode(['ok' => $ok], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($action === 'sync_one') {
    $id = (int) ($input['id'] ?? 0);
    if ($id <= 0) {
        echo json_encode(['ok' => false, 'error' => 'id'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $r = special_odds_sync_match_from_api($pdo, $id);
    echo json_encode(['ok' => $r['ok'], 'settled' => $r['settled'] ?? false, 'error' => $r['error'] ?? null], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($action === 'sync_all') {
    $r = special_odds_sync_all_open($pdo);
    echo json_encode(['ok' => true, 'checked' => $r['checked'], 'settled' => $r['settled'], 'errors' => $r['errors']], JSON_UNESCAPED_UNICODE);
    exit;
}

echo json_encode(['ok' => false, 'error' => 'action'], JSON_UNESCAPED_UNICODE);
