<?php
/**
 * World Cup fixtures (cPanel PHP backend)
 *
 * Endpoints:
 *   GET  /api/worldcup/fixtures
 *   GET  /api/sports/fixtures.php              (compat alias)
 *   POST /api/admin/worldcup/fixtures          (admin)
 */

function worldcup_ensure_schema(): void {
    static $done = false;
    if ($done) return;
    $done = true;

    $sql = <<<SQL
CREATE TABLE IF NOT EXISTS `worldcup_fixtures` (
  `id`            VARCHAR(96)  NOT NULL PRIMARY KEY,
  `kickoff_iso`   VARCHAR(40)  NOT NULL,
  `status`        VARCHAR(24)  NOT NULL DEFAULT 'UPCOMING',
  `group_name`    VARCHAR(120)          DEFAULT NULL,
  `venue`         VARCHAR(255)          DEFAULT NULL,
  `home_name`     VARCHAR(120) NOT NULL,
  `home_code`     VARCHAR(12)           DEFAULT NULL,
  `away_name`     VARCHAR(120) NOT NULL,
  `away_code`     VARCHAR(12)           DEFAULT NULL,
  `home_score`    INT                   DEFAULT NULL,
  `away_score`    INT                   DEFAULT NULL,
  `home_penalty`  INT                   DEFAULT NULL,
  `away_penalty`  INT                   DEFAULT NULL,
  `broadcaster`   VARCHAR(255)          DEFAULT NULL,
  `live_label`    VARCHAR(80)           DEFAULT NULL,
  `created_at`    VARCHAR(40)  NOT NULL,
  `updated_at`    VARCHAR(40)  NOT NULL,
  INDEX `ix_wc_kickoff` (`kickoff_iso`),
  INDEX `ix_wc_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SQL;
    db()->exec($sql);
}

function worldcup_status_normalize(string $raw): string {
    $s = strtoupper(trim($raw));
    if ($s === '') return 'UPCOMING';
    $allow = ['UPCOMING', 'LIVE', 'GOAL', 'HT', 'FT', 'ENDED', 'POSTPONED', 'CANCELLED'];
    return in_array($s, $allow, true) ? $s : 'UPCOMING';
}

function worldcup_team_from_raw($raw, string $fallback): array {
    if (is_array($raw)) {
        return [
            'name' => trim((string)($raw['name'] ?? '')) ?: $fallback,
            'code' => strtolower(trim((string)($raw['code'] ?? ''))),
        ];
    }
    $name = trim((string)$raw);
    return ['name' => $name !== '' ? $name : $fallback, 'code' => ''];
}

function worldcup_int_or_null($v): ?int {
    if ($v === null || $v === '') return null;
    if (is_numeric($v)) return (int)$v;
    return null;
}

function worldcup_normalize_match(array $raw): array {
    $id = trim((string)($raw['id'] ?? ''));
    if ($id === '') {
        $id = 'wc-' . substr(bin2hex(random_bytes(8)), 0, 12);
    }

    $kickoff = trim((string)($raw['kickoffIso'] ?? $raw['kickoff'] ?? ''));
    if ($kickoff === '') $kickoff = now_iso();

    $home = worldcup_team_from_raw($raw['home'] ?? null, 'Home');
    $away = worldcup_team_from_raw($raw['away'] ?? null, 'Away');

    return [
        'id'           => $id,
        'kickoffIso'   => $kickoff,
        'status'       => worldcup_status_normalize((string)($raw['status'] ?? 'UPCOMING')),
        'group'        => trim((string)($raw['group'] ?? '')),
        'venue'        => trim((string)($raw['venue'] ?? '')),
        'home'         => $home,
        'away'         => $away,
        'homeScore'    => worldcup_int_or_null($raw['homeScore'] ?? null),
        'awayScore'    => worldcup_int_or_null($raw['awayScore'] ?? null),
        'homePenalty'  => worldcup_int_or_null($raw['homePenalty'] ?? null),
        'awayPenalty'  => worldcup_int_or_null($raw['awayPenalty'] ?? null),
        'broadcaster'  => trim((string)($raw['broadcaster'] ?? '')),
        'liveLabel'    => trim((string)($raw['liveLabel'] ?? '')),
    ];
}

function worldcup_shape_row(array $r): array {
    return [
        'id'          => (string)$r['id'],
        'kickoffIso'  => (string)$r['kickoff_iso'],
        'status'      => (string)$r['status'],
        'group'       => (string)($r['group_name'] ?? ''),
        'venue'       => (string)($r['venue'] ?? ''),
        'home'        => [
            'name' => (string)$r['home_name'],
            'code' => strtolower((string)($r['home_code'] ?? '')),
        ],
        'away'        => [
            'name' => (string)$r['away_name'],
            'code' => strtolower((string)($r['away_code'] ?? '')),
        ],
        'homeScore'   => $r['home_score'] !== null ? (int)$r['home_score'] : null,
        'awayScore'   => $r['away_score'] !== null ? (int)$r['away_score'] : null,
        'homePenalty' => $r['home_penalty'] !== null ? (int)$r['home_penalty'] : null,
        'awayPenalty' => $r['away_penalty'] !== null ? (int)$r['away_penalty'] : null,
        'broadcaster' => (string)($r['broadcaster'] ?? ''),
        'liveLabel'   => (string)($r['live_label'] ?? ''),
    ];
}

function worldcup_list_matches(): array {
    worldcup_ensure_schema();
    $rows = db()->query(
        'SELECT * FROM worldcup_fixtures ORDER BY kickoff_iso ASC, id ASC'
    )->fetchAll();

    $out = [];
    foreach ($rows as $r) $out[] = worldcup_shape_row($r);
    return $out;
}

function worldcup_map_by_id(array $matches): array {
    $out = [];
    foreach ($matches as $m) {
        $id = (string)($m['id'] ?? '');
        if ($id !== '') $out[$id] = $m;
    }
    return $out;
}

function worldcup_compose_save_message(array $m): array {
    $teams = ($m['home']['name'] ?? 'Home') . ' vs ' . ($m['away']['name'] ?? 'Away');
    $data = [
        'type' => 'worldcup_save',
        'match_id' => (string)($m['id'] ?? ''),
        'kickoff_iso' => (string)($m['kickoffIso'] ?? ''),
    ];
    $channel = trim((string)($m['broadcaster'] ?? ''));
    if ($channel !== '') $data['channel_name'] = $channel;

    return [
        'title' => 'World Cup Match Added',
        'body' => $teams . ' is now scheduled. Tap Watch on to open live stream.',
        'route' => '/world-cup',
        'action_label' => 'Watch on',
        'data' => $data,
    ];
}

function worldcup_compose_live_goal_message(array $m, string $status): array {
    $teams = ($m['home']['name'] ?? 'Home') . ' vs ' . ($m['away']['name'] ?? 'Away');
    $is_goal = $status === 'GOAL';
    $data = [
        'type' => $is_goal ? 'worldcup_goal' : 'worldcup_live',
        'match_id' => (string)($m['id'] ?? ''),
    ];
    $channel = trim((string)($m['broadcaster'] ?? ''));
    if ($channel !== '') $data['channel_name'] = $channel;
    $score = ((string)($m['homeScore'] ?? '0')) . '-' . ((string)($m['awayScore'] ?? '0'));

    return [
        'title' => $is_goal ? 'Goal Alert' : 'Live Now',
        'body' => $is_goal ? ($teams . ' update ' . $score . '.') : ($teams . ' is live.'),
        'route' => '/world-cup',
        'action_label' => 'Watch on',
        'data' => $data,
    ];
}

function worldcup_auto_notify(array $previous_by_id, array $matches): array {
    if (!function_exists('fcm_ensure_schema') || !function_exists('fcm_send_batch')) {
        return [];
    }

    fcm_ensure_schema();
    $rows = db()->query('SELECT device_id, token FROM fcm_tokens WHERE is_active = 1')->fetchAll();
    if (!$rows) {
        return [['queued' => false, 'reason' => 'no_active_devices']];
    }

    $queue = [];
    foreach ($matches as $m) {
        $id = (string)($m['id'] ?? '');
        if ($id === '') continue;

        $prev = $previous_by_id[$id] ?? null;
        if ($prev === null) {
            $queue[] = worldcup_compose_save_message($m);
            continue;
        }

        $prev_status = strtoupper((string)($prev['status'] ?? ''));
        $new_status = strtoupper((string)($m['status'] ?? ''));
        if ($prev_status !== $new_status && in_array($new_status, ['LIVE', 'GOAL'], true)) {
            $queue[] = worldcup_compose_live_goal_message($m, $new_status);
        }
    }

    if (!$queue) return [];

    // Deduplicate by title/body per save action.
    $uniq = [];
    foreach ($queue as $q) {
        $k = ($q['title'] ?? '') . '|' . ($q['body'] ?? '');
        $uniq[$k] = $q;
    }

    $results = [];
    foreach ($uniq as $q) {
        $results[] = fcm_send_batch($rows, $q, 'broadcast');
    }
    return $results;
}

function worldcup_upsert_matches(array $incoming, bool $notify = true): array {
    worldcup_ensure_schema();
    $prev = worldcup_list_matches();
    $prev_by_id = worldcup_map_by_id($prev);

    $clean = [];
    foreach ($incoming as $raw) {
        if (!is_array($raw)) continue;
        $clean[] = worldcup_normalize_match($raw);
    }

    $pdo = db();
    $pdo->beginTransaction();
    try {
        $pdo->exec('DELETE FROM worldcup_fixtures');
        if ($clean) {
            $ins = $pdo->prepare(
                'INSERT INTO worldcup_fixtures
                (id, kickoff_iso, status, group_name, venue, home_name, home_code,
                 away_name, away_code, home_score, away_score, home_penalty, away_penalty,
                 broadcaster, live_label, created_at, updated_at)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
            );
            foreach ($clean as $m) {
                $now = now_iso();
                $ins->execute([
                    $m['id'],
                    $m['kickoffIso'],
                    $m['status'],
                    $m['group'] !== '' ? $m['group'] : null,
                    $m['venue'] !== '' ? $m['venue'] : null,
                    $m['home']['name'],
                    $m['home']['code'] !== '' ? $m['home']['code'] : null,
                    $m['away']['name'],
                    $m['away']['code'] !== '' ? $m['away']['code'] : null,
                    $m['homeScore'],
                    $m['awayScore'],
                    $m['homePenalty'],
                    $m['awayPenalty'],
                    $m['broadcaster'] !== '' ? $m['broadcaster'] : null,
                    $m['liveLabel'] !== '' ? $m['liveLabel'] : null,
                    $now,
                    $now,
                ]);
            }
        }
        $pdo->commit();
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        throw $e;
    }

    $notif = $notify ? worldcup_auto_notify($prev_by_id, $clean) : [];
    return ['ok' => true, 'saved' => count($clean), 'notifications' => $notif];
}

function route_worldcup_fixtures_get(): void {
    $matches = worldcup_list_matches();
    send_json([
        'configured' => true,
        'source' => 'admin',
        'matches' => $matches,
        'standings' => [],
    ]);
}

function route_admin_worldcup_fixtures_post(): void {
    require_admin();
    $b = read_json_body();
    $matches = $b['matches'] ?? null;
    if (!is_array($matches)) {
        json_error(400, 'matches must be an array');
    }
    send_json(worldcup_upsert_matches($matches, true));
}
