<?php
/**
 * PDF Badge & Placecard Generator
 *
 * Generates print-ready PDFs (or HTML fallback) for:
 * - Badges: name, title, rating, assigned table
 * - Placecards (segnaposti): tent cards with the same info
 *
 * @package Chess_Podium
 */

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

final class ChessPodium_PdfBadges
{
    private static function resolve_tournament_logo_url(object $tournament): string
    {
        $tid = (int) ($tournament->id ?? 0);
        if ($tid > 0 && class_exists('ChessPodium_PdfBrochure')) {
            $logo = (string) (ChessPodium_PdfBrochure::get_meta($tid, 'brochure_logo') ?: '');
            $logo = trim($logo);
            if ($logo !== '') {
                return esc_url_raw($logo);
            }
        }
        // Fallback: plugin logo asset (may not exist in all builds).
        if (defined('CHESS_PODIUM_PLUGIN_FILE')) {
            return esc_url_raw(plugins_url('assets/logo-chess-podium.svg', CHESS_PODIUM_PLUGIN_FILE));
        }
        return '';
    }

    private static function get_board_count_for_round(int $tournamentId, int $round): int
    {
        if ($tournamentId <= 0 || $round <= 0 || !class_exists('ChessPodiumPlugin')) {
            return 0;
        }
        $pairings = ChessPodiumPlugin::get_pairings($tournamentId);
        $count = 0;
        foreach ($pairings as $p) {
            if ((int) ($p->round_no ?? 0) !== $round) {
                continue;
            }
            $isBye = (int) ($p->is_bye ?? 0) === 1;
            $blackId = (int) ($p->black_player_id ?? 0);
            if ($isBye || $blackId <= 0) {
                continue;
            }
            $count++;
        }
        return max(0, $count);
    }

    private static function render_flag_for_pdf(string $country): string
    {
        $cc = strtoupper(trim($country));
        if ($cc === '' || strlen($cc) !== 2 || !ctype_alpha($cc) || !class_exists('ChessPodium_CountryHelper')) {
            return '';
        }
        return ChessPodium_CountryHelper::render_flag_img($cc, $cc);
    }

    private static function build_player_profile_url(int $tournamentId, int $playerId): string
    {
        $liveUrl = class_exists('ChessPodiumPlugin') ? ChessPodiumPlugin::get_live_url($tournamentId) : '';
        if ($liveUrl === '') {
            return '';
        }
        return add_query_arg('cp_player', (string) $playerId, $liveUrl);
    }

    private static function build_qr_url(string $targetUrl): string
    {
        if ($targetUrl === '') {
            return '';
        }
        // External QR image generation; works in dompdf with isRemoteEnabled=true.
        return 'https://api.qrserver.com/v1/create-qr-code/?size=120x120&margin=0&data=' . rawurlencode($targetUrl);
    }

    /**
     * @return array<int, int> player_id => fixed board number (effective for round)
     */
    private static function get_fixed_boards_for_round(int $tournamentId, int $round): array
    {
        global $wpdb;
        $table = $wpdb->prefix . 'regina_fixed_boards';
        $rows = $wpdb->get_results($wpdb->prepare(
            "SELECT player_id, board_number FROM $table WHERE tournament_id = %d AND from_round <= %d",
            $tournamentId,
            $round
        ));
        $out = [];
        foreach ((array) $rows as $r) {
            $out[(int) $r->player_id] = (int) $r->board_number;
        }
        return $out;
    }

    /**
     * Return assigned table/board for a player for the given round.
     * Preference:
     * - fixed board assignment (accessibility etc.)
     * - actual game board number in that round (excluding BYEs)
     *
     * @return int|null
     */
    private static function get_assigned_table_for_player(int $tournamentId, int $playerId, int $round): ?int
    {
        if ($round <= 0) {
            return null;
        }

        $fixed = self::get_fixed_boards_for_round($tournamentId, $round);
        if (isset($fixed[$playerId]) && (int) $fixed[$playerId] > 0) {
            return (int) $fixed[$playerId];
        }

        if (!class_exists('ChessPodiumPlugin')) {
            return null;
        }

        // We use board numbering like chess-results: count only real games (non-bye).
        $pairings = ChessPodiumPlugin::get_pairings($tournamentId);
        $gamesInRound = [];
        foreach ($pairings as $p) {
            if ((int) ($p->round_no ?? 0) !== $round) {
                continue;
            }
            $isBye = (int) ($p->is_bye ?? 0) === 1;
            $blackId = (int) ($p->black_player_id ?? 0);
            if ($isBye || $blackId <= 0) {
                continue;
            }
            $gamesInRound[] = $p;
        }

        $boardNo = 0;
        foreach ($gamesInRound as $g) {
            $boardNo++;
            $w = (int) ($g->white_player_id ?? 0);
            $b = (int) ($g->black_player_id ?? 0);
            if ($w === $playerId || $b === $playerId) {
                return $boardNo;
            }
        }

        return null;
    }

    /**
     * Build a printable HTML document for badges.
     *
     * @param object $tournament
     * @param array $players player objects
     */
    public static function generate_badges_html(object $tournament, array $players): string
    {
        $tid = (int) $tournament->id;
        $round = (int) ($tournament->current_round ?? 0);
        $title = esc_html((string) $tournament->name) . ' - ' . esc_html__('Badges', 'chess-podium');

        // Sort by name for predictable printouts.
        usort($players, static fn ($a, $b) => strcasecmp((string) ($a->name ?? ''), (string) ($b->name ?? '')));

        ob_start();
        ?>
        <!doctype html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title><?php echo $title; ?></title>
            <style>
                @page { margin: 10mm; }
                body { font-family: "DejaVu Sans", Helvetica, Arial, sans-serif; color: #111827; margin: 0; }
                .meta { margin: 0 0 10mm 0; font-size: 10pt; color: #374151; }
                .meta strong { color: #111827; }

                .grid { width: 100%; }
                .cp-page { page-break-after: always; }
                .cp-page:last-child { page-break-after: auto; }
                .cp-grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
                .cp-grid td { width: 50%; vertical-align: top; }
                .badge {
                    width: 100%;
                    border: 1px solid #cbd5e1;
                    border-left: 5px solid #1a365d;
                    border-radius: 4px;
                    padding: 6mm;
                    box-sizing: border-box;
                    height: 62mm;
                    position: relative;
                    overflow: hidden;
                }
                .badge .name { font-size: 18pt; font-weight: 800; line-height: 1.1; margin: 0 0 3mm 0; }
                .badge .name-wrap { display: flex; align-items: center; gap: 3mm; margin: 0 0 3mm 0; }
                .badge .name-wrap .name { margin: 0; }
                .badge .sub { font-size: 10pt; color: #374151; margin: 0; font-weight: 700; }
                .badge .row { margin-top: 2.5mm; display: flex; gap: 6mm; flex-wrap: wrap; }
                .pill {
                    display: inline-block;
                    padding: 2mm 3.2mm;
                    border: 1px solid #e2e8f0;
                    border-radius: 999px;
                    background: #f8fafc;
                    font-size: 10pt;
                    color: #0f172a;
                }
                .pill strong { font-weight: 800; }
                .corner {
                    position: absolute;
                    top: 5mm;
                    right: 40mm;
                    font-size: 9pt;
                    color: #64748b;
                }
                .corner span { display: block; text-align: right; }
                .qr {
                    position: absolute;
                    top: 6mm;
                    right: 6mm;
                    width: 28mm;
                    height: 28mm;
                    border: 1px solid #e2e8f0;
                    background: #fff;
                }
                .qr img { width: 100%; height: 100%; object-fit: contain; display: block; }
            </style>
        </head>
        <body>
            <div class="meta">
                <strong><?php echo esc_html((string) $tournament->name); ?></strong>
                <?php if ($round > 0): ?> — <?php echo esc_html(sprintf(__('Round %d', 'chess-podium'), $round)); ?><?php endif; ?>
                — <?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'))); ?>
            </div>
            <div class="grid">
                <?php for ($idx = 0; $idx < count($players); $idx += 4): ?>
                    <div class="cp-page">
                        <table class="cp-grid">
                            <?php for ($row = 0; $row < 2; $row++): ?>
                            <tr>
                                <?php for ($col = 0; $col < 2; $col++): ?>
                                    <?php
                                    $slot = $row * 2 + $col;
                                    $p = $players[$idx + $slot] ?? null;
                                    $padRight = $col === 0 ? '3mm' : '0';
                                    $padLeft = $col === 1 ? '3mm' : '0';
                                    $padBottom = $row === 0 ? '5mm' : '0';
                                    ?>
                                    <td style="padding:0 <?php echo esc_attr($padRight); ?> <?php echo esc_attr($padBottom); ?> <?php echo esc_attr($padLeft); ?>;">
                                    <?php if ($p !== null):
                                        $pid = (int) ($p->id ?? 0);
                                        $name = (string) ($p->name ?? '');
                                        $rating = (int) ($p->rating ?? 0);
                                        $fed = (string) ($p->country ?? '');
                                        $flag = self::render_flag_for_pdf($fed);
                                        $ptitle = (string) ($p->title ?? '');
                                        $profileUrl = self::build_player_profile_url($tid, $pid);
                                        $qrUrl = self::build_qr_url($profileUrl);
                                    ?>
                    <div class="badge">
                        <div class="corner">
                            <?php if ($fed !== ''): ?><span><?php echo esc_html($fed); ?></span><?php endif; ?>
                            <?php if ($ptitle !== ''): ?><span><?php echo esc_html($ptitle); ?></span><?php endif; ?>
                        </div>
                        <?php if ($qrUrl !== ''): ?>
                            <div class="qr"><img src="<?php echo esc_url($qrUrl); ?>" alt="QR"></div>
                        <?php endif; ?>
                        <div class="name-wrap">
                            <?php if ($flag !== ''): ?><span><?php echo $flag; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span><?php endif; ?>
                            <div class="name"><?php echo esc_html($name); ?></div>
                        </div>
                        <p class="sub"><?php echo esc_html((string) $tournament->name); ?></p>
                        <div class="row">
                            <span class="pill"><strong><?php esc_html_e('Elo', 'chess-podium'); ?>:</strong> <?php echo (int) $rating; ?></span>
                        </div>
                    </div>
                                    <?php endif; ?>
                                    </td>
                                <?php endfor; ?>
                            </tr>
                            <?php endfor; ?>
                        </table>
                    </div>
                <?php endfor; ?>
            </div>
        </body>
        </html>
        <?php
        return (string) ob_get_clean();
    }

    /**
     * Build a printable HTML document for placecards (tent cards).
     */
    public static function generate_placecards_html(object $tournament, array $players): string
    {
        $tid = (int) $tournament->id;
        $round = (int) ($tournament->current_round ?? 0);
        $title = esc_html((string) $tournament->name) . ' - ' . esc_html__('Placecards', 'chess-podium');

        usort($players, static fn ($a, $b) => strcasecmp((string) ($a->name ?? ''), (string) ($b->name ?? '')));

        ob_start();
        ?>
        <!doctype html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title><?php echo $title; ?></title>
            <style>
                @page { margin: 10mm; }
                body { font-family: "DejaVu Sans", Helvetica, Arial, sans-serif; color: #0f172a; margin: 0; }
                .meta { margin: 0 0 10mm 0; font-size: 10pt; color: #334155; }
                .sheet { width: 100%; }
                .cp-page { page-break-after: always; }
                .cp-page:last-child { page-break-after: auto; }
                .cp-grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
                .cp-grid td { width: 50%; vertical-align: top; }
                .card {
                    width: 100%;
                    border: 1px solid #cbd5e1;
                    border-radius: 6px;
                    overflow: hidden; /* strict cut: never overflow to next page */
                    box-sizing: border-box;
                    height: 132mm;
                }
                .face {
                    padding: 8mm 8mm 6mm;
                    border-bottom: 1px dashed #cbd5e1;
                    background: #ffffff;
                    height: 55mm;
                    box-sizing: border-box;
                    overflow: hidden;
                }
                .face.alt { background: #f8fafc; }
                .tournament { font-size: 10pt; color: #475569; margin: 0 0 2.5mm 0; font-weight: 700; }
                .name-wrap { display: flex; align-items: center; gap: 3mm; margin: 0 0 4mm 0; }
                .name { font-size: 18pt; font-weight: 900; line-height: 1.05; margin: 0 0 4mm 0; }
                .line { font-size: 10pt; color: #334155; margin: 0; display: flex; gap: 4mm; flex-wrap: wrap; }
                .line span { display: inline-block; padding: 2mm 3.2mm; border: 1px solid #e2e8f0; border-radius: 999px; background: #fff; }
                .hint { font-size: 9pt; color: #64748b; margin: 0; padding: 3mm 8mm; }
            </style>
        </head>
        <body>
            <div class="meta">
                <strong><?php echo esc_html((string) $tournament->name); ?></strong>
                <?php if ($round > 0): ?> — <?php echo esc_html(sprintf(__('Round %d', 'chess-podium'), $round)); ?><?php endif; ?>
                — <?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'))); ?>
            </div>
            <div class="sheet">
                <?php for ($idx = 0; $idx < count($players); $idx += 4): ?>
                    <div class="cp-page">
                        <table class="cp-grid">
                            <?php for ($row = 0; $row < 2; $row++): ?>
                            <tr>
                                <?php for ($col = 0; $col < 2; $col++): ?>
                                    <?php
                                    $slot = $row * 2 + $col;
                                    $p = $players[$idx + $slot] ?? null;
                                    $padRight = $col === 0 ? '4mm' : '0';
                                    $padLeft = $col === 1 ? '4mm' : '0';
                                    $padBottom = $row === 0 ? '6mm' : '0';
                                    ?>
                                    <td style="padding:0 <?php echo esc_attr($padRight); ?> <?php echo esc_attr($padBottom); ?> <?php echo esc_attr($padLeft); ?>;">
                                    <?php if ($p !== null):
                                        $pid = (int) ($p->id ?? 0);
                                        $name = (string) ($p->name ?? '');
                                        $rating = (int) ($p->rating ?? 0);
                                        $flag = self::render_flag_for_pdf((string) ($p->country ?? ''));
                                        $ptitle = (string) ($p->title ?? '');
                                        $table = $round > 0 ? self::get_assigned_table_for_player($tid, $pid, $round) : null;
                                    ?>
                    <div class="card">
                        <div class="face">
                            <p class="tournament"><?php echo esc_html((string) $tournament->name); ?></p>
                            <div class="name-wrap">
                                <?php if ($flag !== ''): ?><span><?php echo $flag; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span><?php endif; ?>
                                <div class="name"><?php echo esc_html($name); ?></div>
                            </div>
                            <p class="line">
                                <?php if ($ptitle !== ''): ?><span><strong><?php esc_html_e('Title', 'chess-podium'); ?>:</strong> <?php echo esc_html($ptitle); ?></span><?php endif; ?>
                                <span><strong><?php esc_html_e('Elo', 'chess-podium'); ?>:</strong> <?php echo (int) $rating; ?></span>
                                <span><strong><?php esc_html_e('Board', 'chess-podium'); ?>:</strong> <?php echo $table ? (int) $table : '—'; ?></span>
                            </p>
                        </div>
                        <div class="face alt">
                            <p class="tournament"><?php echo esc_html((string) $tournament->name); ?></p>
                            <div class="name-wrap">
                                <?php if ($flag !== ''): ?><span><?php echo $flag; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span><?php endif; ?>
                                <div class="name"><?php echo esc_html($name); ?></div>
                            </div>
                            <p class="line">
                                <?php if ($ptitle !== ''): ?><span><strong><?php esc_html_e('Title', 'chess-podium'); ?>:</strong> <?php echo esc_html($ptitle); ?></span><?php endif; ?>
                                <span><strong><?php esc_html_e('Elo', 'chess-podium'); ?>:</strong> <?php echo (int) $rating; ?></span>
                                <span><strong><?php esc_html_e('Board', 'chess-podium'); ?>:</strong> <?php echo $table ? (int) $table : '—'; ?></span>
                            </p>
                        </div>
                        <p class="hint"><?php esc_html_e('Cut and fold on the dashed line.', 'chess-podium'); ?></p>
                    </div>
                                    <?php endif; ?>
                                    </td>
                                <?php endfor; ?>
                            </tr>
                            <?php endfor; ?>
                        </table>
                    </div>
                <?php endfor; ?>
            </div>
        </body>
        </html>
        <?php
        return (string) ob_get_clean();
    }

    /**
     * Build a printable HTML document for board number cards (for tables).
     * Contains: logo + tournament name + big board number. Cut-ready grid.
     */
    public static function generate_boardcards_html(object $tournament): string
    {
        $tid = (int) ($tournament->id ?? 0);
        $round = (int) ($tournament->current_round ?? 0);
        $logo = self::resolve_tournament_logo_url($tournament);
        $boardCount = self::get_board_count_for_round($tid, $round);
        if ($boardCount <= 0) {
            // Fallback: estimate from players when pairings are not available yet.
            $players = class_exists('ChessPodiumPlugin') ? ChessPodiumPlugin::get_players($tid) : [];
            $boardCount = (int) floor(max(0, count($players)) / 2);
        }
        $title = esc_html((string) $tournament->name) . ' - ' . esc_html__('Board cards', 'chess-podium');

        // Layout: 2 columns x 3 rows = 6 cards per page (bigger, easier to cut).
        $perPage = 6;
        $cols = 2;
        $rows = 3;

        ob_start();
        ?>
        <!doctype html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title><?php echo $title; ?></title>
            <style>
                @page { margin: 10mm; }
                body { font-family: "DejaVu Sans", Helvetica, Arial, sans-serif; color: #0f172a; margin: 0; }
                .meta { margin: 0 0 8mm 0; font-size: 10pt; color: #334155; }
                .meta strong { color: #0f172a; }
                .cp-page { page-break-after: always; }
                .cp-page:last-child { page-break-after: auto; }
                .cp-grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
                .cp-grid td { vertical-align: top; }
                .cell { padding: 0 4mm 6mm 0; }
                .cell.right { padding-right: 0; padding-left: 4mm; }
                .cell.bottom { padding-bottom: 0; }
                .card {
                    border: 1px solid #cbd5e1;
                    border-radius: 6px;
                    overflow: hidden;
                    height: 78mm;
                    box-sizing: border-box;
                    background: #ffffff;
                }
                .header {
                    display: table;
                    width: 100%;
                    background: #f8fafc;
                    border-bottom: 1px solid #e2e8f0;
                    padding: 3mm 4mm;
                    box-sizing: border-box;
                    height: 18mm;
                }
                .header .logo { display: table-cell; vertical-align: middle; width: 26mm; }
                .header .logo img { width: 24mm; height: 10mm; object-fit: contain; display: block; }
                .header .tname { display: table-cell; vertical-align: middle; font-size: 10pt; font-weight: 800; color: #0f172a; }
                .numwrap {
                    height: 56mm;
                    display: table;
                    width: 100%;
                }
                .num {
                    display: table-cell;
                    vertical-align: middle;
                    text-align: center;
                    font-size: 72pt;
                    font-weight: 900;
                    letter-spacing: -1px;
                }
                .label {
                    text-align: center;
                    font-size: 10pt;
                    color: #475569;
                    margin-top: -3mm;
                    padding-bottom: 2mm;
                }
            </style>
        </head>
        <body>
            <div class="meta">
                <strong><?php echo esc_html((string) $tournament->name); ?></strong>
                <?php if ($round > 0): ?> — <?php echo esc_html(sprintf(__('Round %d', 'chess-podium'), $round)); ?><?php endif; ?>
                — <?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'))); ?>
            </div>
            <?php if ($boardCount <= 0): ?>
                <p><?php echo esc_html__('No boards found for the current round.', 'chess-podium'); ?></p>
            <?php else: ?>
                <?php for ($start = 1; $start <= $boardCount; $start += $perPage): ?>
                    <div class="cp-page">
                        <table class="cp-grid">
                            <?php for ($r = 0; $r < $rows; $r++): ?>
                            <tr>
                                <?php for ($c = 0; $c < $cols; $c++): ?>
                                    <?php
                                    $idx = $r * $cols + $c;
                                    $boardNo = $start + $idx;
                                    $isRight = ($c === $cols - 1);
                                    $isBottom = ($r === $rows - 1);
                                    ?>
                                    <td class="cell<?php echo $isRight ? ' right' : ''; ?><?php echo $isBottom ? ' bottom' : ''; ?>">
                                        <?php if ($boardNo <= $boardCount): ?>
                                            <div class="card">
                                                <div class="header">
                                                    <div class="logo">
                                                        <?php if ($logo !== ''): ?>
                                                            <img src="<?php echo esc_url($logo); ?>" alt="">
                                                        <?php endif; ?>
                                                    </div>
                                                    <div class="tname"><?php echo esc_html((string) $tournament->name); ?></div>
                                                </div>
                                                <div class="numwrap">
                                                    <div class="num"><?php echo (int) $boardNo; ?></div>
                                                </div>
                                                <div class="label"><?php echo esc_html__('Board', 'chess-podium'); ?></div>
                                            </div>
                                        <?php endif; ?>
                                    </td>
                                <?php endfor; ?>
                            </tr>
                            <?php endfor; ?>
                        </table>
                    </div>
                <?php endfor; ?>
            <?php endif; ?>
        </body>
        </html>
        <?php
        return (string) ob_get_clean();
    }

    /**
     * @return string|null PDF binary content
     */
    public static function generate_pdf(object $tournament, array $players, string $type): ?string
    {
        $autoload = CHESS_PODIUM_PLUGIN_DIR . '/lib/dompdf/vendor/autoload.php';
        if (!file_exists($autoload)) {
            $autoload = CHESS_PODIUM_PLUGIN_DIR . '/vendor/autoload.php';
        }
        if (!file_exists($autoload)) {
            return null;
        }
        require_once $autoload;
        if (!class_exists('Dompdf\\Dompdf')) {
            return null;
        }

        $html = $type === 'placecards'
            ? self::generate_placecards_html($tournament, $players)
            : ($type === 'boardcards'
                ? self::generate_boardcards_html($tournament)
                : self::generate_badges_html($tournament, $players));

        $dompdf = new \Dompdf\Dompdf(['isRemoteEnabled' => true]);
        $dompdf->loadHtml($html, 'UTF-8');
        $dompdf->setPaper('A4', 'portrait');
        $dompdf->render();
        return $dompdf->output();
    }
}

