@page "/sessions/{EntryKey}"
@using DeepDrftModels.DTOs
@using DeepDrftPublic.Client.Controls
@using DeepDrftPublic.Client.Services
@inherits ReleaseDetailBase
@inject SeoOptions Seo

@if (ViewModel.IsLoading)
{
    <div class="deepdrft-track-detail-container">
        <div class="deepdrft-track-detail-cover">
            <MudSkeleton SkeletonType="SkeletonType.Rectangle" Width="100%" Height="320px" />
        </div>
        <div class="deepdrft-track-detail-masthead">
            <MudSkeleton SkeletonType="SkeletonType.Text" Width="70%" Height="56px" />
            <MudSkeleton SkeletonType="SkeletonType.Text" Width="40%" Height="32px" />
        </div>
    </div>
}
else if (ViewModel.NotFound || ViewModel.Release is null)
{
    @* Soft-404: a bad key renders a 200 "not found" view, so it must carry noindex so it is not indexed
       (mirrors the dedicated /404 NotFound page). *@
    <SeoHead Model="@SeoModel.ForNotFound(Seo)" />
    <div class="deepdrft-track-detail-container">
        <div class="deepdrft-track-detail-masthead">
            <MudText Typo="Typo.h4" Align="Align.Center">Session not found.</MudText>
            <div class="d-flex justify-center mt-4">
                <MudButton Href="/sessions"
                           Variant="Variant.Text"
                           StartIcon="@Icons.Material.Filled.ArrowBack">
                    All sessions
                </MudButton>
            </div>
        </div>
    </div>
}
else
{
    var release = ViewModel.Release;
    var heroKey = release.SessionMetadata?.HeroImageEntryKey;
    // Hero image precedence: the session's dedicated hero, then the release cover, then a placeholder.
    var heroImage = !string.IsNullOrEmpty(heroKey) ? heroKey : release.ImagePath;

    @* SEO head — fed from the same bridged release, so prerender and WASM render identical tags (AC6).
       MusicAlbum/LiveAlbum (a session is a live release, §3.4/OQ6). *@
    <SeoHead Model="@SeoModel.ForRelease(Seo, release)" />

    @* Ambient living waveform behind the hero overlay (Phase 12 §3e option b / §3f mode B). Session does
       NOT compose ReleaseDetailScaffold, so it mounts the shared engine directly with its own thin
       full-bleed wrapper — the engine is single-source either way, only the mount differs (§3b). The
       visualizer positions itself fixed/inset:0; the session-detail-foreground class lifts the content
       above it. The bridge follows the live playing track; TrackEntryKey is the at-rest datum. *@
    <WaveformVisualizer ReleaseEntryKey="@release.EntryKey"
                        TrackId="@ViewModel.Track?.Id"
                        TrackEntryKey="@ViewModel.Track?.EntryKey" />

    <MudContainer MaxWidth="MaxWidth.Large" Class="session-detail-page session-detail-foreground dd-detail-fill">

        <div class="session-detail-top-row">
            <MudLink Href="/sessions" Typo="Typo.body2" Class="deepdrft-track-detail-back">
                &larr; All sessions
            </MudLink>

            @* Theater toggle sits immediately LEFT of the lava-lamp popover (Phase 20 §3). The whole top
               row (back + theater + lava) stays in Theater Mode — controls, not release content (§4/OQ4). *@
            <div class="dd-detail-top-actions">
                @* Theater toggle only appears when this Session is the currently-playing release
                   (Phase 20 Wave 2 §3). ShowTheaterToggle folds in the subsystem + release-playing gate. *@
                <TheaterModeToggle Available="ShowTheaterToggle" />
                @* Lava-lamp icon → popover panel (full parity, §3e/§3d-revised). Anchored top-right, clear of
                   the hero overlay and the share/play affordances overlaid on the hero below. *@
                <WaveformVisualizerControlPopover />
            </div>
        </div>

        @* Theater Mode (Phase 20 §4, Wave 2 §2): the hero overlay + blurb stay mounted and ease out via a
           collapsing wrapper so they do not pop — collapsed to zero height when Theater is on AND this
           Session is the playing release. The top row above stays. OFF eases this region back in. *@
        <div class="dd-theater-collapsible @(IsContentHidden ? "dd-theater-collapsed" : null)">
        <div class="dd-theater-collapsible-inner">
        @* The overlay shows the cover thumbnail only when it differs from the resolved hero image —
           when there is no dedicated hero, heroImage already falls back to release.ImagePath, so the
           thumb would duplicate the background. That logic lives in ReleaseHeroOverlay. *@
        <ReleaseHeroOverlay HeroImageKey="@heroImage"
                            CoverThumbKey="@release.ImagePath"
                            PlaceholderIcon="@Icons.Material.Filled.Piano"
                            Title="@release.Title"
                            Artist="@release.Artist"
                            Genre="@release.Genre"
                            ReleaseDate="@release.ReleaseDate">
            <ShareContent>
                @* Release-mode share: copies the canonical /sessions/{entryKey} URL, not a single track (§3b). *@
                <SharePopover ReleaseEntryKey="@release.EntryKey" ReleaseMedium="@release.Medium" />
            </ShareContent>
            <PlayContent>
                @if (ViewModel.Track is not null)
                {
                    <PlayStateIcon Track="@ViewModel.Track" Size="Size.Large" Color="Color.Secondary" OnToggle="@PlayTrack" />
                    @* Append-only: queues the session's single track without starting playback. *@
                    <AddToQueueButton Track="@ViewModel.Track" Size="Size.Large" />
                }
            </PlayContent>
        </ReleaseHeroOverlay>

        <ReleaseDescription Description="@release.Description" />
        </div>
        </div>

    </MudContainer>
}

@code {
    protected override string PersistKey => "session-detail";

    // PlayerService is cascaded by ReleaseDetailBase (used there for the Theater release-playing predicate).
    [CascadingParameter] public IQueueService? Queue { get; set; }

    // Mirrors the play-toggle wiring the shared scaffold owns. Session detail composes the player
    // affordance directly (it diverges from ReleaseDetailScaffold for the overlay layout), so the
    // toggle logic lives here: toggle if this track is already active, otherwise PLAY it — prepend to
    // the queue's front (deque PLAY semantics) so it becomes current and the existing queue stays
    // intact behind it. Falls back to a direct stream when the queue cascade is absent.
    private async Task PlayTrack()
    {
        var track = ViewModel.Track;
        if (track is null || PlayerService is null) return;

        var isThisTrack = PlayerService.CurrentTrack?.Id == track.Id;
        if (isThisTrack && (PlayerService.IsPlaying || PlayerService.IsPaused))
        {
            await PlayerService.TogglePlayPause();
        }
        else if (Queue is not null)
        {
            await Queue.PlayTrack(track);
        }
        else
        {
            await PlayerService.SelectTrackStreaming(track);
        }
    }
}
