@page "/application"
@page "/application.html"
@inject BrowserBridge Browser
@inject MatchStore Store
@inject NavigationManager Navigation

<PageTitle>ChessCubing Arena | Application</PageTitle>
<PageBody Page="setup" BodyClass="@SetupBodyClass" />

<div class="ambient ambient-left"></div>
<div class="ambient ambient-right"></div>

<div class="setup-shell">
    <header class="hero hero-setup">
        <div class="hero-copy">
            <a class="logo-lockup" href="index.html" aria-label="Accueil ChessCubing">
                <img class="hero-logo-icon" src="logo.png" alt="Icone ChessCubing" />
                <img class="hero-logo" src="transparent.png" alt="Logo ChessCubing" />
            </a>
            <p class="eyebrow">Application officielle de match</p>
            <h1>ChessCubing Arena</h1>
            <div class="hero-actions">
                <a class="button ghost" href="index.html">Accueil du site</a>
                <a class="button secondary" href="reglement.html">Consulter le reglement</a>
            </div>
        </div>

        <aside class="hero-preview">
            <div class="preview-card">
                <p class="micro-label">Flux de match</p>
                <ol class="phase-list">
                    <li>Configurer la rencontre</li>
                    <li>Passer a la page chrono</li>
                    <li>Basculer automatiquement sur la page cube</li>
                    <li>Revenir sur la page chrono pour le Block suivant</li>
                </ol>
            </div>
        </aside>
    </header>

    <main class="setup-grid">
        <section class="panel">
            <div class="section-heading">
                <div>
                    <p class="eyebrow">Nouvelle rencontre</p>
                    <h2>Configuration</h2>
                </div>
                <p class="section-copy">
                    Les reglages ci-dessous preparent les pages chrono et cube.
                </p>
            </div>

            <form class="setup-form" @onsubmit="HandleSubmit" @onsubmit:preventDefault="true" novalidate>
                <label class="option-card competition-option span-2 @(Form.CompetitionMode ? "is-selected" : string.Empty)">
                    <input @bind="Form.CompetitionMode" id="competitionMode" name="competitionMode" type="checkbox" />
                    <strong>Mode competition</strong>
                    <span>
                        Affiche le nom de la rencontre, l'arbitre, le club ou l'evenement
                        et les notes d'organisation.
                    </span>
                </label>

                @if (Form.CompetitionMode)
                {
                    <label class="field span-2" id="matchLabelField">
                        <span>Nom de la rencontre</span>
                        <input @bind="Form.MatchLabel" @bind:event="oninput" name="matchLabel" type="text" maxlength="80" placeholder="Open ChessCubing de Paris" />
                    </label>
                }

                <fieldset class="field span-2">
                    <legend>Mode officiel</legend>
                    <div class="option-grid mode-grid">
                        <label class="option-card @(Form.Mode == MatchEngine.ModeTwice ? "is-selected" : string.Empty)">
                            <input type="radio" name="mode" checked="@(Form.Mode == MatchEngine.ModeTwice)" @onchange="() => SetMode(MatchEngine.ModeTwice)" />
                            <strong>ChessCubing Twice</strong>
                            <span>
                                Le gagnant du cube ouvre le Block suivant et peut obtenir un
                                double coup V2.
                            </span>
                        </label>
                        <label class="option-card @(Form.Mode == MatchEngine.ModeTime ? "is-selected" : string.Empty)">
                            <input type="radio" name="mode" checked="@(Form.Mode == MatchEngine.ModeTime)" @onchange="() => SetMode(MatchEngine.ModeTime)" />
                            <strong>ChessCubing Time</strong>
                            <span>
                                Meme structure de Blocks, avec chronos cumules et alternance
                                bloc - / bloc +.
                            </span>
                        </label>
                    </div>
                </fieldset>

                <fieldset class="field span-2">
                    <legend>Cadence du match</legend>
                    <div class="option-grid preset-grid">
                        <label class="option-card @(Form.Preset == MatchEngine.PresetFast ? "is-selected" : string.Empty)">
                            <input type="radio" name="preset" checked="@(Form.Preset == MatchEngine.PresetFast)" @onchange="() => SetPreset(MatchEngine.PresetFast)" />
                            <strong>FAST</strong>
                            <span>6 coups par joueur</span>
                        </label>
                        <label class="option-card @(Form.Preset == MatchEngine.PresetFreeze ? "is-selected" : string.Empty)">
                            <input type="radio" name="preset" checked="@(Form.Preset == MatchEngine.PresetFreeze)" @onchange="() => SetPreset(MatchEngine.PresetFreeze)" />
                            <strong>FREEZE</strong>
                            <span>8 coups par joueur</span>
                        </label>
                        <label class="option-card @(Form.Preset == MatchEngine.PresetMasters ? "is-selected" : string.Empty)">
                            <input type="radio" name="preset" checked="@(Form.Preset == MatchEngine.PresetMasters)" @onchange="() => SetPreset(MatchEngine.PresetMasters)" />
                            <strong>MASTERS</strong>
                            <span>10 coups par joueur</span>
                        </label>
                    </div>
                </fieldset>

                <fieldset class="field span-2">
                    <legend>Temps personnalises</legend>
                    <div class="timing-grid">
                        <label class="field">
                            <span>Temps du Block (minutes)</span>
                            <input @bind="Form.BlockMinutes" name="blockMinutes" type="number" min="1" max="180" step="1" />
                        </label>

                        @if (!UsesMoveLimit)
                        {
                            <label class="field" id="timeInitialField">
                                <span>Temps de chaque joueur (minutes)</span>
                                <input @bind="Form.TimeInitialMinutes" name="timeInitialMinutes" type="number" min="1" max="180" step="1" />
                            </label>
                        }

                        @if (UsesMoveLimit)
                        {
                            <label class="field" id="moveSecondsField">
                                <span>Temps coup (secondes)</span>
                                <input @bind="Form.MoveSeconds" name="moveSeconds" type="number" min="5" max="300" step="1" />
                            </label>
                        }
                    </div>
                </fieldset>

                <label class="field">
                    <span>Joueur blanc</span>
                    <input @bind="Form.WhiteName" @bind:event="oninput" name="whiteName" type="text" maxlength="40" placeholder="Blanc" />
                </label>

                <label class="field">
                    <span>Joueur noir</span>
                    <input @bind="Form.BlackName" @bind:event="oninput" name="blackName" type="text" maxlength="40" placeholder="Noir" />
                </label>

                @if (Form.CompetitionMode)
                {
                    <label class="field" id="arbiterField">
                        <span>Arbitre</span>
                        <input @bind="Form.ArbiterName" @bind:event="oninput" name="arbiterName" type="text" maxlength="40" placeholder="Arbitre principal" />
                    </label>

                    <label class="field" id="eventField">
                        <span>Club / evenement</span>
                        <input @bind="Form.EventName" @bind:event="oninput" name="eventName" type="text" maxlength="60" placeholder="Club, tournoi, demonstration" />
                    </label>

                    <label class="field span-2" id="notesField">
                        <span>Notes</span>
                        <textarea @bind="Form.Notes" @bind:event="oninput" name="notes" rows="3" placeholder="Tirage au sort effectue, 8 cubes verifies, variante prete..."></textarea>
                    </label>
                }

                <div id="setupSummary" class="setup-summary span-2">
                    <strong>@CurrentMode.Label</strong>
                    <span>@CurrentPreset.Description</span>
                    <span>@TimingText</span>
                    <span>@TimeImpact</span>
                    <span>@QuotaText</span>
                </div>

                <div class="setup-actions span-2">
                    <button class="button primary" type="button" @onclick="HandleSubmit">Ouvrir la page chrono</button>
                    <button class="button secondary" id="loadDemoButton" type="button" @onclick="LoadDemo">Charger une demo</button>
                    <a class="button ghost" href="reglement.html">Consulter le reglement</a>
                </div>
            </form>
        </section>

        <aside class="panel side-panel">
            <div class="section-heading">
                <div>
                    <p class="eyebrow">Match en memoire</p>
                    <h2>Reprise rapide</h2>
                </div>
            </div>

            @if (!_ready || CurrentMatch is null)
            {
                <div id="resumeCard" class="resume-card empty">
                    <p>Aucun match en cours pour l'instant.</p>
                </div>
            }
            else
            {
                <div id="resumeCard" class="resume-card">
                    <strong>@ResumeMatchLabel(CurrentMatch)</strong>
                    <p>@CurrentMatchMode(CurrentMatch)</p>
                    <p>@($"{CurrentMatch.Config.WhiteName} vs {CurrentMatch.Config.BlackName}")</p>
                    <p>@ResumePhaseLabel(CurrentMatch)</p>
                    <div class="resume-actions">
                        <button class="button primary" id="resumeMatchButton" type="button" @onclick="ResumeMatch">
                            @(string.IsNullOrEmpty(CurrentMatch.Result) ? "Reprendre la phase" : "Voir le match")
                        </button>
                        <button class="button ghost" id="clearMatchButton" type="button" @onclick="ClearMatchAsync">Effacer le match</button>
                    </div>
                </div>
            }

            <div class="rules-stack">
                <article class="rule-card">
                    <span class="micro-label">Page chrono</span>
                    <strong>Gros boutons uniquement</strong>
                    <p>
                        Chaque joueur dispose d'une grande zone tactile pour signaler la
                        fin de son coup, puis l'app ouvre automatiquement la phase cube
                        quand le Block d'echecs est termine.
                    </p>
                </article>
                <article class="rule-card">
                    <span class="micro-label">Page cube</span>
                    <strong>Une page dediee</strong>
                    <p>
                        Les deux joueurs lancent et arretent leur propre chrono cube sur
                        un ecran separe, toujours en face-a-face sur mobile.
                    </p>
                </article>
                <article class="rule-card">
                    <span class="micro-label">Sources</span>
                    <strong>Reglements integres</strong>
                    <p>
                        <a href="reglement.html">Page reglement du site</a>
                        <br />
                        <a href="ChessCubing_Twice_Reglement_Officiel_V2-1.pdf" target="_blank">Reglement ChessCubing Twice</a>
                        <br />
                        <a href="ChessCubing_Time_Reglement_Officiel_V1-1.pdf" target="_blank">Reglement ChessCubing Time</a>
                    </p>
                </article>
            </div>
        </aside>
    </main>

    <div class="setup-refresh-footer">
        <button class="refresh-link-button" id="refreshAppButton" type="button" @onclick="ForceRefreshAsync">
            Rafraichir l'app
        </button>
    </div>
</div>

@code {
    private SetupFormModel Form { get; set; } = new();
    private bool _ready;

    private MatchState? CurrentMatch => Store.Current;

    private string SetupBodyClass => UsesMoveLimit ? string.Empty : "time-setup-mode";

    private bool UsesMoveLimit => MatchEngine.UsesMoveLimit(Form.Mode);

    private MatchPresetInfo CurrentPreset =>
        MatchEngine.Presets.TryGetValue(Form.Preset, out var preset)
            ? preset
            : MatchEngine.Presets[MatchEngine.PresetFast];

    private MatchModeInfo CurrentMode =>
        MatchEngine.Modes.TryGetValue(Form.Mode, out var mode)
            ? mode
            : MatchEngine.Modes[MatchEngine.ModeTwice];

    private string TimingText =>
        UsesMoveLimit
            ? $"Temps configures : Block {MatchEngine.FormatClock(Form.BlockMinutes * 60_000L)}, coup {MatchEngine.FormatClock(Form.MoveSeconds * 1_000L)}."
            : $"Temps configures : Block {MatchEngine.FormatClock(Form.BlockMinutes * 60_000L)}, temps de chaque joueur {MatchEngine.FormatClock(Form.TimeInitialMinutes * 60_000L)}.";

    private string TimeImpact =>
        Form.Mode == MatchEngine.ModeTime
            ? $"Chronos cumules de {MatchEngine.FormatClock(Form.TimeInitialMinutes * 60_000L)} par joueur, ajustes apres chaque phase cube avec plafond de 120 s pris en compte. Aucun temps par coup en mode Time."
            : "Le gagnant du cube commence le Block suivant, avec double coup V2 possible.";

    private string QuotaText =>
        UsesMoveLimit
            ? $"Quota actif : {CurrentPreset.Quota} coups par joueur."
            : $"Quota actif : {CurrentPreset.Quota} coups par joueur et par Block.";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender)
        {
            return;
        }

        await Store.EnsureLoadedAsync();
        _ready = true;
        StateHasChanged();
    }

    private async Task HandleSubmit()
    {
        await Store.EnsureLoadedAsync();
        var match = MatchEngine.CreateMatch(Form.ToMatchConfig());
        Store.SetCurrent(match);

        try
        {
            await Store.SaveAsync();
        }
        catch
        {
            // La navigation vers la phase chrono doit rester possible meme si la persistence
            // du navigateur echoue ponctuellement.
        }

        Navigation.NavigateTo("/chrono.html");
    }

    private void LoadDemo()
        => Form = SetupFormModel.CreateDemo();

    private void SetMode(string mode)
        => Form.Mode = mode;

    private void SetPreset(string preset)
        => Form.Preset = preset;

    private void ResumeMatch()
    {
        if (CurrentMatch is null)
        {
            return;
        }

        Navigation.NavigateTo(MatchEngine.RouteForMatch(CurrentMatch));
    }

    private async Task ClearMatchAsync()
    {
        await Store.ClearAsync();
        StateHasChanged();
    }

    private Task ForceRefreshAsync()
        => Browser.ForceRefreshAsync("/application.html").AsTask();

    private static string ResumeMatchLabel(MatchState match)
        => string.IsNullOrWhiteSpace(match.Config.MatchLabel) ? "Rencontre ChessCubing" : match.Config.MatchLabel;

    private static string CurrentMatchMode(MatchState match)
        => MatchEngine.Modes.TryGetValue(match.Config.Mode, out var mode) ? mode.Label : "ChessCubing Twice";

    private static string ResumePhaseLabel(MatchState match)
    {
        if (!string.IsNullOrEmpty(match.Result))
        {
            return MatchEngine.ResultText(match);
        }

        return match.Phase == MatchEngine.PhaseCube ? "Page cube prete" : "Page chrono prete";
    }
}
