using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using PlotLine.Services;
using PlotLine.ViewModels;

namespace PlotLine.Controllers;

[Authorize]
public sealed class ScenariosController(IScenarioService scenarios) : Controller
{
    public async Task<IActionResult> Index(int projectId)
    {
        var model = await scenarios.ListAsync(projectId);
        return model is null ? NotFound() : View(model);
    }

    public async Task<IActionResult> Create(int projectId, int? bookId)
    {
        var model = await scenarios.GetCreateAsync(projectId, bookId);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(ScenarioCreateViewModel model)
    {
        if (string.IsNullOrWhiteSpace(model.ScenarioName))
        {
            ModelState.AddModelError(nameof(model.ScenarioName), "Scenario name is required.");
            var repopulated = await scenarios.GetCreateAsync(model.ProjectID, model.BookID);
            model.BookOptions = repopulated?.BookOptions ?? [];
            return View(model);
        }

        var scenarioId = await scenarios.CreateAsync(model);
        return RedirectToAction(nameof(Timeline), new { id = scenarioId });
    }

    public async Task<IActionResult> Timeline(int id)
    {
        var model = await scenarios.GetTimelineAsync(id);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> MoveScene(int scenarioId, int sceneId, int? anchorSceneId, int? targetChapterId, string position)
    {
        await scenarios.MoveSceneAsync(scenarioId, sceneId, anchorSceneId, targetChapterId, position);
        return RedirectToAction(nameof(Timeline), new { id = scenarioId });
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Validate(int id)
    {
        var warningCount = await scenarios.ValidateAsync(id);
        TempData["ScenarioMessage"] = $"Scenario validation found {warningCount} warning{(warningCount == 1 ? "" : "s")}.";
        return RedirectToAction(nameof(Timeline), new { id });
    }

    public async Task<IActionResult> Compare(int id)
    {
        var model = await scenarios.CompareAsync(id);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Apply(int id, string confirmation)
    {
        if (!string.Equals(confirmation, "This will replace the current scene order with the scenario order. Continue?", StringComparison.Ordinal))
        {
            TempData["ScenarioMessage"] = "Scenario was not applied. Use the exact confirmation text.";
            return RedirectToAction(nameof(Compare), new { id });
        }

        await scenarios.ApplyAsync(id);
        TempData["ScenarioMessage"] = "Scenario applied to the main story order.";
        return RedirectToAction(nameof(Timeline), new { id });
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Archive(int id, int projectId)
    {
        await scenarios.ArchiveAsync(id);
        TempData["ArchiveMessage"] = "Scenario archived. You can restore it from Archived Items.";
        return RedirectToAction(nameof(Index), new { projectId });
    }
}
