<?php

namespace App\Repositories;

final class SheetTemplateRepository extends BaseRepository
{
    public function all(): array
    {
        $tournamentId = isset($_GET['tournament_id']) ? (int) $_GET['tournament_id'] : 0;
        if ($tournamentId > 0) {
            return $this->paginate(
                'SELECT st.*, CASE WHEN tst.sheet_template_id IS NULL THEN 0 ELSE 1 END AS assigned_to_tournament
                 FROM sheet_templates st
                 LEFT JOIN tournament_sheet_templates tst
                    ON tst.sheet_template_id = st.id AND tst.tournament_id = :tournament_id
                 ORDER BY assigned_to_tournament DESC, st.active DESC, st.name ASC',
                ['tournament_id' => $tournamentId]
            );
        }

        return $this->paginate('SELECT *, 0 AS assigned_to_tournament FROM sheet_templates ORDER BY active DESC, name ASC');
    }

    public function create(array $data): array
    {
        $stmt = $this->db->prepare(
            'INSERT INTO sheet_templates (code, name, image_path, page_width, page_height, config_json, active)
             VALUES (:code, :name, :image_path, :page_width, :page_height, :config_json, :active)'
        );
        $stmt->execute([
            'code' => $data['code'],
            'name' => $data['name'],
            'image_path' => $data['image_path'],
            'page_width' => (int) $data['page_width'],
            'page_height' => (int) $data['page_height'],
            'config_json' => is_string($data['config_json']) ? $data['config_json'] : json_encode($data['config_json']),
            'active' => (int) ($data['active'] ?? 1),
        ]);
        return $this->find((int) $this->db->lastInsertId());
    }

    public function update(int $id, array $data): ?array
    {
        $allowed = ['code', 'name', 'image_path', 'page_width', 'page_height', 'config_json', 'active'];
        $fields = [];
        $params = ['id' => $id];
        foreach ($allowed as $field) {
            if (array_key_exists($field, $data)) {
                $fields[] = "$field = :$field";
                $params[$field] = $field === 'config_json' && !is_string($data[$field]) ? json_encode($data[$field]) : $data[$field];
            }
        }
        if ($fields) {
            $this->db->prepare('UPDATE sheet_templates SET ' . implode(', ', $fields) . ' WHERE id = :id')->execute($params);
        }
        return $this->find($id);
    }

    public function assignToTournament(int $tournamentId, int $templateId): void
    {
        $this->db->prepare('DELETE FROM tournament_sheet_templates WHERE tournament_id = :id')->execute(['id' => $tournamentId]);
        $this->db->prepare(
            'INSERT INTO tournament_sheet_templates (tournament_id, sheet_template_id, is_default)
             VALUES (:tournament_id, :sheet_template_id, 1)'
        )->execute(['tournament_id' => $tournamentId, 'sheet_template_id' => $templateId]);
    }

    public function overrideMatch(int $matchId, int $templateId): void
    {
        $this->db->prepare(
            'INSERT INTO match_sheet_template_overrides (match_id, sheet_template_id)
             VALUES (:match_id, :sheet_template_id)
             ON DUPLICATE KEY UPDATE sheet_template_id = VALUES(sheet_template_id)'
        )->execute(['match_id' => $matchId, 'sheet_template_id' => $templateId]);
    }

    public function find(int $id): ?array
    {
        $stmt = $this->db->prepare('SELECT * FROM sheet_templates WHERE id = :id');
        $stmt->execute(['id' => $id]);
        return $stmt->fetch() ?: null;
    }

    public function resolveForMatch(int $matchId): ?array
    {
        $stmt = $this->db->prepare(
            'SELECT st.*
             FROM matches m
             LEFT JOIN match_sheet_template_overrides mo ON mo.match_id = m.id
             LEFT JOIN tournament_sheet_templates tt ON tt.tournament_id = m.tournament_id AND tt.is_default = 1
             JOIN sheet_templates st ON st.id = COALESCE(mo.sheet_template_id, tt.sheet_template_id)
             WHERE m.id = :id AND st.active = 1
             LIMIT 1'
        );
        $stmt->execute(['id' => $matchId]);
        $template = $stmt->fetch();
        if ($template) {
            return $template;
        }

        $stmt = $this->db->query('SELECT * FROM sheet_templates WHERE active = 1 ORDER BY id LIMIT 1');
        return $stmt->fetch() ?: null;
    }

    public function effectiveConfig(array $template): array
    {
        $config = json_decode($template['config_json'] ?? '{}', true);
        return is_array($config) ? $config : [];
    }
}
