@page "/club/{Slug}"
@layout PublicLayout
@inject ISessionStore SessionStore
@inject IPortfolioStore PortfolioStore
@inject NavigationManager Navigation
@inject IHttpContextAccessor HttpContextAccessor
@inject AuthorizedMembershipService MembershipService
@using System.Security.Claims
@using GmRelay.Web.Components.Portfolio
@using GmRelay.Web.Services.Portfolio

<PageTitle>@PageTitleText</PageTitle>

@if (loaded && club is null)
{
    <HeadContent>
        <meta name="robots" content="noindex, nofollow" />
    </HeadContent>

    <section class="public-hero public-hero-compact">
        <span class="status-badge status-neutral">Недоступно</span>
        <h1>Публичная страница не найдена</h1>
        <p>Расписание клуба выключено или адрес больше не используется.</p>
    </section>
}
else if (!loaded)
{
    <section class="public-hero public-hero-compact">
        <div class="skeleton skeleton-text" style="width: 55%; height: 2rem;"></div>
        <div class="skeleton skeleton-text" style="width: 75%;"></div>
    </section>
}
else if (club is not null)
{
    <HeadContent>
        <meta name="description" content="@($"Публичное расписание клуба {club.Name} в GM-Relay.")" />
    </HeadContent>

    <section class="public-hero">
        <span class="status-badge status-success">Публичное расписание</span>
        <h1>@club.Name</h1>
        <p>Открытые игры клуба без состава игроков, личных данных и приватных ссылок.</p>
        <div class="public-share-row">
            <span>Ссылка клуба</span>
            <a href="@PublicClubUrl" target="_blank" rel="noopener noreferrer">@PublicClubUrl</a>
        </div>
        @if (!string.IsNullOrWhiteSpace(club.MasterProfileSlug))
        {
            <div class="public-share-row">
                <span>Мастер</span>
                <a href="@MasterProfilePath(club.MasterProfileSlug)" target="_blank" rel="noopener noreferrer">
                    @(club.MasterDisplayName ?? "Профиль мастера")
                </a>
            </div>
        }
    </section>

    @if (club.Sessions.Count == 0)
    {
        <div class="glass-card public-empty-state">
            <h2>Опубликованных игр пока нет</h2>
            <p>Когда owner или co-GM откроет сессии для публичного расписания, они появятся здесь.</p>
        </div>
    }
    else
    {
        var publicSessions = club.Sessions.Where(s => !s.IsMembersOnly).ToList();
        var membersOnlySessions = club.Sessions.Where(s => s.IsMembersOnly).ToList();

        @if (publicSessions.Count > 0)
        {
            <div class="public-session-list">
                @foreach (var session in publicSessions)
                {
                    <article class="public-session-card">
                        <div class="public-session-main">
                            <span class="status-badge @GetStatusClass(session.Status)">@TranslateStatus(session.Status)</span>
                            <h2>@session.Title</h2>
                            <div class="public-session-meta">
                                <span>@session.ScheduledAt.FormatMoscow()</span>
                                <span>@FormatSeats(session)</span>
                            </div>
                        </div>
                        <a class="btn-gm btn-gm-outline" href="@PublicSessionPath(session.Id)">Открыть</a>
                    </article>
                }
            </div>
        }

        @if (membersOnlySessions.Count > 0)
        {
            <section class="glass-card members-only-section">
                <h2>Игры для участников клуба</h2>
                @if (viewerIsActiveMember)
                {
                    <div class="public-session-list">
                        @foreach (var session in membersOnlySessions)
                        {
                            <article class="public-session-card">
                                <div class="public-session-main">
                                    <span class="status-badge status-warning">Только для участников</span>
                                    <h2>@session.Title</h2>
                                    <div class="public-session-meta">
                                        <span>@session.ScheduledAt.FormatMoscow()</span>
                                        <span>@FormatSeats(session)</span>
                                    </div>
                                </div>
                                <a class="btn-gm btn-gm-outline" href="@PublicSessionPath(session.Id)">Открыть</a>
                            </article>
                        }
                    </div>
                }
                else
                {
                    <p>Эти сессии доступны только одобренным участникам клуба.</p>
                    @if (viewerPlayerId is null)
                    {
                        <a class="btn-gm btn-gm-primary" href="/login?returnUrl=/club/@Slug">Войти как участник</a>
                    }
                    else
                    {
                        <details class="application-form">
                            <summary class="btn-gm btn-gm-primary">Подать заявку</summary>
                            <EditForm Model="@this" OnValidSubmit="TrySubmitApplicationAsync">
                                <div class="gm-form-group">
                                    <label class="gm-form-label" for="applicationMessage">Сообщение мастеру (необязательно)</label>
                                    <textarea id="applicationMessage" class="gm-form-control" maxlength="1000" @bind="applicationMessage" rows="3"></textarea>
                                </div>
                                @if (!string.IsNullOrEmpty(applicationError))
                                {
                                    <p class="form-error">@applicationError</p>
                                }
                                <button type="submit" class="btn-gm btn-gm-primary" disabled="@isSubmittingApplication">Отправить</button>
                            </EditForm>
                        </details>
                    }
                }
            </section>
        }
    }

    @if (portfolioGames.Count > 0)
    {
        <section class="glass-card portfolio-section">
            <h2>Завершённые игры клуба</h2>
            <p>Публичные портфолио, опубликованные мастерами этого клуба.</p>
            <PortfolioCardGrid Games="portfolioGames" />
        </section>
    }
}

@code {
    [Parameter] public string? Slug { get; set; }

    private WebPublicClub? club;
    private IReadOnlyList<PublicPortfolioCard> portfolioGames = [];
    private bool loaded;
    private Guid? viewerPlayerId;
    private bool viewerIsActiveMember;
    private string? applicationError;
    private string? applicationMessage;
    private bool isSubmittingApplication;

    private async Task TrySubmitApplicationAsync()
    {
        applicationError = null;
        if (club is null)
            return;

        try
        {
            isSubmittingApplication = true;
            await MembershipService.ApplyForCurrentUserAsync(club.GroupId, applicationMessage);
            applicationMessage = null;
        }
        catch (InvalidOperationException ex)
        {
            applicationError = ex.Message;
        }
        finally
        {
            isSubmittingApplication = false;
        }
    }

    private string PageTitleText => club is null ? "Публичный клуб — GM-Relay" : $"{club.Name} — GM-Relay";

    private string PublicClubUrl =>
        club is null
            ? Navigation.ToAbsoluteUri($"/club/{Slug}").ToString()
            : Navigation.ToAbsoluteUri($"/club/{club.Slug}").ToString();

    protected override async Task OnParametersSetAsync()
    {
        loaded = false;
        var trimmedSlug = string.IsNullOrWhiteSpace(Slug) ? null : Slug.Trim();
        applicationError = null;
        applicationMessage = null;

        // Resolve viewer identity (player id) for member-aware access.
        var user = HttpContextAccessor.HttpContext?.User;
        if (user?.Identity?.IsAuthenticated == true && user.TryGetPlatformIdentity(out _, out var externalUserId))
        {
            // We don't have platform here, but AuthorizedSessionService resolves via claims; use SessionStore directly
            // by reading both claims. Simpler: only resolve when both Platform and externalUserId are present.
            var platform = user.FindFirst("Platform")?.Value;
            viewerPlayerId = !string.IsNullOrWhiteSpace(platform)
                ? await SessionStore.GetPlayerIdByPlatformIdentityAsync(platform, externalUserId)
                : null;
        }
        else
        {
            viewerPlayerId = null;
        }

        club = trimmedSlug is null
            ? null
            : await SessionStore.GetPublicClubBySlugAsync(trimmedSlug, viewerPlayerId);
        portfolioGames = trimmedSlug is null
            ? []
            : await PortfolioStore.GetPublicPortfolioGamesForClubAsync(trimmedSlug);

        if (club is not null && viewerPlayerId is not null)
        {
            viewerIsActiveMember = await SessionStore.IsActiveClubMemberAsync(club.GroupId, viewerPlayerId.Value);
        }
        else
        {
            viewerIsActiveMember = false;
        }

        loaded = true;
    }

    private string PublicSessionPath(Guid sessionId) => $"/s/{sessionId}";

    private static string MasterProfilePath(string slug) => $"/gm/{slug}";

    private static string FormatSeats(WebPublicSession session)
    {
        var seats = session.MaxPlayers.HasValue
            ? $"{session.ActivePlayerCount}/{session.MaxPlayers.Value}"
            : $"{session.ActivePlayerCount} игроков";

        return session.WaitlistedPlayerCount > 0
            ? $"{seats}, ожидание {session.WaitlistedPlayerCount}"
            : seats;
    }

    private static string GetStatusClass(string status) => status switch
    {
        SessionStatus.Confirmed => "status-success",
        SessionStatus.ConfirmationSent => "status-warning",
        SessionStatus.Planned => "status-info",
        _ => "status-neutral"
    };

    private static string TranslateStatus(string status) => status switch
    {
        SessionStatus.Planned => "Запланировано",
        SessionStatus.ConfirmationSent => "Ждем подтверждения",
        SessionStatus.Confirmed => "Подтверждено",
        _ => status
    };
}
