@extends('admin.layouts.app')

@section('title', __('Matches Builder'))

@php
    $championshipName = is_array($championship->name)
        ? ($championship->name[app()->getLocale()] ?? $championship->name['en'] ?? reset($championship->name))
        : $championship->name;

    $gameName = null;
    if ($championship->game) {
        $gameName = is_array($championship->game->name)
            ? ($championship->game->name[app()->getLocale()] ?? $championship->game->name['en'] ?? reset($championship->game->name))
            : $championship->game->name;
    }
@endphp

@push('styles')
<style>
    .matches-builder-page {
        --mb-surface:       #f4f6f9;
        --mb-card:          #ffffff;
        --mb-border:        #e2e6ef;
        --mb-text:          #1e293b;
        --mb-muted:         #64748b;
        --mb-primary:       #1e40af;
        --mb-primary-soft:  #eff6ff;
        --mb-danger:        #b91c1c;
        --mb-danger-bg:     #fef2f2;
        --mb-success:       #15803d;
        --mb-radius:        14px;
        --mb-radius-sm:     10px;
    }

    .matches-builder-page .builder-hero {
        background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 55%, #2563eb 100%);
        border-radius: var(--mb-radius);
        padding: 1.5rem 1.75rem;
        color: #fff;
        margin-bottom: 1.25rem;
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        gap: 1.25rem;
        flex-wrap: wrap;
        box-shadow: 0 10px 40px rgba(30, 58, 138, 0.2);
    }
    .matches-builder-page .builder-hero h4 {
        color: #fff;
        font-size: 1.125rem;
        font-weight: 700;
        margin-bottom: 0.25rem;
    }
    .matches-builder-page .builder-hero p {
        color: rgba(255,255,255,0.72);
        font-size: 0.8125rem;
        margin: 0;
        max-width: 36rem;
        line-height: 1.5;
    }
    .matches-builder-page .builder-summary {
        display: flex;
        gap: 0.625rem;
        flex-wrap: wrap;
    }
    .matches-builder-page .summary-box {
        min-width: 5.5rem;
        background: rgba(255,255,255,0.12);
        border: 1px solid rgba(255,255,255,0.2);
        border-radius: 12px;
        padding: 0.625rem 1rem;
        text-align: center;
    }
    .matches-builder-page .summary-box .summary-label {
        display: block;
        font-size: 0.6875rem;
        color: rgba(255,255,255,0.65);
        margin-bottom: 0.25rem;
        text-transform: uppercase;
        letter-spacing: 0.04em;
    }
    .matches-builder-page .summary-box .summary-value {
        font-size: 1.375rem;
        font-weight: 800;
        color: #fff;
        line-height: 1;
    }

    .matches-builder-page .builder-settings-card {
        background: var(--mb-card);
        border: 1px solid var(--mb-border);
        border-radius: var(--mb-radius);
        margin-bottom: 1.25rem;
        overflow: hidden;
        box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
    }
    .matches-builder-page .builder-settings-card .settings-head {
        padding: 0.875rem 1.25rem;
        background: var(--mb-surface);
        border-bottom: 1px solid var(--mb-border);
        font-size: 0.8125rem;
        font-weight: 700;
        color: var(--mb-text);
    }
    .matches-builder-page .settings-grid {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
    }
    .matches-builder-page .settings-field {
        padding: 1rem 1.25rem;
        border-inline-end: 1px solid var(--mb-border);
        border-bottom: 1px solid var(--mb-border);
    }
    .matches-builder-page .settings-field:nth-child(3n) {
        border-inline-end: none;
    }
    .matches-builder-page .settings-field:nth-last-child(-n+3) {
        border-bottom: none;
    }
    .matches-builder-page .settings-field label {
        display: block;
        font-size: 0.6875rem;
        font-weight: 700;
        color: var(--mb-muted);
        text-transform: uppercase;
        letter-spacing: 0.06em;
        margin-bottom: 0.375rem;
    }
    .matches-builder-page .settings-field .form-control,
    .matches-builder-page .settings-field .form-select {
        font-size: 0.875rem;
        border: 1px solid var(--mb-border);
        border-radius: var(--mb-radius-sm);
        padding: 0.5rem 0.75rem;
        background: var(--mb-card);
    }
    .matches-builder-page .settings-field .form-control:focus,
    .matches-builder-page .settings-field .form-select:focus {
        border-color: var(--mb-primary);
        box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
    }

    .matches-builder-page .builder-errors {
        display: none;
        border-radius: var(--mb-radius-sm);
        border: 1px solid #fecaca;
        background: var(--mb-danger-bg);
    }
    .matches-builder-page .builder-errors.show {
        display: block;
    }

    .matches-builder-page .builder-empty {
        border: 2px dashed var(--mb-border);
        border-radius: var(--mb-radius);
        padding: 3rem 1.5rem;
        text-align: center;
        color: var(--mb-muted);
        background: var(--mb-surface);
    }

    .matches-builder-page .matches-panel {
        background: var(--mb-card);
        border: 1px solid var(--mb-border);
        border-radius: var(--mb-radius);
        overflow: hidden;
        box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
    }
    .matches-builder-page .matches-panel-head {
        display: flex;
        justify-content: space-between;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.75rem;
        padding: 1rem 1.25rem;
        background: var(--mb-surface);
        border-bottom: 1px solid var(--mb-border);
    }
    .matches-builder-page .matches-panel-head h5 {
        font-size: 0.9375rem;
        font-weight: 700;
        margin: 0;
        color: var(--mb-text);
    }
    .matches-builder-page .matches-panel-body {
        padding: 1.25rem;
        background: var(--mb-surface);
    }

    /* Match card — light professional tile */
    .matches-builder-page .mb-match-card {
        background: var(--mb-card);
        border: 1px solid var(--mb-border);
        border-radius: var(--mb-radius);
        overflow: hidden;
        transition: box-shadow 0.2s ease, border-color 0.2s ease;
    }
    .matches-builder-page .mb-match-card:hover {
        box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);
    }
    .matches-builder-page .mb-match-card.has-error {
        border-color: #f87171;
        box-shadow: 0 0 0 1px rgba(248, 113, 113, 0.35);
    }

    .matches-builder-page .mb-match-card .mb-match-head {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 0.75rem;
        padding: 0.75rem 1.125rem;
        background: #fafbfc;
        border-bottom: 1px solid var(--mb-border);
    }
    .matches-builder-page .mb-match-head-title {
        font-size: 0.8125rem;
        font-weight: 700;
        color: var(--mb-text);
        line-height: 1.35;
    }
    .matches-builder-page .mb-match-head-sub {
        font-size: 0.75rem;
        color: var(--mb-muted);
        margin-top: 0.125rem;
    }
    .matches-builder-page .mb-btn-delete {
        font-size: 0.75rem;
        font-weight: 600;
        padding: 0.35rem 0.85rem;
        border-radius: 8px;
        border: 1px solid var(--mb-border);
        background: var(--mb-card);
        color: var(--mb-muted);
        transition: color 0.15s, border-color 0.15s, background 0.15s;
    }
    .matches-builder-page .mb-btn-delete:hover {
        color: var(--mb-danger);
        border-color: #fecaca;
        background: var(--mb-danger-bg);
    }

    .matches-builder-page .mb-match-body {
        padding: 1.125rem 1.125rem 0.5rem;
    }
    .matches-builder-page .mb-teams-row {
        display: flex;
        align-items: flex-end;
        gap: 0.75rem;
    }
    .matches-builder-page .mb-team-col {
        flex: 1;
        min-width: 0;
    }
    .matches-builder-page .mb-team-col label {
        display: block;
        font-size: 0.6875rem;
        font-weight: 700;
        color: var(--mb-muted);
        text-transform: uppercase;
        letter-spacing: 0.05em;
        margin-bottom: 0.375rem;
    }
    .matches-builder-page .mb-team-col .form-select {
        font-size: 0.875rem;
        border: 1px solid var(--mb-border);
        border-radius: var(--mb-radius-sm);
        padding: 0.55rem 0.75rem;
        width: 100%;
    }
    .matches-builder-page .mb-team-col .form-select:focus {
        border-color: var(--mb-primary);
        box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
    }
    .matches-builder-page .mb-team-col .form-select.is-filled {
        border-color: #93c5fd;
        background: var(--mb-primary-soft);
        color: var(--mb-primary);
        font-weight: 600;
    }

    .matches-builder-page .mb-vs-wrap {
        flex-shrink: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        padding-bottom: 0.125rem;
    }
    .matches-builder-page .mb-vs {
        width: 2.5rem;
        height: 2.5rem;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 0.625rem;
        font-weight: 800;
        letter-spacing: 0.06em;
        color: var(--mb-muted);
        background: var(--mb-surface);
        border: 1px solid var(--mb-border);
    }

    .matches-builder-page .mb-time-row {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 0.75rem;
        padding: 0.75rem 1.125rem 1rem;
    }
    .matches-builder-page .mb-time-row label {
        display: flex;
        align-items: center;
        gap: 0.35rem;
        font-size: 0.6875rem;
        font-weight: 700;
        color: var(--mb-muted);
        text-transform: uppercase;
        letter-spacing: 0.05em;
        margin-bottom: 0.375rem;
    }
    .matches-builder-page .mb-time-row label i {
        font-size: 0.875rem;
        opacity: 0.7;
    }
    .matches-builder-page .mb-time-row .form-control,
    .matches-builder-page .mb-time-row .form-select {
        font-size: 0.8125rem;
        border: 1px solid var(--mb-border);
        border-radius: var(--mb-radius-sm);
        padding: 0.5rem 0.65rem;
    }
    .matches-builder-page .mb-time-row .form-control:focus,
    .matches-builder-page .mb-time-row .form-select:focus {
        border-color: var(--mb-primary);
        box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
    }

    .matches-builder-page .mb-inline-error {
        display: none;
        margin: 0 1.125rem 0.75rem;
        padding: 0.5rem 0.75rem;
        border-radius: var(--mb-radius-sm);
        font-size: 0.8125rem;
        font-weight: 500;
        color: var(--mb-danger);
        background: var(--mb-danger-bg);
        border: 1px solid #fecaca;
        align-items: center;
        gap: 0.5rem;
    }
    .matches-builder-page .mb-inline-error.show {
        display: flex;
    }
    .matches-builder-page .mb-inline-error i {
        font-size: 1.1rem;
        flex-shrink: 0;
    }

    .matches-builder-page .mb-match-footer {
        padding: 0.65rem 1.125rem;
        background: #f8fafc;
        border-top: 1px solid var(--mb-border);
        font-size: 0.8125rem;
        color: var(--mb-muted);
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.35rem 0.5rem;
    }
    .matches-builder-page .mb-footer-team {
        font-weight: 600;
        color: var(--mb-primary);
        text-decoration: none;
        cursor: default;
    }
    .matches-builder-page .mb-footer-team.is-placeholder {
        font-weight: 500;
        font-style: italic;
        color: var(--mb-muted);
    }
    .matches-builder-page .mb-footer-sep {
        color: #cbd5e1;
        user-select: none;
    }
    .matches-builder-page .mb-footer-meta {
        display: inline-flex;
        align-items: center;
        gap: 0.25rem;
        margin-inline-start: auto;
        font-size: 0.75rem;
        color: var(--mb-muted);
    }
    .matches-builder-page .mb-footer-meta i {
        font-size: 0.9rem;
        opacity: 0.75;
    }

    /* Spacer between cards (visual rhythm) */
    .matches-builder-page .mb-card-spacer {
        display: flex;
        justify-content: center;
        padding: 0.35rem 0;
    }
    .matches-builder-page .mb-card-spacer button {
        width: 2.25rem;
        height: 2.25rem;
        border-radius: 50%;
        border: 1px solid var(--mb-border);
        background: var(--mb-card);
        color: var(--mb-muted);
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 1rem;
        transition: background 0.15s, color 0.15s, border-color 0.15s;
    }
    .matches-builder-page .mb-card-spacer button:hover {
        background: var(--mb-primary-soft);
        color: var(--mb-primary);
        border-color: #93c5fd;
    }

    .matches-builder-page .btn-add-match {
        background: var(--mb-primary);
        color: #fff;
        border: none;
        border-radius: var(--mb-radius-sm);
        padding: 0.5rem 1.1rem;
        font-size: 0.8125rem;
        font-weight: 600;
        display: inline-flex;
        align-items: center;
        gap: 0.35rem;
    }
    .matches-builder-page .btn-add-match:hover {
        background: #1d4ed8;
        color: #fff;
    }
    .matches-builder-page .btn-add-match:disabled {
        opacity: 0.45;
        pointer-events: none;
    }

    .matches-builder-page .sticky-actions {
        position: sticky;
        bottom: 0.75rem;
        z-index: 10;
        margin-top: 1.25rem;
    }
    .matches-builder-page .save-bar {
        background: var(--mb-card);
        border: 1px solid var(--mb-border);
        border-radius: var(--mb-radius);
        padding: 1rem 1.25rem;
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 0.75rem;
        flex-wrap: wrap;
        box-shadow: 0 -4px 24px rgba(15, 23, 42, 0.08);
    }
    .matches-builder-page .save-bar .tip {
        font-size: 0.8125rem;
        color: var(--mb-muted);
        max-width: 28rem;
        line-height: 1.45;
    }
    .matches-builder-page .btn-create-matches {
        background: var(--mb-success);
        color: #fff;
        border: none;
        border-radius: var(--mb-radius-sm);
        padding: 0.55rem 1.35rem;
        font-size: 0.8125rem;
        font-weight: 600;
        display: inline-flex;
        align-items: center;
        gap: 0.35rem;
    }
    .matches-builder-page .btn-create-matches:hover {
        background: #166534;
        color: #fff;
    }
    .matches-builder-page .btn-create-matches:disabled {
        opacity: 0.45;
        pointer-events: none;
    }

    @media (max-width: 991.98px) {
        .matches-builder-page .settings-grid {
            grid-template-columns: repeat(2, 1fr);
        }
        .matches-builder-page .settings-field:nth-child(3n) {
            border-inline-end: 1px solid var(--mb-border);
        }
        .matches-builder-page .settings-field:nth-child(2n) {
            border-inline-end: none;
        }
        .matches-builder-page .mb-time-row {
            grid-template-columns: 1fr 1fr;
        }
    }
    @media (max-width: 575.98px) {
        .matches-builder-page .settings-grid {
            grid-template-columns: 1fr;
        }
        .matches-builder-page .settings-field {
            border-inline-end: none !important;
        }
        .matches-builder-page .mb-teams-row {
            flex-direction: column;
            align-items: stretch;
        }
        .matches-builder-page .mb-vs-wrap {
            order: -1;
            padding: 0.25rem 0;
        }
        .matches-builder-page .mb-time-row {
            grid-template-columns: 1fr;
        }
        .matches-builder-page .mb-footer-meta {
            margin-inline-start: 0;
            width: 100%;
        }
    }
</style>
@endpush

@section('content')
<div class="matches-builder-page">
    <x-admin.page-header
        title="{{ __('Matches Builder') }}"
        :breadcrumbs="[
            __('Championships') => route('admin.championships.index'),
            $championshipName => route('admin.championships.show', $championship->id),
            __('Matches Builder') => '#',
        ]"
    />

    <div class="builder-hero">
        <div>
            <h4 class="mb-1">{{ $championshipName }}</h4>
            <p>{{ __('Build multiple matches quickly using simple cards and team selectors.') }}</p>
        </div>
        <div class="builder-summary">
            <div class="summary-box">
                <span class="summary-label">{{ __('Game') }}</span>
                <span class="summary-value">{{ $gameName ?: __('N/A') }}</span>
            </div>
            <div class="summary-box">
                <span class="summary-label">{{ __('Teams') }}</span>
                <span class="summary-value">{{ count($teamsPayload) }}</span>
            </div>
            <div class="summary-box">
                <span class="summary-label">{{ __('Matches') }}</span>
                <span class="summary-value" id="summary-matches-count">0</span>
            </div>
        </div>
    </div>

    <div class="builder-settings-card">
        <div class="settings-head">
            <i class="ri-settings-3-line me-1"></i>{{ __('Round Settings') }}
        </div>
        <div class="settings-grid">
            <div class="settings-field">
                <label for="builder-match-date">{{ __('Date') }} <span class="text-danger">*</span></label>
                <input type="date" id="builder-match-date" class="form-control" value="{{ now()->format('Y-m-d') }}">
            </div>
            <div class="settings-field">
                <label for="builder-stage">{{ __('Round') }} <span class="text-danger">*</span></label>
                <select id="builder-stage" class="form-select">
                    <option value="">{{ __('Select Round') }}</option>
                    @foreach($stages as $stage)
                        <option value="{{ $stage['value'] }}">{{ $stage['label'] }}</option>
                    @endforeach
                </select>
            </div>
            <div class="settings-field">
                <label for="builder-round-label">{{ __('Round Label') }}</label>
                <input type="text" id="builder-round-label" class="form-control" maxlength="50" placeholder="{{ __('Optional custom label') }}">
            </div>
            <div class="settings-field">
                <label for="builder-default-start">{{ __('Start Time') }}</label>
                <input type="time" id="builder-default-start" class="form-control" value="16:00">
            </div>
            <div class="settings-field">
                <label for="builder-default-end">{{ __('End Time') }}</label>
                <input type="time" id="builder-default-end" class="form-control" value="17:00">
            </div>
            <div class="settings-field">
                <label for="builder-default-court">{{ __('Court') }}</label>
                <select id="builder-default-court" class="form-select">
                    <option value="">{{ __('Select court') }}</option>
                    @foreach($courts as $court)
                        <option value="{{ $court->id }}">{{ $court->name }}</option>
                    @endforeach
                </select>
            </div>
        </div>
    </div>

    <div id="builder-errors" class="alert builder-errors mb-3"></div>

    <div class="matches-panel">
        <div class="matches-panel-head">
            <h5>{{ __('Matches') }}</h5>
            <div class="d-flex gap-2 align-items-center">
                <a href="{{ route('admin.championships.show', $championship->id) }}" class="btn btn-outline-secondary btn-sm">
                    <i class="ri-arrow-left-line me-1"></i>{{ __('Back') }}
                </a>
                <button type="button" id="add-match-btn" class="btn-add-match" @disabled(empty($teamsPayload))>
                    <i class="ri-add-line"></i>{{ __('Add Match') }}
                </button>
            </div>
        </div>
        <div class="matches-panel-body">
            @if(empty($teamsPayload))
                <div class="builder-empty">
                    <i class="ri-team-line fs-1 d-block mb-3"></i>
                    <h5 class="mb-2">{{ __('No teams available') }}</h5>
                    <p class="mb-0">{{ __('Add teams to this championship first, then come back to build matches.') }}</p>
                </div>
            @else
                <div id="matches-empty-state" class="builder-empty">
                    <i class="ri-calendar-event-line fs-1 d-block mb-3"></i>
                    <h5 class="mb-2">{{ __('No matches added yet') }}</h5>
                    <p class="mb-3">{{ __('Start by adding your first match card.') }}</p>
                    <button type="button" class="btn btn-outline-primary btn-sm" id="add-first-match-btn">
                        <i class="ri-add-line me-1"></i>{{ __('Add First Match') }}
                    </button>
                </div>

                <div id="matches-list" class="d-flex flex-column"></div>

                <div class="sticky-actions">
                    <div class="save-bar">
                        <div class="tip">
                            <strong>{{ __('Tip:') }}</strong>
                            {{ __('A team can only be selected once on the chosen date.') }}
                        </div>
                        <button type="button" id="submit-builder-btn" class="btn-create-matches" @disabled(empty($teamsPayload))>
                            <i class="ri-save-line"></i>{{ __('Create Matches') }}
                        </button>
                    </div>
                </div>
            @endif
        </div>
    </div>
</div>
@endsection

@push('scripts')
<script>
(function () {
    const teams       = @json($teamsPayload);
    const courts      = @json($courtsPayload);
    const bulkUrl     = @json(route('admin.championships.matches.bulk', $championship->id));
    const redirectUrl = @json(route('admin.championships.show', $championship->id));
    const csrfToken   = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '{{ csrf_token() }}';

    const str = {
        selectTeam: @json(__('Select team')),
        selectCourt: @json(__('Select court')),
        notSpecified: @json(__('Not specified yet')),
        match: @json(__('Match')),
        round: @json(__('Round')),
        teamARequired: @json(__('Team A is required for this match.')),
        teamBRequired: @json(__('Team B is required to complete this match.')),
        sameTeam: @json(__('A team cannot play against itself.')),
        timeOrder: @json(__('End time must be after start time.')),
        teamUsed: @json(__('This team is already used in another match on this date.')),
        fixGeneric: @json(__('Please check this match card.')),
    };

    const matchesList       = document.getElementById('matches-list');
    const emptyState        = document.getElementById('matches-empty-state');
    const addMatchBtn       = document.getElementById('add-match-btn');
    const addFirstMatchBtn  = document.getElementById('add-first-match-btn');
    const submitBtn         = document.getElementById('submit-builder-btn');
    const errorBox          = document.getElementById('builder-errors');
    const summaryMatchesCount = document.getElementById('summary-matches-count');

    const dateInput         = document.getElementById('builder-match-date');
    const stageInput        = document.getElementById('builder-stage');
    const roundLabelInput   = document.getElementById('builder-round-label');
    const defaultStartInput = document.getElementById('builder-default-start');
    const defaultEndInput   = document.getElementById('builder-default-end');
    const defaultCourtInput = document.getElementById('builder-default-court');

    let nextId = 1;
    let matchCards = [];

    function teamName(teamId) {
        const t = teams.find(x => String(x.id) === String(teamId));
        return t ? t.name : '';
    }
    function courtName(courtId) {
        const c = courts.find(x => String(x.id) === String(courtId));
        return c ? c.name : '';
    }
    function escapeHtml(v) {
        return String(v ?? '')
            .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;').replace(/'/g, '&#039;');
    }

    function showErrors(errors) {
        if (!errors.length) {
            errorBox.classList.remove('show', 'alert-danger');
            errorBox.innerHTML = '';
            return;
        }
        errorBox.classList.add('show', 'alert-danger');
        errorBox.innerHTML =
            '<div class="fw-semibold mb-2">{{ __('Please fix the following issues:') }}</div>' +
            '<ul class="mb-0 ps-3">' + errors.map(e => '<li>' + escapeHtml(e) + '</li>').join('') + '</ul>';
        window.scrollTo({ top: 0, behavior: 'smooth' });
    }

    function getUsedTeamIds(excludeCardId) {
        const s = new Set();
        matchCards.forEach(c => {
            if (excludeCardId != null && c.id === excludeCardId) return;
            if (c.team_a_id) s.add(String(c.team_a_id));
            if (c.team_b_id) s.add(String(c.team_b_id));
        });
        return s;
    }

    function buildTeamOptions(card, field) {
        const cur = String(card[field] || '');
        const other = String(field === 'team_a_id' ? (card.team_b_id || '') : (card.team_a_id || ''));
        const used = getUsedTeamIds(card.id);
        let html = '<option value="">' + escapeHtml(str.selectTeam) + '</option>';
        teams.forEach(team => {
            const v = String(team.id);
            const sel = cur === v ? 'selected' : '';
            const dis = !sel && (used.has(v) || (other && other === v)) ? 'disabled' : '';
            html += '<option value="' + v + '" ' + sel + ' ' + dis + '>' + escapeHtml(team.name) + '</option>';
        });
        return html;
    }

    function buildCourtOptions(card) {
        const cur = String(card.court_id || '');
        let html = '<option value="">' + escapeHtml(str.selectCourt) + '</option>';
        courts.forEach(court => {
            const v = String(court.id);
            html += '<option value="' + v + '" ' + (cur === v ? 'selected' : '') + '>' + escapeHtml(court.name) + '</option>';
        });
        return html;
    }

    /** Per-card first message + global errors */
    function validateCards() {
        const errors = [];
        const invalidIds = new Set();
        const cardMsg = {};
        const used = new Set();

        if (!dateInput.value) errors.push('{{ __('Date is required.') }}');
        if (!stageInput.value) errors.push('{{ __('Round is required.') }}');
        if (!matchCards.length) errors.push('{{ __('Add at least one match card.') }}');

        matchCards.forEach((card, i) => {
            const title = str.match + ' #' + (i + 1);
            const msgs = [];

            if (!card.team_a_id) {
                errors.push(title + ': ' + str.teamARequired);
                invalidIds.add(card.id);
                msgs.push(str.teamARequired);
            }
            if (!card.team_b_id) {
                errors.push(title + ': ' + str.teamBRequired);
                invalidIds.add(card.id);
                msgs.push(str.teamBRequired);
            }
            if (card.team_a_id && card.team_b_id && String(card.team_a_id) === String(card.team_b_id)) {
                errors.push(title + ': ' + str.sameTeam);
                invalidIds.add(card.id);
                msgs.push(str.sameTeam);
            }
            if (card.start_time && card.end_time && card.end_time <= card.start_time) {
                errors.push(title + ': ' + str.timeOrder);
                invalidIds.add(card.id);
                msgs.push(str.timeOrder);
            }
            ['team_a_id', 'team_b_id'].forEach(f => {
                const v = card[f] ? String(card[f]) : '';
                if (!v) return;
                if (used.has(v)) {
                    errors.push(title + ': ' + str.teamUsed);
                    invalidIds.add(card.id);
                    msgs.push(str.teamUsed);
                } else {
                    used.add(v);
                }
            });
            if (invalidIds.has(card.id) && msgs.length) {
                cardMsg[card.id] = msgs[0];
            }
        });

        return { errors, invalidIds, cardMsg };
    }

    function roundLabelText() {
        return (roundLabelInput && roundLabelInput.value.trim())
            || (stageInput && stageInput.options[stageInput.selectedIndex]?.text)
            || str.round;
    }

    function footerHtml(card) {
        const a = teamName(card.team_a_id);
        const b = teamName(card.team_b_id);
        const tagA = a
            ? '<span class="mb-footer-team">' + escapeHtml(a) + '</span>'
            : '<span class="mb-footer-team is-placeholder">' + escapeHtml(str.notSpecified) + '</span>';
        const tagB = b
            ? '<span class="mb-footer-team">' + escapeHtml(b) + '</span>'
            : '<span class="mb-footer-team is-placeholder">' + escapeHtml(str.notSpecified) + '</span>';

        let meta = '';
        if (card.start_time) {
            meta += '<span class="mb-footer-meta"><i class="ri-time-line"></i> ' + escapeHtml(card.start_time);
            if (card.end_time) meta += ' – ' + escapeHtml(card.end_time);
            meta += '</span>';
        }
        if (card.court_id) {
            meta += '<span class="mb-footer-meta"><i class="ri-building-2-line"></i> ' + escapeHtml(courtName(card.court_id)) + '</span>';
        }

        return tagA + '<span class="mb-footer-sep">·</span><span class="text-muted small">vs</span><span class="mb-footer-sep">·</span>' + tagB + meta;
    }

    function singleCardHtml(card, index, validation) {
        const hasErr = validation.invalidIds.has(card.id);
        const msg = validation.cardMsg[card.id] || str.fixGeneric;
        const roundText = roundLabelText();
        const fa = card.team_a_id ? 'is-filled' : '';
        const fb = card.team_b_id ? 'is-filled' : '';

        return (
            '<div class="mb-match-card' + (hasErr ? ' has-error' : '') + '" data-card-id="' + card.id + '">' +
                '<div class="mb-match-head">' +
                    '<div>' +
                        '<div class="mb-match-head-title">' + escapeHtml(str.match) + ' #' + (index + 1) + '</div>' +
                        '<div class="mb-match-head-sub">' + escapeHtml(roundText) + '</div>' +
                    '</div>' +
                    '<button type="button" class="mb-btn-delete remove-match-btn" data-card-id="' + card.id + '">' +
                        '<i class="ri-delete-bin-line me-1"></i>{{ __('Remove') }}' +
                    '</button>' +
                '</div>' +
                '<div class="mb-match-body">' +
                    '<div class="mb-teams-row">' +
                        '<div class="mb-team-col">' +
                            '<label>{{ __('Team A') }}</label>' +
                            '<select class="form-select ' + fa + ' card-input" data-field="team_a_id" data-card-id="' + card.id + '">' +
                                buildTeamOptions(card, 'team_a_id') +
                            '</select>' +
                        '</div>' +
                        '<div class="mb-vs-wrap"><div class="mb-vs">VS</div></div>' +
                        '<div class="mb-team-col">' +
                            '<label>{{ __('Team B') }}</label>' +
                            '<select class="form-select ' + fb + ' card-input" data-field="team_b_id" data-card-id="' + card.id + '">' +
                                buildTeamOptions(card, 'team_b_id') +
                            '</select>' +
                        '</div>' +
                    '</div>' +
                '</div>' +
                '<div class="mb-time-row">' +
                    '<div>' +
                        '<label><i class="ri-time-line"></i> {{ __('Start Time') }}</label>' +
                        '<input type="time" class="form-control card-input" data-field="start_time" data-card-id="' + card.id + '" value="' + escapeHtml(card.start_time || '') + '">' +
                    '</div>' +
                    '<div>' +
                        '<label><i class="ri-time-line"></i> {{ __('End Time') }}</label>' +
                        '<input type="time" class="form-control card-input" data-field="end_time" data-card-id="' + card.id + '" value="' + escapeHtml(card.end_time || '') + '">' +
                    '</div>' +
                    '<div>' +
                        '<label><i class="ri-building-2-line"></i> {{ __('Court') }}</label>' +
                        '<select class="form-select card-input" data-field="court_id" data-card-id="' + card.id + '">' +
                            buildCourtOptions(card) +
                        '</select>' +
                    '</div>' +
                '</div>' +
                '<div class="mb-inline-error' + (hasErr ? ' show' : '') + '" data-inline-error>' +
                    '<i class="ri-error-warning-line"></i><span data-inline-msg>' + (hasErr ? escapeHtml(msg) : '') + '</span>' +
                '</div>' +
                '<div class="mb-match-footer">' + footerHtml(card) + '</div>' +
            '</div>'
        );
    }

    function renderSpacer() {
        return (
            '<div class="mb-card-spacer">' +
                '<button type="button" class="add-between-btn" title="{{ __('Add match') }}"><i class="ri-arrow-down-s-line"></i></button>' +
            '</div>'
        );
    }

    function renderAllCards() {
        if (!matchesList) return;
        summaryMatchesCount.textContent = String(matchCards.length);

        if (!matchCards.length) {
            matchesList.innerHTML = '';
            if (emptyState) emptyState.style.display = 'block';
            return;
        }
        if (emptyState) emptyState.style.display = 'none';

        const v = validateCards();
        const parts = [];
        matchCards.forEach((card, i) => {
            if (i > 0) parts.push(renderSpacer());
            parts.push(singleCardHtml(card, i, v));
        });
        matchesList.innerHTML = parts.join('');
    }

    function refreshAllTeamSelects() {
        matchCards.forEach(card => {
            const root = matchesList.querySelector('.mb-match-card[data-card-id="' + card.id + '"]');
            if (!root) return;
            ['team_a_id', 'team_b_id'].forEach(field => {
                const sel = root.querySelector('select[data-field="' + field + '"]');
                if (!sel) return;
                const saved = String(card[field] || '');
                sel.innerHTML = buildTeamOptions(card, field);
                if (saved) sel.value = saved;
                sel.classList.toggle('is-filled', !!saved);
            });
        });
    }

    function refreshFooter(cardId) {
        const card = matchCards.find(c => c.id === cardId);
        const root = matchesList.querySelector('.mb-match-card[data-card-id="' + cardId + '"]');
        if (!card || !root) return;
        const foot = root.querySelector('.mb-match-footer');
        if (foot) foot.innerHTML = footerHtml(card);
    }

    function applyValidationVisuals() {
        const v = validateCards();
        matchCards.forEach(card => {
            const root = matchesList.querySelector('.mb-match-card[data-card-id="' + card.id + '"]');
            if (!root) return;
            const hasErr = v.invalidIds.has(card.id);
            root.classList.toggle('has-error', hasErr);
            const err = root.querySelector('[data-inline-error]');
            const span = root.querySelector('[data-inline-msg]');
            if (err && span) {
                err.classList.toggle('show', hasErr);
                span.textContent = hasErr ? (v.cardMsg[card.id] || str.fixGeneric) : '';
            }
        });
    }

    function updateCard(cardId, field, value) {
        const card = matchCards.find(c => c.id === cardId);
        if (!card) return;
        card[field] = value;
        showErrors([]);
        refreshAllTeamSelects();
        refreshFooter(cardId);
        applyValidationVisuals();
    }

    function addMatchCard() {
        matchCards.push({
            id: nextId++,
            team_a_id: '',
            team_b_id: '',
            start_time: defaultStartInput?.value || '',
            end_time: defaultEndInput?.value || '',
            court_id: defaultCourtInput?.value || '',
        });
        showErrors([]);
        renderAllCards();
    }

    function removeMatchCard(cardId) {
        matchCards = matchCards.filter(c => c.id !== cardId);
        showErrors([]);
        renderAllCards();
    }

    async function submitBuilder() {
        const v = validateCards();
        if (v.errors.length) {
            showErrors(v.errors);
            applyValidationVisuals();
            return;
        }

        const orig = submitBtn.innerHTML;
        submitBtn.disabled = true;
        submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>{{ __('Creating...') }}';

        const payload = {
            stage: stageInput.value,
            round: roundLabelInput.value.trim() || null,
            match_date: dateInput.value,
            matches: matchCards.map(c => ({
                team_a_id: c.team_a_id,
                team_b_id: c.team_b_id,
                start_time: c.start_time || null,
                end_time: c.end_time || null,
                court_id: c.court_id || null,
            })),
        };

        try {
            const response = await fetch(bulkUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'application/json',
                    'X-CSRF-TOKEN': csrfToken,
                },
                body: JSON.stringify(payload),
            });
            const data = await response.json();
            if (!response.ok || data.success === false) {
                const be = data.errors ? Object.values(data.errors).flat() : [data.message || '{{ __('An error occurred while creating matches.') }}'];
                showErrors(be);
                applyValidationVisuals();
                return;
            }
            showErrors([]);
            Swal.fire({
                icon: 'success',
                title: data.message || '{{ __('Matches created successfully') }}',
                timer: 1400,
                showConfirmButton: false,
            }).then(() => {
                window.location.href = data.redirect_url || redirectUrl;
            });
        } catch (e) {
            showErrors(['{{ __('Network error. Please try again.') }}']);
        } finally {
            submitBtn.disabled = false;
            submitBtn.innerHTML = orig;
        }
    }

    if (addMatchBtn) addMatchBtn.addEventListener('click', addMatchCard);
    if (addFirstMatchBtn) addFirstMatchBtn.addEventListener('click', addMatchCard);

    if (matchesList) {
        matchesList.addEventListener('click', e => {
            const del = e.target.closest('.remove-match-btn');
            if (del) {
                removeMatchCard(Number(del.dataset.cardId));
                return;
            }
            const between = e.target.closest('.add-between-btn');
            if (between) addMatchCard();
        });

        matchesList.addEventListener('change', e => {
            const input = e.target.closest('.card-input');
            if (!input) return;
            updateCard(Number(input.dataset.cardId), input.dataset.field, input.value);
        });

        matchesList.addEventListener('input', e => {
            const input = e.target.closest('input.card-input');
            if (!input) return;
            updateCard(Number(input.dataset.cardId), input.dataset.field, input.value);
        });
    }

    if (submitBtn) submitBtn.addEventListener('click', submitBuilder);

    [dateInput, stageInput, roundLabelInput].forEach(el => {
        if (!el) return;
        el.addEventListener('change', () => {
            showErrors([]);
            const t = roundLabelText();
            matchesList?.querySelectorAll('.mb-match-head-sub').forEach(n => { n.textContent = t; });
            applyValidationVisuals();
        });
    });

    renderAllCards();
})();
</script>
@endpush
