using Microsoft.AspNetCore.Http;
using PlotLine.Models;

namespace PlotLine.ViewModels;

public sealed class ImportIndexViewModel
{
    public string JsonText { get; set; } = string.Empty;
    public IFormFile? JsonFile { get; set; }
    public bool AllowDuplicateProjectTitle { get; set; }
    public bool ConfirmImport { get; set; }
    public bool AcknowledgeWarnings { get; set; }
    public bool DryRun { get; set; }
    public ImportPreview? Preview { get; set; }
    public string? StatusMessage { get; set; }
    public string? TechnicalDetail { get; set; }
    public bool CanImport => Preview is { Validation.IsValid: true }
        && (!Preview.Validation.Warnings.Any() || AcknowledgeWarnings)
        && (!Preview.HasDuplicateProjectTitle || AllowDuplicateProjectTitle)
        && ConfirmImport;

    public static string SampleJson => """
    {
      "packageVersion": "1.0",
      "source": "JSON Import Phase 1G sample",
      "createdBy": "PlotDirector sample generator",
      "createdDate": "2026-06-02",
      "description": "Phase 1G sample with aliases, metadata, dependencies, and a few validation warnings.",
      "project": {
        "title": "The Glass Meridian",
        "description": "A placeholder two-book fantasy outline.",
        "notes": "Imported sample data for testing."
      },
      "aliases": {
        "characters": {
          "mara vale": "Mara",
          "Ilen Or": "Ilen"
        },
        "locations": {
          "service staircase": "Service stair",
          "Tidal Causeway": "Tidal causeway",
          "old stairs": "Missing Stairwell"
        }
      },
      "characters": [
        { "name": "Mara", "displayName": "Mara Vale", "shortName": "Mara", "role": "Main protagonist", "importance": 10, "description": "Courier drawn into the hidden city.", "notes": "Primary POV for book one." },
        { "name": "Ilen", "displayName": "Ilen Or", "shortName": "Ilen", "role": "Guide", "importance": 8, "description": "Watchman with partial knowledge of the old routes.", "notes": "Carries secrets into book two." },
        { "name": "Sera", "displayName": "Sera Quill", "shortName": "Sera", "role": "Antagonist", "importance": 7, "description": "Rival mapmaker.", "notes": "Opposes the expedition." },
        { "name": "Tovin", "displayName": "Tovin Reed", "shortName": "Tovin", "role": "Supporting", "importance": 5, "description": "Mechanic and signal reader.", "notes": "Useful for technical scenes." }
      ],
      "locations": [
        { "name": "Old Arcade", "displayName": "Old Arcade", "type": "Building", "description": "Covered shopping arcade above the hidden route.", "notes": "Opening location." },
        { "name": "Service stair", "displayName": "Service Stair", "type": "Room", "parentLocationName": "Old Arcade", "description": "Narrow stair behind a locked panel.", "notes": "Connects to the lower city." },
        { "name": "Lantern Court", "displayName": "Lantern Court", "type": "Landmark", "description": "Underground civic court lit by glass lamps.", "notes": "Central discovery location." },
        { "name": "Clockwork Shore", "displayName": "Clockwork Shore", "type": "Outdoor Area", "description": "Mechanical coastline beyond the city.", "notes": "Book two setting." },
        { "name": "Tidal causeway", "displayName": "Tidal Causeway", "type": "Outdoor Area", "parentLocationName": "Clockwork Shore", "description": "Crossing exposed at low tide.", "notes": "Final sample scene location." }
      ],
      "plotLines": [
        {
          "name": "Hidden City Mystery",
          "displayName": "Hidden City Mystery",
          "type": "Mystery",
          "importance": 10,
          "description": "The central question of what lies beneath the city.",
          "notes": "Sample main mystery line.",
          "threads": [
            {
              "name": "The Brass Key",
              "displayName": "The Brass Key",
              "type": "Clue",
              "status": "Developing",
              "importance": 8,
              "description": "The key points toward the lower city.",
              "notes": "Thread imported from sample JSON.",
              "events": [
                { "bookOrder": 1, "chapterOrder": 1, "sceneOrder": 1, "title": "Key discovered", "eventType": "Introduced", "summary": "Mara finds the brass key.", "impact": "Opens the route beneath the arcade.", "importance": 8, "notes": "First marker." },
                { "bookOrder": 1, "chapterOrder": 2, "sceneOrder": 1, "title": "Map gap revealed", "eventType": "Developed", "summary": "The key does not match the visible map.", "impact": "Expands the mystery.", "importance": 7, "notes": "Shows there is more below." }
              ]
            },
            {
              "name": "Missing Captain",
              "displayName": "Missing Captain",
              "type": "Question",
              "status": "Introduced",
              "importance": 6,
              "description": "A name on the signal plate points to a missing captain.",
              "events": [
                { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 1, "title": "Captain named", "eventType": "Question Raised", "summary": "The signal names a missing captain.", "impact": "Sets up the next search.", "importance": 6, "notes": "Book two escalation." }
              ]
            }
          ]
        },
        {
          "name": "Rival Expedition",
          "displayName": "Rival Expedition",
          "type": "Threat",
          "importance": 7,
          "description": "Sera's group races the protagonists.",
          "threads": [
            {
              "name": "Sera's Pressure",
              "displayName": "Sera's Pressure",
              "type": "Threat",
              "status": "Developing",
              "importance": 7,
              "description": "Sera appears as active opposition.",
              "events": [
                { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 2, "title": "Camp sighted", "eventType": "Introduced", "summary": "Sera's camp is visible across the causeway.", "impact": "Turns the crossing into a race.", "importance": 7, "notes": "Visible antagonist pressure." }
              ]
            }
          ]
        }
      ],
      "storyAssets": [
        {
          "name": "Brass key",
          "displayName": "The Brass Key",
          "type": "Object",
          "importance": 9,
          "description": "A warm brass key with a notch pattern that does not match city locks.",
          "notes": "Tracks the mystery through book one.",
          "initialOwnerCharacterName": "Mara",
          "initialLocationName": "Old Arcade",
          "states": [
            { "bookOrder": 1, "chapterOrder": 1, "sceneOrder": 1, "stateName": "Known", "description": "Mara finds the key in the old arcade.", "notes": "First asset state." },
            { "bookOrder": 1, "chapterOrder": 2, "sceneOrder": 1, "stateName": "Changed", "description": "The key reacts to the lantern court map.", "notes": "Shows the key is more than a door tool." }
          ],
          "events": [
            { "bookOrder": 1, "chapterOrder": 1, "sceneOrder": 1, "eventType": "Introduced", "title": "Key found", "summary": "Mara pockets the key after the impossible doorway appears.", "characterName": "Mara", "locationName": "Old Arcade", "notes": "Creates initial custody." },
            { "bookOrder": 1, "chapterOrder": 2, "sceneOrder": 1, "eventType": "Used", "title": "Key warms near the map", "summary": "The brass key warms in Mara's hand near the incomplete map.", "characterName": "Mara", "locationName": "Lantern Court", "notes": "Moves the asset to the hidden city." }
          ]
        },
        {
          "name": "Signal plate",
          "displayName": "The Signal Plate",
          "type": "Clue",
          "importance": 8,
          "description": "A damaged brass plate that carries a warning from the coast.",
          "initialOwnerCharacterName": "Tovin",
          "initialLocationName": "Clockwork Shore",
          "states": [
            { "bookOrder": 2, "chapterOrder": 1, "sceneOrder": 2, "stateName": "Damaged", "description": "The plate is cracked by salt and failed gears." },
            { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 1, "stateName": "Known", "description": "Mara translates the warning." }
          ],
          "events": [
            { "bookOrder": 2, "chapterOrder": 1, "sceneOrder": 2, "eventType": "Discovered", "title": "Plate recovered", "summary": "Tovin pulls the plate free from the broken machine.", "characterName": "Tovin", "locationName": "Clockwork Shore" },
            { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 1, "eventType": "Revealed", "title": "Warning translated", "summary": "The plate names the missing captain and points toward Sera's route.", "characterName": "Mara", "locationName": "Clockwork Shore" }
          ]
        },
        {
          "name": "Tide chart",
          "displayName": "Ilen's Tide Chart",
          "type": "Document",
          "importance": 6,
          "description": "A folded chart showing when the causeway opens.",
          "initialOwnerCharacterName": "Ilen",
          "initialLocationName": "Tidal causeway",
          "states": [
            { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 2, "stateName": "Known", "description": "Ilen confirms the safe crossing window." }
          ],
          "events": [
            { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 2, "eventType": "Used", "title": "Crossing window found", "summary": "Ilen uses the chart to time the causeway crossing.", "characterName": "Ilen", "locationName": "Tidal causeway" }
          ]
        }
      ],
      "sceneDependencies": [
        {
          "fromScene": { "bookOrder": 1, "chapterOrder": 1, "sceneOrder": 1 },
          "toScene": { "bookOrder": 1, "chapterOrder": 1, "sceneOrder": 2 },
          "dependencyType": "Requires",
          "strength": "Hard",
          "description": "Mara needs to find the arcade door before choosing to descend.",
          "notes": "Opening cause and effect."
        },
        {
          "fromScene": { "bookOrder": 1, "chapterOrder": 1, "sceneOrder": 2 },
          "toScene": { "bookOrder": 1, "chapterOrder": 2, "sceneOrder": 1 },
          "dependencyType": "Reveals",
          "strength": "Strong",
          "description": "The descent sets up the first view of Lantern Court."
        },
        {
          "fromScene": { "bookOrder": 1, "chapterOrder": 2, "sceneOrder": 2 },
          "toScene": { "bookOrder": 2, "chapterOrder": 1, "sceneOrder": 1 },
          "dependencyType": "Follows",
          "strength": "Medium",
          "description": "Ilen's bargain motivates the later departure."
        },
        {
          "fromScene": { "bookOrder": 2, "chapterOrder": 1, "sceneOrder": 2 },
          "toScene": { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 1 },
          "dependencyType": "Reveals",
          "strength": "Hard",
          "description": "The damaged signal plate must be recovered before Mara can translate it."
        },
        {
          "fromScene": { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 1 },
          "toScene": { "bookOrder": 2, "chapterOrder": 2, "sceneOrder": 2 },
          "dependencyType": "Blocks",
          "strength": "7",
          "description": "The warning turns the causeway crossing into a race."
        }
      ],
      "books": [
        {
          "title": "Book One",
          "subtitle": "The Map Beneath the City",
          "seriesOrder": 1,
          "dependsOnPreviousBook": false,
          "description": "The opening movement of the story.",
          "notes": "Keep this book focused on discovery.",
          "chapters": [
            {
              "chapterNumber": 1,
              "title": "A Door in the Rain",
              "order": 1,
              "summary": "Mara finds a hidden route under the old district.",
              "notes": "Establish the central mystery.",
              "scenes": [
                {
                  "sceneNumber": 1,
                  "title": "The Locked Arcade",
                  "order": 1,
                  "summary": "A late delivery leads to an impossible doorway.",
                  "povCharacterName": "Mara",
                  "locationName": "Old Arcade",
                  "dateTimeText": "Rainy evening",
                  "purposeText": "Introduce the mystery",
                  "outcomeText": "Mara keeps the brass key",
                  "notes": "Quiet, tense opening.",
                  "sceneCharacters": [
                    { "characterName": "Mara", "roleInScene": "POV", "importance": 10, "notes": "Finds the key." },
                    { "characterName": "Tovin", "roleInScene": "Supporting", "importance": 4, "notes": "Warns Mara not to linger." }
                  ]
                },
                {
                  "sceneNumber": 2,
                  "title": "Footsteps Below",
                  "order": 2,
                  "summary": "Mara hears someone moving beneath the street.",
                  "povCharacterName": "Mara",
                  "locationName": "Service stair",
                  "dateTimeText": "Same evening",
                  "purposeText": "Escalate the discovery",
                  "outcomeText": "She chooses to descend",
                  "notes": "End on a decision.",
                  "sceneCharacters": [
                    { "characterName": "Mara", "roleInScene": "POV", "importance": 10, "notes": "Chooses to descend." },
                    { "characterName": "Ilen", "roleInScene": "Present", "importance": 6, "notes": "Unseen at first." }
                  ]
                }
              ]
            },
            {
              "chapterNumber": 2,
              "title": "The Lantern Court",
              "order": 2,
              "summary": "The route opens into a forgotten civic space.",
              "notes": "Add wonder, but keep danger near.",
              "scenes": [
                {
                  "sceneNumber": 1,
                  "title": "A City Under Glass",
                  "order": 1,
                  "summary": "Mara sees the underground court for the first time.",
                  "povCharacterName": "Mara",
                  "locationName": "Lantern Court",
                  "dateTimeText": "Later that night",
                  "purposeText": "Reveal the hidden setting",
                  "outcomeText": "Mara realizes the map is incomplete",
                  "notes": "Use strong visual contrast.",
                  "sceneCharacters": [
                    { "characterName": "Mara", "roleInScene": "POV", "importance": 10, "notes": "First glimpse of the court." },
                    { "characterName": "Ilen", "roleInScene": "Supporting", "importance": 7, "notes": "Explains only part of the truth." }
                  ]
                },
                {
                  "sceneNumber": 2,
                  "title": "The Watchman's Offer",
                  "order": 2,
                  "summary": "Ilen offers help at a cost.",
                  "povCharacterName": "Ilen",
                  "locationName": "Lantern Court",
                  "dateTimeText": "Later that night",
                  "purposeText": "Introduce an uneasy ally",
                  "outcomeText": "Mara accepts a temporary guide",
                  "notes": "Trust should feel provisional.",
                  "sceneCharacters": [
                    { "characterName": "Ilen", "roleInScene": "POV", "importance": 8, "notes": "Frames the bargain." },
                    { "characterName": "Mara", "roleInScene": "Present", "importance": 8, "notes": "Accepts with reservations." }
                  ]
                }
              ]
            }
          ]
        },
        {
          "title": "Book Two",
          "subtitle": "The Clockwork Shore",
          "seriesOrder": 2,
          "dependsOnPreviousBook": true,
          "description": "The story widens beyond the city.",
          "notes": "Seed consequences from book one.",
          "chapters": [
            {
              "chapterNumber": 1,
              "title": "Tide Tables",
              "order": 1,
              "summary": "The route points toward a mechanical coastline.",
              "notes": "Reorient the cast after the first book.",
              "scenes": [
                {
                  "sceneNumber": 1,
                  "title": "Departure Bell",
                  "order": 1,
                  "summary": "The expedition leaves before dawn.",
                  "povCharacterName": "Ilen",
                  "locationName": "Clockwork Shore",
                  "dateTimeText": "Early morning",
                  "purposeText": "Start the next journey",
                  "outcomeText": "The group reaches the shore",
                  "notes": "Keep momentum high.",
                  "sceneCharacters": [
                    { "characterName": "Ilen", "roleInScene": "POV", "importance": 8, "notes": "Knows the tide table." },
                    { "characterName": "Mara", "roleInScene": "Present", "importance": 8, "notes": "Questions the plan." },
                    { "characterName": "Tovin", "roleInScene": "Supporting", "importance": 5, "notes": "Carries tools." }
                  ]
                },
                {
                  "sceneNumber": 2,
                  "title": "Salt in the Gears",
                  "order": 2,
                  "summary": "The first coastal machine fails in a revealing way.",
                  "povCharacterName": "Ilen",
                  "locationName": "Clockwork Shore",
                  "dateTimeText": "Midday",
                  "purposeText": "Show the new world's rules",
                  "outcomeText": "They find a damaged signal plate",
                  "notes": "Make the mechanism readable.",
                  "sceneCharacters": [
                    { "characterName": "Ilen", "roleInScene": "POV", "importance": 8, "notes": "Recognizes sabotage." },
                    { "characterName": "Tovin", "roleInScene": "Supporting", "importance": 6, "notes": "Repairs enough to continue." }
                  ]
                }
              ]
            },
            {
              "chapterNumber": 2,
              "title": "The Signal Plate",
              "order": 2,
              "summary": "The signal points to a rival expedition.",
              "notes": "Bring in pressure from outside the group.",
              "scenes": [
                {
                  "sceneNumber": 1,
                  "title": "A Message in Brass",
                  "order": 1,
                  "summary": "The plate reveals a warning.",
                  "povCharacterName": "Mara",
                  "locationName": "Clockwork Shore",
                  "dateTimeText": "Afternoon",
                  "purposeText": "Translate the clue",
                  "outcomeText": "The warning names a missing captain",
                  "notes": "Make the clue actionable.",
                  "sceneCharacters": [
                    { "characterName": "Mara", "roleInScene": "POV", "importance": 10, "notes": "Interprets the warning." },
                    { "characterName": "Sera", "roleInScene": "Mentioned", "importance": 6, "notes": "Named by the signal." }
                  ]
                },
                {
                  "sceneNumber": 2,
                  "title": "Smoke on the Causeway",
                  "order": 2,
                  "summary": "Sera's camp appears across the water.",
                  "povCharacterName": "Mara",
                  "locationName": "Tidal causeway",
                  "dateTimeText": "Sunset",
                  "purposeText": "Introduce opposition",
                  "outcomeText": "The group prepares to cross",
                  "notes": "End with forward motion.",
                  "sceneCharacters": [
                    { "characterName": "Mara", "roleInScene": "POV", "importance": 10, "notes": "Chooses to cross." },
                    { "characterName": "Sera", "roleInScene": "Antagonist", "importance": 7, "notes": "Visible across the causeway." },
                    { "characterName": "Ilen", "roleInScene": "Supporting", "importance": 6, "notes": "Warns about the tide." }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
    """;
}
