<?php
/**
 * ECF Export - JSON format for ECF LMS (League Management System) grading submission
 *
 * @package Chess_Podium
 */

if (!defined('ABSPATH')) {
    exit;
}

final class ChessPodium_ECF_Export
{
    /**
     * Generate JSON format for ECF LMS submission.
     *
     * @param int $tournamentId Tournament ID.
     * @return string JSON file content.
     */
    public static function generate_json(int $tournamentId): string
    {
        $tournament = self::get_tournament($tournamentId);
        if (!$tournament) {
            return '{}';
        }

        $players = self::get_players($tournamentId);
        $pairings = self::get_all_pairings($tournamentId);
        $roundsTotal = (int) ($tournament->current_round ?: $tournament->rounds_total);

        $playerIdToIndex = [];
        $index = 0;
        foreach ($players as $p) {
            $playerIdToIndex[(int) $p->id] = $index;
            $index++;
        }

        $ecfPlayers = [];
        foreach ($players as $p) {
            $ecfCode = isset($p->ecf_id) && (string) $p->ecf_id !== '' ? (string) $p->ecf_id : null;
            $ecfPlayers[] = [
                'name' => (string) $p->name,
                'ecf_code' => $ecfCode,
                'rating' => (int) ($p->rating ?? 0),
                'club' => '',
            ];
        }

        $rounds = [];
        for ($r = 1; $r <= $roundsTotal; $r++) {
            $roundPairings = array_filter($pairings, static fn ($p) => (int) $p->round_no === $r);
            $games = [];
            foreach ($roundPairings as $m) {
                $wId = (int) $m->white_player_id;
                $bId = (int) $m->black_player_id;
                $isBye = (int) $m->is_bye === 1;
                $res = class_exists('ChessPodiumPlugin') ? ChessPodiumPlugin::normalize_result((string) ($m->result ?? '')) : trim((string) ($m->result ?? ''));

                if ($isBye) {
                    $games[] = [
                        'white' => $playerIdToIndex[$wId] ?? -1,
                        'black' => -1,
                        'result' => '1',
                    ];
                    continue;
                }

                $whiteIdx = $playerIdToIndex[$wId] ?? -1;
                $blackIdx = $playerIdToIndex[$bId] ?? -1;

                $ecfResult = '=';
                if (in_array($res, ['1-0', '1F'], true)) {
                    $ecfResult = '1';
                } elseif (in_array($res, ['0-1', '0F'], true)) {
                    $ecfResult = '0';
                } elseif ($res === '1/2-1/2') {
                    $ecfResult = '=';
                }

                $games[] = [
                    'white' => $whiteIdx,
                    'black' => $blackIdx,
                    'result' => $ecfResult,
                ];
            }
            $rounds[] = ['games' => $games];
        }

        $tournamentMeta = class_exists('ChessPodium_PdfBrochure') ? ChessPodium_PdfBrochure::get_all_meta($tournamentId) : [];
        $startDate = $tournamentMeta['start_date'] ?? ($tournament->start_date ?? '');
        $endDate = $tournamentMeta['end_date'] ?? ($tournament->end_date ?? $startDate);

        $data = [
            'event' => [
                'name' => (string) $tournament->name,
                'start_date' => self::format_date_iso($startDate),
                'end_date' => self::format_date_iso($endDate),
                'rounds' => $roundsTotal,
            ],
            'players' => $ecfPlayers,
            'rounds' => $rounds,
        ];

        return wp_json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    }

    private static function get_tournament(int $id): ?object
    {
        if (!class_exists('ChessPodiumPlugin')) {
            return null;
        }
        return ChessPodiumPlugin::get_tournament($id);
    }

    private static function get_players(int $tournamentId): array
    {
        if (!class_exists('ChessPodiumPlugin')) {
            return [];
        }
        return ChessPodiumPlugin::get_players($tournamentId);
    }

    private static function get_all_pairings(int $tournamentId): array
    {
        global $wpdb;
        $table = $wpdb->prefix . 'regina_pairings';
        return $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM $table WHERE tournament_id = %d ORDER BY round_no ASC, id ASC",
            $tournamentId
        ));
    }

    private static function format_date_iso(string $date): string
    {
        if ($date === '') {
            return date('Y-m-d');
        }
        $ts = strtotime($date);
        if ($ts === false) {
            return date('Y-m-d');
        }
        return date('Y-m-d', $ts);
    }
}
