@model StoryIntelligenceProgressViewModel
@using System.Security.Claims
@inject IConfiguration Configuration
@{
    ViewData["Title"] = "Review scenes";
    var adminEmails = Configuration.GetSection("Admin:AllowedEmails").Get<string[]>() ?? [];
    var userEmail = User.FindFirstValue(ClaimTypes.Email);
    var isAdmin = !string.IsNullOrWhiteSpace(userEmail)
        && adminEmails.Any(email => string.Equals(email, userEmail, StringComparison.OrdinalIgnoreCase));
    var chaptersNeedingReview = Model.Chapters.Count(NeedsReview);
    var warningsCount = Model.Chapters.Sum(chapter => NeedsReviewCount(chapter));
}

<section class="onboarding-shell" aria-labelledby="story-review-title">
    <div class="onboarding-panel onboarding-review-panel story-review-page">
        <partial name="_StoryIntelligencePipelineHeader" model="@(new StoryIntelligencePipelineHeaderViewModel { CurrentStage = "Review Scenes" })" />
        <div class="onboarding-copy story-review-heading">
            <p class="eyebrow">Phase 3</p>
            <p class="story-review-heading__phase">Review Story Intelligence</p>
            <p class="story-review-heading__stage">Stage 1 of 4</p>
            <h1 id="story-review-title">Review Scenes</h1>
            <p>PlotDirector has finished reading your manuscript. Review the detected scenes before creating them in your story database.</p>
        </div>

        @if (TempData["OnboardingStoryIntelligenceError"] is string error)
        {
            <div class="alert alert-danger">@error</div>
        }
        @if (TempData["OnboardingStoryIntelligenceMessage"] is string message)
        {
            <div class="alert alert-success">@message</div>
        }

        <section class="alert alert-info">
            Scene creation runs first. Character import is reviewed separately and only creates or links approved characters. Locations, assets, relationships and knowledge remain for later Story Intelligence phases.
        </section>

        <section class="story-review-summary" aria-label="Analysis summary">
            <div>
                <span>Story Intelligence complete</span>
                <strong>@Model.CompletedChapterCount.ToString("N0") chapter@(Model.CompletedChapterCount == 1 ? string.Empty : "s")</strong>
            </div>
            <div>
                <span>Scenes detected</span>
                <strong>@Model.TotalDetectedScenes.ToString("N0")</strong>
            </div>
            <div>
                <span>Words analysed</span>
                <strong>@Model.TotalAnalysedWords.ToString("N0")</strong>
            </div>
            <div>
                <span>Elapsed time</span>
                <strong>@FormatDuration(Model.TotalDurationMs)</strong>
            </div>
            <div>
                <span>Estimated AI cost</span>
                <strong>@FormatCost(Model.TotalEstimatedCostUSD)</strong>
            </div>
            <div>
                <span>Needs review</span>
                <strong>@warningsCount.ToString("N0")</strong>
            </div>
        </section>

        <section class="story-review-chapter-list" aria-label="Chapter review">
            @foreach (var chapter in Model.Chapters.OrderBy(chapter => chapter.ChapterNumber))
            {
                <details class="story-review-chapter-card">
                    <summary class="story-review-chapter-heading">
                        <div>
                            <p class="eyebrow">Chapter @chapter.ChapterNumber</p>
                            <h2>@chapter.ChapterTitle</h2>
                            <p>@DetectedCount(chapter).ToString("N0") scene@(DetectedCount(chapter) == 1 ? string.Empty : "s") detected / @ReadyCount(chapter).ToString("N0") ready to create</p>
                        </div>
                        <strong class="@StatusClass(chapter)">@FriendlyStatus(chapter)</strong>
                    </summary>

                    <div class="story-review-scene-panel">
                        <div>
                            <span>Detected scenes</span>
                            <strong>@DetectedCount(chapter).ToString("N0")</strong>
                        </div>
                        <div>
                            <span>Ready</span>
                            <strong>@ReadyCount(chapter).ToString("N0")</strong>
                        </div>
                        <div>
                            <span>Needs review</span>
                            <strong>@NeedsReviewCount(chapter).ToString("N0")</strong>
                        </div>
                        <div>
                            <span>Rejected</span>
                            <strong>@RejectedCount(chapter).ToString("N0")</strong>
                        </div>
                    </div>

                    @if (!string.IsNullOrWhiteSpace(chapter.CommitMessage))
                    {
                        <p class="story-review-note">@chapter.CommitMessage</p>
                    }

                    @if (chapter.Warnings.Count > 0)
                    {
                        <div class="story-review-note">
                            <strong>Notes</strong>
                            <ul>
                                @foreach (var warning in chapter.Warnings)
                                {
                                    <li>@AuthorMessage(warning)</li>
                                }
                            </ul>
                        </div>
                    }

                    @if (chapter.Blockers.Count > 0)
                    {
                        <div class="story-review-note story-review-note--warning">
                            <strong>Before scenes can be created</strong>
                            <ul>
                                @foreach (var blocker in chapter.Blockers)
                                {
                                    <li>@AuthorMessage(blocker)</li>
                                }
                            </ul>
                        </div>
                    }

                    @if (!string.IsNullOrWhiteSpace(chapter.ErrorMessage))
                    {
                        <p class="story-review-note story-review-note--warning">@AuthorMessage(chapter.ErrorMessage)</p>
                    }

                    <div class="story-scene-preview-list">
                        @if (chapter.Scenes.Count == 0)
                        {
                            <p class="text-muted mb-0">No readable scene previews are available for this chapter.</p>
                        }
                        else
                        {
                            @foreach (var scene in chapter.Scenes)
                            {
                                <article class="story-scene-preview">
                                    <div>
                                        <strong>Scene @scene.SceneNumber.ToString("N0")</strong>
                                        @if (scene.HasWarnings)
                                        {
                                            <span class="story-review-status story-review-status--active">Review recommended</span>
                                        }
                                    </div>
                                    <p>@scene.Summary</p>
                                    <dl>
                                        <div><dt>POV</dt><dd>@Display(scene.Pov)</dd></div>
                                        <div><dt>Setting</dt><dd>@Display(scene.Setting)</dd></div>
                                        <div><dt>Confidence</dt><dd>@FormatConfidence(scene.Confidence)</dd></div>
                                    </dl>
                                </article>
                            }
                        }
                    </div>

                    @if (isAdmin)
                    {
                        <details class="story-review-admin">
                            <summary>Admin diagnostics</summary>
                            <dl>
                                <div><dt>Run ID</dt><dd>@chapter.RunID</dd></div>
                                <div><dt>Status</dt><dd>@chapter.Status</dd></div>
                                <div><dt>Stage</dt><dd>@(chapter.CurrentStage ?? "-")</dd></div>
                                <div><dt>Failure stage</dt><dd>@(chapter.FailureStage ?? "-")</dd></div>
                                <div><dt>Tokens</dt><dd>@(chapter.TotalTokens?.ToString("N0") ?? "-")</dd></div>
                            </dl>
                            <a class="btn btn-outline-secondary btn-sm" asp-controller="Admin" asp-action="StoryIntelligenceRunDetails" asp-route-id="@chapter.RunID">Open diagnostics</a>
                        </details>
                    }
                </details>
            }
        </section>

        <section class="alert alert-info">
            Scene creation uses PlotDirector import safeguards. Duplicate imports are blocked, and failures roll back safely.
        </section>

        <div class="onboarding-actions">
            @if (Model.BatchID.HasValue)
            {
                <a class="btn btn-outline-secondary" asp-action="StoryIntelligenceProgress" asp-route-batchId="@Model.BatchID">Back</a>
                @if (Model.HasReadyScenesToCreate)
                {
                    <form asp-action="CommitAllStoryIntelligence" method="post">
                        <input type="hidden" name="batchId" value="@Model.BatchID" />
                        <button class="btn btn-primary" type="submit">Create PlotDirector Scenes</button>
                    </form>
                }
                else if (Model.AllCommitted)
                {
                    <a class="btn btn-primary" asp-action="StoryIntelligenceCharacters" asp-route-batchId="@Model.BatchID">Review characters</a>
                }
            }
        </div>
    </div>
</section>

@functions {
    private static bool NeedsReview(StoryIntelligenceOnboardingChapterViewModel chapter)
        => chapter.IsFailed
            || chapter.Blockers.Count > 0
            || NeedsReviewCount(chapter) > 0
            || (!chapter.CanCommit && !chapter.HasCompletedCommit && chapter.IsRunComplete);

    private static int DetectedCount(StoryIntelligenceOnboardingChapterViewModel chapter)
        => Math.Max(chapter.TotalDetectedScenes ?? 0, ReadyCount(chapter) + Math.Max(chapter.FailedScenes ?? 0, 0));

    private static int ReadyCount(StoryIntelligenceOnboardingChapterViewModel chapter)
        => chapter.HasCompletedCommit ? chapter.ScenesCreated : chapter.Scenes.Count;

    private static int RejectedCount(StoryIntelligenceOnboardingChapterViewModel chapter) => 0;

    private static int NeedsReviewCount(StoryIntelligenceOnboardingChapterViewModel chapter)
        => Math.Max(0, DetectedCount(chapter) - ReadyCount(chapter) - RejectedCount(chapter));

    private static string FriendlyStatus(StoryIntelligenceOnboardingChapterViewModel chapter)
    {
        if (chapter.HasCompletedCommit)
        {
            return "Scenes created";
        }

        if (chapter.CanCommit)
        {
            return "Ready";
        }

        return chapter.Status switch
        {
            StoryIntelligenceRunStatuses.Pending => "Waiting",
            StoryIntelligenceRunStatuses.Running => "Reading",
            StoryIntelligenceRunStatuses.Completed => "Cannot import",
            StoryIntelligenceRunStatuses.CompletedWithWarnings => "Cannot import",
            StoryIntelligenceRunStatuses.Failed => "Needs review",
            StoryIntelligenceRunStatuses.Cancelled => "Cancelled",
            _ => "Needs review"
        };
    }

    private static string StatusClass(StoryIntelligenceOnboardingChapterViewModel chapter)
    {
        if (chapter.HasCompletedCommit)
        {
            return "story-review-status story-review-status--created";
        }

        if (chapter.CanCommit)
        {
            return "story-review-status story-review-status--ready";
        }

        return chapter.IsActive
            ? "story-review-status story-review-status--active"
            : "story-review-status story-review-status--warning";
    }

    private static string Display(string? value) => string.IsNullOrWhiteSpace(value) ? "Not detected" : value;

    private static string AuthorMessage(string? value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return "This chapter needs review before scenes can be created.";
        }

        var message = value.Trim();
        if (message.Contains("JSON", StringComparison.OrdinalIgnoreCase)
            || message.Contains("parsed", StringComparison.OrdinalIgnoreCase)
            || message.Contains("parser", StringComparison.OrdinalIgnoreCase)
            || message.Contains("deserial", StringComparison.OrdinalIgnoreCase))
        {
            return "One or more scene suggestions could not be prepared automatically and need review.";
        }

        if (message.Contains("existing authored scenes", StringComparison.OrdinalIgnoreCase)
            || message.Contains("already contains scenes", StringComparison.OrdinalIgnoreCase))
        {
            return "This chapter already contains scenes. Choose an empty chapter before creating scenes from this analysis.";
        }

        return message;
    }

    private static string FormatConfidence(decimal? confidence)
    {
        if (!confidence.HasValue)
        {
            return "Not available";
        }

        var value = Math.Clamp(confidence.Value, 0m, 1m);
        return value >= 0.75m
            ? "High"
            : value >= 0.45m
                ? "Medium"
                : "Low";
    }

    private static string FormatCost(decimal? cost)
        => cost.HasValue ? $"About ${cost.Value:0.00}" : "Not available";

    private static string FormatDuration(long milliseconds)
    {
        var elapsed = TimeSpan.FromMilliseconds(Math.Max(0, milliseconds));
        if (elapsed.TotalHours >= 1)
        {
            return $"{Math.Ceiling(elapsed.TotalHours):N0} hr";
        }

        return elapsed.TotalMinutes >= 1
            ? $"{Math.Max(1, (int)Math.Round(elapsed.TotalMinutes)):N0} min"
            : $"{Math.Max(0, (int)Math.Round(elapsed.TotalSeconds)):N0} sec";
    }
}
