<?php

namespace App\Controllers;

use App\Core\Database;
use App\Repositories\SheetTemplateRepository;

final class ScoresheetExportController
{
    public function ltv26(array $params): void
    {
        $matchId = (int) $params['id'];
        $db = Database::connection();
        $templateRow = (new SheetTemplateRepository())->resolveForMatch($matchId);
        if (!$templateRow) {
            $template = require __DIR__ . '/../../config/templates/ltv26_scoresheet.php';
        } else {
            $template = json_decode($templateRow['config_json'], true);
            $template = is_array($template) ? $template : [];
            $template['image'] = $templateRow['image_path'];
            $template['width'] = (int) $templateRow['page_width'];
            $template['height'] = (int) $templateRow['page_height'];
        }
        $match = $this->match($db, $matchId);
        $sets = $this->rows($db, 'SELECT * FROM match_sets WHERE match_id = :id ORDER BY set_number', $matchId);
        $homePlayers = $this->players($db, (int) $match['home_team_id']);
        $awayPlayers = $this->players($db, (int) $match['away_team_id']);
        $signatures = $this->rows($db, 'SELECT * FROM referee_signatures WHERE match_id = :id ORDER BY signed_at DESC', $matchId);

        header('Content-Type: text/html; charset=utf-8');
        header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
        if ($templateRow) {
            $payload = json_encode(['match_id' => $matchId, 'template_id' => $templateRow['id'], 'time' => time()]);
            $db->prepare(
                'INSERT INTO match_sheet_exports (match_id, sheet_template_id, export_type, export_hash)
                 VALUES (:match_id, :sheet_template_id, "html", :export_hash)'
            )->execute([
                'match_id' => $matchId,
                'sheet_template_id' => $templateRow['id'],
                'export_hash' => hash('sha256', $payload),
            ]);
        }
        echo $this->html($template, $match, $sets, $homePlayers, $awayPlayers, $signatures);
    }

    private function html(array $template, array $match, array $sets, array $homePlayers, array $awayPlayers, array $signatures): string
    {
        $fields = [
            'tournament' => $match['tournament_name'],
            'match_code' => '#' . $match['id'],
            'date' => $match['scheduled_at'] ? date('d/m/Y', strtotime($match['scheduled_at'])) : '',
            'time' => $match['scheduled_at'] ? date('H:i', strtotime($match['scheduled_at'])) : '',
            'court' => $match['court_name'] ?? '',
            'home_team' => $match['home_team'],
            'away_team' => $match['away_team'],
            'home_sets' => (string) $match['home_sets'],
            'away_sets' => (string) $match['away_sets'],
            'referee_signature' => $signatures[0]['signer_name'] ?? '',
        ];

        $items = [];
        foreach ($fields as $key => $value) {
            if (isset($template['fields'][$key])) {
                $items[] = $this->box($template, $template['fields'][$key], $value);
            }
        }
        foreach ($sets as $index => $set) {
            if (!isset($template['result_rows'][$index], $template['result_columns'])) {
                continue;
            }
            $row = $template['result_rows'][$index];
            $cols = $template['result_columns'];
            $items[] = $this->box($template, ['x' => $cols['home_pt']['x'], 'y' => $row['y'], 'w' => $cols['home_pt']['w'], 'size' => 11, 'align' => 'center'], (string) $set['home_points']);
            $items[] = $this->box($template, ['x' => $cols['set']['x'], 'y' => $row['y'], 'w' => $cols['set']['w'], 'size' => 11, 'align' => 'center'], $set['home_points'] . ' - ' . $set['away_points']);
            $items[] = $this->box($template, ['x' => $cols['away_pt']['x'], 'y' => $row['y'], 'w' => $cols['away_pt']['w'], 'size' => 11, 'align' => 'center'], (string) $set['away_points']);
        }
        if (!empty($template['home_players'])) {
            $items = array_merge($items, $this->playerBoxes($template, $template['home_players'], $homePlayers));
        }
        if (!empty($template['away_players'])) {
            $items = array_merge($items, $this->playerBoxes($template, $template['away_players'], $awayPlayers));
        }

        $image = htmlspecialchars($template['image'], ENT_QUOTES);
        return '<!doctype html><html><head><meta charset="utf-8"><title>Planilla LTV 26</title>'
            . '<style>@page{size:landscape;margin:0}body{margin:0;background:#e5e7eb;padding:16px}.sheet{position:relative;width:min(100%,'
            . (int) $template['width'] . 'px);margin:0 auto;background:#fff;box-shadow:0 18px 60px rgba(15,23,42,.25)}.sheet-img{display:block;width:100%;height:auto}.txt{position:absolute;font-family:Arial,sans-serif;font-weight:700;color:#111;white-space:nowrap;overflow:hidden;line-height:1.1}.toolbar{position:fixed;right:16px;top:16px;z-index:3}.toolbar button{border:0;border-radius:6px;background:#16a34a;color:white;font-weight:800;padding:10px 14px}.missing{padding:24px;color:#991b1b;font-family:Arial;font-weight:700}@media print{body{background:#fff;padding:0}.sheet{width:100vw;max-width:none;box-shadow:none}.toolbar{display:none}}</style>'
            . '</head><body><div class="toolbar"><button onclick="window.print()">Imprimir / PDF</button></div><main class="sheet">'
            . '<img class="sheet-img" src="' . $image . '" alt="Planilla" onerror="this.insertAdjacentHTML(\'afterend\', \'<div class=&quot;missing&quot;>No se pudo cargar la imagen de plantilla: ' . $image . '</div>\'); this.remove();">'
            . implode('', $items)
            . '</main></body></html>';
    }

    private function box(array $template, array $box, string $value): string
    {
        $align = $box['align'] ?? 'left';
        $valign = $box['valign'] ?? 'top';
        $translate = match ($valign) {
            'middle' => 'translateY(-50%)',
            'bottom' => 'translateY(-100%)',
            default => 'none',
        };
        $style = sprintf(
            'left:%s%%;top:%s%%;width:%s%%;font-size:%spx;text-align:%s;transform:%s',
            ($box['x'] / $template['width']) * 100,
            ($box['y'] / $template['height']) * 100,
            ($box['w'] / $template['width']) * 100,
            $box['size'],
            $align,
            $translate
        );
        return '<span class="txt" style="' . $style . '">' . htmlspecialchars($value) . '</span>';
    }

    private function playerBoxes(array $template, array $config, array $players): array
    {
        foreach (['x', 'y', 'row_h', 'number_w', 'name_w', 'size'] as $required) {
            if (!isset($config[$required])) {
                return [];
            }
        }
        $items = [];
        foreach (array_slice($players, 0, 14) as $index => $player) {
            $y = $config['y'] + ($index * $config['row_h']);
            $items[] = $this->box($template, ['x' => $config['x'], 'y' => $y, 'w' => $config['number_w'], 'size' => $config['size'], 'align' => 'center'], (string) ($player['jersey_number'] ?? ''));
            $items[] = $this->box($template, ['x' => $config['x'] + $config['number_w'], 'y' => $y, 'w' => $config['name_w'], 'size' => $config['size']], $player['first_name'] . ' ' . $player['last_name']);
        }
        return $items;
    }

    private function match(\PDO $db, int $matchId): array
    {
        $stmt = $db->prepare(
            'SELECT m.*, tr.name tournament_name, ht.name home_team, at.name away_team, c.name court_name
             FROM matches m
             JOIN tournaments tr ON tr.id = m.tournament_id
             JOIN teams ht ON ht.id = m.home_team_id
             JOIN teams at ON at.id = m.away_team_id
             LEFT JOIN courts c ON c.id = m.court_id
             WHERE m.id = :id'
        );
        $stmt->execute(['id' => $matchId]);
        return $stmt->fetch() ?: [];
    }

    private function players(\PDO $db, int $teamId): array
    {
        $stmt = $db->prepare('SELECT * FROM players WHERE team_id = :id ORDER BY jersey_number, last_name');
        $stmt->execute(['id' => $teamId]);
        return $stmt->fetchAll();
    }

    private function rows(\PDO $db, string $sql, int $matchId): array
    {
        $stmt = $db->prepare($sql);
        $stmt->execute(['id' => $matchId]);
        return $stmt->fetchAll();
    }
}
