using DeepDrftModels.DTOs;
using DeepDrftPublic.Client.Services;
using Microsoft.AspNetCore.Components;

namespace DeepDrftPublic.Client.Controls;

/// <summary>
/// Shared detail-page chrome for any release medium: back link, masthead, play/share affordance,
/// and hero/meta slots. Owns the play-toggle wiring against the cascaded streaming player so each
/// detail page supplies only its data and medium-specific visuals. Each medium's detail page is a
/// thin consumer of this scaffold.
/// </summary>
public partial class ReleaseDetailScaffold : ComponentBase
{
    [CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; }
    [CascadingParameter] public IQueueService? Queue { get; set; }

    [Parameter] public required string Title { get; set; }
    [Parameter] public string? Artist { get; set; }

    // The playable track for this release. Null while unresolved (or when a release has no
    // streamable track yet) — the play/share row is hidden in that case.
    [Parameter] public TrackDto? Track { get; set; }

    [Parameter] public string BackHref { get; set; } = "/archive";
    [Parameter] public string BackLabel { get; set; } = "Archive";

    /// <summary>
    /// Optional medium-specific content rendered as its own full-width band between the back/action top
    /// row and the masthead — the "below the back button, above the details" band. The Mix detail page
    /// uses it for the visualizer knob row (gated by Blazor on the lava-lamp toggle); other media leave
    /// it null.
    /// </summary>
    [Parameter] public RenderFragment? TopContent { get; set; }

    /// <summary>
    /// Optional action rendered at the top-right of the container, on the same SpaceBetween row as the
    /// back link (back link left, action right). The Mix detail page uses it for the lava-lamp
    /// visualizer-settings button; other media leave it null and render the back link alone.
    /// </summary>
    [Parameter] public RenderFragment? TopRightAction { get; set; }

    /// <summary>
    /// Optional replacement for the header region (masthead + play affordance). When null, the
    /// scaffold renders its default masthead+play row wired to <see cref="PlayTrack"/>. A composer
    /// that needs a different header arrangement (e.g. the Cut album's left-meta / right-cover split
    /// with its own Play/Share buttons) supplies this — layout variance rides the slot, never a
    /// boolean flag (Phase 9 §5.3).
    /// </summary>
    [Parameter] public RenderFragment? Header { get; set; }

    /// <summary>Medium-specific hero visual (cover art, hero image, or waveform background).</summary>
    [Parameter] public RenderFragment? Hero { get; set; }

    /// <summary>
    /// Optional full-bleed ambient layer rendered BEHIND the scaffold content (Phase 12 §3c/§3f mode B).
    /// A host that wants a living environment behind hero+content — e.g. Cut supplying a
    /// <c>WaveformVisualizer</c> — places it here. The mounted layer positions itself fixed/inset:0
    /// (its own CSS), so the scaffold only promotes its content into a foreground stacking context above
    /// it. Absent = today's plain background, no regression (Liskov). Mode A (Mix) and mode C (the
    /// NowPlaying card) mount the engine without this slot — see §3f.
    /// </summary>
    [Parameter] public RenderFragment? Ambient { get; set; }

    /// <summary>
    /// Optional body region rendered below the meta block — the Cut album's multi-track listing.
    /// Single-track media leave it null.
    /// </summary>
    [Parameter] public RenderFragment? BodyContent { get; set; }

    /// <summary>Optional medium-specific metadata block, rendered under a divider when present.</summary>
    [Parameter] public RenderFragment? MetaContent { get; set; }

    /// <summary>
    /// Gate for the header region (masthead + play, or a custom <see cref="Header"/>). A composer that
    /// carries title/artist/play elsewhere — e.g. Mix overlays them on its hero — sets this false to
    /// suppress the duplicate. A gate, not a layout flag, so it is slot-consistent with
    /// <see cref="ShowMeta"/> / <see cref="ShowShareRow"/> (Phase 9 §5.3). Defaults to shown.
    /// </summary>
    [Parameter] public bool ShowHeader { get; set; } = true;

    /// <summary>
    /// Gate for the metadata block. Lets a consumer supply a <see cref="MetaContent"/> fragment but
    /// suppress the divider + block when its data is empty (slot fragments cannot be conditionally
    /// attached inline). Defaults to shown.
    /// </summary>
    [Parameter] public bool ShowMeta { get; set; } = true;

    /// <summary>
    /// Gate for the default track-keyed share row at the foot of the scaffold. A composer that owns
    /// its own share affordance (the Cut header carries Play + Share inline) sets this false to
    /// suppress the duplicate. Defaults to shown.
    /// </summary>
    [Parameter] public bool ShowShareRow { get; set; } = true;

    private async Task PlayTrack()
    {
        if (Track is null || PlayerService is null) return;

        // Toggle if this track is already active (playing or paused); 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 (prerender / non-interactive).
        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);
        }
    }
}
