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

namespace PlotLine.Controllers;

[Authorize]
[Route("onboarding")]
public sealed class OnboardingController(IOnboardingService onboarding, IOnboardingStoryIntelligenceService storyIntelligence) : Controller
{
    [HttpGet("")]
    public async Task<IActionResult> Index()
    {
        var model = await onboarding.GetWizardAsync();
        return View(model);
    }

    [HttpPost("start-manual")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> StartManual()
    {
        await onboarding.StartManualSetupAsync();
        return RedirectToAction(nameof(Index));
    }

    [HttpPost("start-import")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> StartImport()
    {
        await onboarding.StartManuscriptImportSetupAsync();
        return RedirectToAction(nameof(Index));
    }

    [HttpGet("scan-review")]
    public async Task<IActionResult> ScanReview(Guid? previewId)
    {
        var model = await onboarding.GetScanReviewAsync(previewId)
            ?? (previewId.HasValue ? await onboarding.GetScanReviewAsync() : null);
        if (model is null)
        {
            TempData["ArchiveError"] = "The scan review could not be opened. Please scan the manuscript again.";
            await onboarding.SetCurrentStepAsync(OnboardingSteps.NextPathPreview);
            return RedirectToAction(nameof(Index));
        }

        return View(model);
    }

    [HttpGet("build-complete")]
    public async Task<IActionResult> BuildComplete(Guid previewId)
    {
        var model = await onboarding.GetBuildResultAsync(previewId);
        return model is null ? NotFound() : View(model);
    }

    [HttpGet("story-intelligence")]
    public async Task<IActionResult> StoryIntelligence()
    {
        var model = await storyIntelligence.GetOverviewAsync();
        return View(model);
    }

    [HttpGet("story-intelligence/book/{bookId:int}/continue")]
    public async Task<IActionResult> ContinueStoryIntelligence(int bookId)
    {
        var target = await storyIntelligence.ResumeBookAsync(bookId);
        if (target is null)
        {
            TempData["ArchiveError"] = "Story Intelligence could not find saved analysis for that book.";
            return RedirectToAction("Details", "Books", new { id = bookId });
        }

        return target.Route switch
        {
            StoryIntelligenceResumeRoutes.Complete => RedirectToAction(nameof(StoryIntelligenceComplete), new { batchId = target.BatchID }),
            StoryIntelligenceResumeRoutes.Knowledge => RedirectToAction(nameof(StoryIntelligenceKnowledge), new { batchId = target.BatchID }),
            StoryIntelligenceResumeRoutes.Relationships => RedirectToAction(nameof(StoryIntelligenceRelationships), new { batchId = target.BatchID }),
            StoryIntelligenceResumeRoutes.Assets => RedirectToAction(nameof(StoryIntelligenceAssets), new { batchId = target.BatchID }),
            StoryIntelligenceResumeRoutes.Locations => RedirectToAction(nameof(StoryIntelligenceLocations), new { batchId = target.BatchID }),
            StoryIntelligenceResumeRoutes.Characters => RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId = target.BatchID }),
            _ => RedirectToAction(nameof(StoryIntelligenceReview), new { batchId = target.BatchID })
        };
    }

    [HttpPost("story-intelligence/start")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> StartStoryIntelligence(
        [FromForm] string? appearancePreference,
        [FromForm] string? primaryAgeGroup,
        [FromForm] string? storyEra,
        [FromForm] string? storyLocation)
    {
        var job = await storyIntelligence.StartAsync(appearancePreference, primaryAgeGroup, storyEra, storyLocation);
        if (job is null)
        {
            TempData["OnboardingStoryIntelligenceError"] = "Review the manuscript scan before starting Story Intelligence.";
            return RedirectToAction(nameof(StoryIntelligence));
        }

        return RedirectToAction(nameof(StoryIntelligenceProgress), new { batchId = job.BatchID });
    }

    [HttpPost("story-intelligence/skip")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> SkipStoryIntelligence()
    {
        await onboarding.MarkCompletedAsync();
        TempData["ArchiveMessage"] = "Story Intelligence skipped for now. You can return to it from your dashboard.";
        return RedirectToAction("Index", "Projects");
    }

    [HttpPost("scan-manuscript")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ScanManuscript()
    {
        await onboarding.SetCurrentStepAsync(OnboardingSteps.NextPathPreview);
        return RedirectToAction(nameof(Index));
    }

    [HttpGet("story-intelligence/progress")]
    public async Task<IActionResult> StoryIntelligenceProgress(Guid batchId)
    {
        var model = await storyIntelligence.GetProgressAsync(batchId);
        return model is null ? NotFound() : View(model);
    }

    [HttpGet("story-intelligence/review")]
    public async Task<IActionResult> StoryIntelligenceReview(Guid batchId)
    {
        var model = await storyIntelligence.GetProgressAsync(batchId);
        if (model is null)
        {
            return NotFound();
        }

        if (model.HasActiveRuns)
        {
            return RedirectToAction(nameof(StoryIntelligenceProgress), new { batchId });
        }

        return model.AllCommitted
            ? RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId })
            : View(model);
    }

    [HttpGet("story-intelligence/characters")]
    public async Task<IActionResult> StoryIntelligenceCharacters(Guid batchId)
    {
        var model = await storyIntelligence.GetProgressAsync(batchId);
        if (model is null)
        {
            return NotFound();
        }

        if (model.HasActiveRuns)
        {
            return RedirectToAction(nameof(StoryIntelligenceProgress), new { batchId });
        }

        return !model.AllCommitted
            ? RedirectToAction(nameof(StoryIntelligenceReview), new { batchId })
            : View(model);
    }

    [HttpGet("story-intelligence/locations")]
    public async Task<IActionResult> StoryIntelligenceLocations(Guid batchId)
    {
        var model = await storyIntelligence.GetProgressAsync(batchId);
        if (model is null)
        {
            return NotFound();
        }

        if (model.HasActiveRuns)
        {
            return RedirectToAction(nameof(StoryIntelligenceProgress), new { batchId });
        }

        if (!model.AllCommitted)
        {
            return RedirectToAction(nameof(StoryIntelligenceReview), new { batchId });
        }

        return !model.PipelineDashboard.CharacterStageComplete
            ? RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId })
            : View(model);
    }

    [HttpGet("story-intelligence/assets")]
    public async Task<IActionResult> StoryIntelligenceAssets(Guid batchId)
    {
        var model = await storyIntelligence.GetProgressAsync(batchId);
        if (model is null)
        {
            return NotFound();
        }

        if (model.HasActiveRuns)
        {
            return RedirectToAction(nameof(StoryIntelligenceProgress), new { batchId });
        }

        if (!model.AllCommitted)
        {
            return RedirectToAction(nameof(StoryIntelligenceReview), new { batchId });
        }

        if (!model.PipelineDashboard.CharacterStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId });
        }

        return !model.PipelineDashboard.LocationStageComplete
            ? RedirectToAction(nameof(StoryIntelligenceLocations), new { batchId })
            : View(model);
    }

    [HttpGet("story-intelligence/relationships")]
    public async Task<IActionResult> StoryIntelligenceRelationships(Guid batchId)
    {
        var model = await storyIntelligence.GetProgressAsync(batchId);
        if (model is null)
        {
            return NotFound();
        }

        if (model.HasActiveRuns)
        {
            return RedirectToAction(nameof(StoryIntelligenceProgress), new { batchId });
        }

        if (!model.AllCommitted)
        {
            return RedirectToAction(nameof(StoryIntelligenceReview), new { batchId });
        }

        if (!model.PipelineDashboard.CharacterStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId });
        }

        if (!model.PipelineDashboard.LocationStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceLocations), new { batchId });
        }

        return !model.PipelineDashboard.AssetStageComplete
            ? RedirectToAction(nameof(StoryIntelligenceAssets), new { batchId })
            : View(model);
    }

    [HttpPost("story-intelligence/cancel")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> CancelStoryIntelligence(Guid batchId)
    {
        var progress = await storyIntelligence.CancelAsync(batchId);
        if (progress is null)
        {
            return NotFound();
        }

        TempData["OnboardingStoryIntelligenceMessage"] = "Analysis cancellation requested.";
        return RedirectToAction(nameof(StoryIntelligenceReview), new { batchId });
    }

    [HttpPost("story-intelligence/commit")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> CommitStoryIntelligence(Guid batchId, int runId)
    {
        var (progress, result) = await storyIntelligence.CommitAsync(batchId, runId);
        if (progress is null)
        {
            return NotFound();
        }

        TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
        if (result.Success && progress.AllCommitted)
        {
            TempData["WriterWorkspaceMessage"] = $"{progress.CommittedChapterCount} chapter(s) and {progress.Chapters.Sum(chapter => chapter.ScenesCreated)} scene(s) created from your manuscript.";
            return RedirectToAction("Index", "Writer", new { projectId = progress.ProjectID });
        }

        return RedirectToAction(nameof(StoryIntelligenceReview), new { batchId });
    }

    [HttpPost("story-intelligence/commit-all")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> CommitAllStoryIntelligence(Guid batchId)
    {
        var (progress, result) = await storyIntelligence.CommitAllAsync(batchId);
        if (progress is null)
        {
            return NotFound();
        }

        TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
        return result.Success && progress.AllCommitted
            ? RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId })
            : RedirectToAction(nameof(StoryIntelligenceReview), new { batchId });
    }

    [HttpPost("story-intelligence/characters")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ImportStoryIntelligenceCharacters(StoryIntelligenceCharacterImportForm form)
    {
        var (progress, result) = await storyIntelligence.ImportCharactersAsync(form.BatchID, form);
        if (progress is null)
        {
            return NotFound();
        }

        TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
        return result.Success
            ? RedirectToAction(nameof(StoryIntelligenceCharacterComplete), new { batchId = form.BatchID })
            : RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId = form.BatchID });
    }

    [HttpGet("story-intelligence/characters/complete")]
    public async Task<IActionResult> StoryIntelligenceCharacterComplete(Guid batchId)
    {
        var model = await storyIntelligence.GetCharacterImportResultAsync(batchId);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost("story-intelligence/locations")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ImportStoryIntelligenceLocations(StoryIntelligenceLocationImportForm form)
    {
        var (progress, result) = await storyIntelligence.ImportLocationsAsync(form.BatchID, form);
        if (progress is null)
        {
            return NotFound();
        }

        TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
        return result.Success
            ? RedirectToAction(nameof(StoryIntelligenceLocationComplete), new { batchId = form.BatchID })
            : RedirectToAction(nameof(StoryIntelligenceLocations), new { batchId = form.BatchID });
    }

    [HttpGet("story-intelligence/locations/complete")]
    public async Task<IActionResult> StoryIntelligenceLocationComplete(Guid batchId)
    {
        var model = await storyIntelligence.GetLocationImportResultAsync(batchId);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost("story-intelligence/assets")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ImportStoryIntelligenceAssets(StoryIntelligenceAssetImportForm form)
    {
        var (progress, result) = await storyIntelligence.ImportAssetsAsync(form.BatchID, form);
        if (progress is null)
        {
            return NotFound();
        }

        TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
        return result.Success
            ? RedirectToAction(nameof(StoryIntelligenceAssetComplete), new { batchId = form.BatchID })
            : RedirectToAction(nameof(StoryIntelligenceAssets), new { batchId = form.BatchID });
    }

    [HttpGet("story-intelligence/assets/complete")]
    public async Task<IActionResult> StoryIntelligenceAssetComplete(Guid batchId)
    {
        var model = await storyIntelligence.GetAssetImportResultAsync(batchId);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost("story-intelligence/relationships")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ImportStoryIntelligenceRelationships(StoryIntelligenceRelationshipImportForm form)
    {
        var (progress, result) = await storyIntelligence.ImportRelationshipsAsync(form.BatchID, form);
        if (progress is null)
        {
            return NotFound();
        }

        TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
        return result.Success
            ? RedirectToAction(nameof(StoryIntelligenceRelationshipComplete), new { batchId = form.BatchID })
            : RedirectToAction(nameof(StoryIntelligenceRelationships), new { batchId = form.BatchID });
    }

    [HttpGet("story-intelligence/relationships/complete")]
    public async Task<IActionResult> StoryIntelligenceRelationshipComplete(Guid batchId)
    {
        var model = await storyIntelligence.GetRelationshipImportResultAsync(batchId);
        return model is null ? NotFound() : View(model);
    }

    [HttpGet("story-intelligence/knowledge")]
    public async Task<IActionResult> StoryIntelligenceKnowledge(Guid batchId)
    {
        var model = await storyIntelligence.GetProgressAsync(batchId);
        if (model is null)
        {
            return NotFound();
        }

        if (model.HasActiveRuns)
        {
            return RedirectToAction(nameof(StoryIntelligenceProgress), new { batchId });
        }

        if (!model.AllCommitted)
        {
            return RedirectToAction(nameof(StoryIntelligenceReview), new { batchId });
        }

        if (!model.PipelineDashboard.CharacterStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId });
        }

        if (!model.PipelineDashboard.LocationStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceLocations), new { batchId });
        }

        if (!model.PipelineDashboard.AssetStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceAssets), new { batchId });
        }

        return !model.PipelineDashboard.RelationshipStageComplete
            ? RedirectToAction(nameof(StoryIntelligenceRelationships), new { batchId })
            : View(model);
    }

    [HttpPost("story-intelligence/knowledge")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ImportStoryIntelligenceKnowledge(StoryIntelligenceKnowledgeImportForm form)
    {
        var (progress, result) = await storyIntelligence.ImportKnowledgeAsync(form.BatchID, form);
        if (progress is null)
        {
            return NotFound();
        }

        TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
        return result.Success
            ? RedirectToAction(nameof(StoryIntelligenceKnowledgeComplete), new { batchId = form.BatchID })
            : RedirectToAction(nameof(StoryIntelligenceKnowledge), new { batchId = form.BatchID });
    }

    [HttpGet("story-intelligence/knowledge/complete")]
    public async Task<IActionResult> StoryIntelligenceKnowledgeComplete(Guid batchId)
    {
        var model = await storyIntelligence.GetKnowledgeImportResultAsync(batchId);
        return model is null ? NotFound() : View(model);
    }

    [HttpGet("story-intelligence/complete")]
    public async Task<IActionResult> StoryIntelligenceComplete(Guid batchId)
    {
        var progress = await storyIntelligence.GetProgressAsync(batchId);
        if (progress is null)
        {
            return NotFound();
        }

        if (!progress.PipelineDashboard.CharacterStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceCharacters), new { batchId });
        }

        if (!progress.PipelineDashboard.LocationStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceLocations), new { batchId });
        }

        if (!progress.PipelineDashboard.AssetStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceAssets), new { batchId });
        }

        if (!progress.PipelineDashboard.RelationshipStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceRelationships), new { batchId });
        }

        if (!progress.PipelineDashboard.KnowledgeStageComplete)
        {
            return RedirectToAction(nameof(StoryIntelligenceKnowledge), new { batchId });
        }

        var model = await storyIntelligence.GetCompletionAsync(batchId);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost("scan-review")]
    [RequestSizeLimit(25 * 1024 * 1024)]
    [RequestFormLimits(ValueCountLimit = 20000, KeyLengthLimit = 4096, ValueLengthLimit = 1024 * 1024)]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> SaveScanReview(ManuscriptScanReviewForm form, string intent = "save")
    {
        var readyToImport = string.Equals(intent, "continue", StringComparison.OrdinalIgnoreCase);
        try
        {
            var model = await onboarding.SaveScanReviewAsync(form, readyToImport);
            if (model is null)
            {
                return NotFound();
            }

            TempData["OnboardingReviewMessage"] = readyToImport
                ? "Review saved. Next: prepare chapters and analyse manuscript."
                : "Review choices saved.";
            return readyToImport
                ? RedirectToAction(nameof(StoryIntelligence))
                : RedirectToAction(nameof(ScanReview), new { previewId = form.PreviewID });
        }
        catch (InvalidOperationException ex)
        {
            ModelState.AddModelError(string.Empty, ex.Message);
            var model = await onboarding.GetScanReviewAsync(form.PreviewID);
            if (model is null)
            {
                return NotFound();
            }

            return View("ScanReview", model);
        }
    }

    [HttpPost("welcome")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Welcome()
    {
        await onboarding.MoveToNextStepAsync();
        return RedirectToAction(nameof(Index));
    }

    [HttpPost("writing-journey")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> WritingJourney(WritingJourneyOnboardingForm form)
    {
        if (!ModelState.IsValid || string.IsNullOrWhiteSpace(form.WritingJourney))
        {
            var model = await onboarding.GetWizardAsync();
            model.CurrentStep = OnboardingSteps.WritingJourney;
            model.StepNumber = 2;
            return View(nameof(Index), model);
        }

        await onboarding.SaveWritingJourneyAsync(form.WritingJourney);
        return RedirectToAction(nameof(Index));
    }

    [HttpPost("writing-software")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> WritingSoftware(WritingSoftwareOnboardingForm form)
    {
        if (!ModelState.IsValid || string.IsNullOrWhiteSpace(form.WritingSoftware))
        {
            var model = await onboarding.GetWizardAsync();
            model.CurrentStep = OnboardingSteps.WritingSoftware;
            model.StepNumber = 3;
            return View(nameof(Index), model);
        }

        await onboarding.SaveWritingSoftwareAsync(form.WritingSoftware);
        return RedirectToAction(nameof(Index));
    }

    [HttpPost("project")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Project(ProjectOnboardingForm form)
    {
        if (string.Equals(form.Mode, OnboardingSelectionModes.Create, StringComparison.Ordinal)
            && string.IsNullOrWhiteSpace(form.ProjectName))
        {
            ModelState.AddModelError(nameof(form.ProjectName), "Enter a project name.");
        }

        if (string.Equals(form.Mode, OnboardingSelectionModes.Select, StringComparison.Ordinal)
            && !form.SelectedProjectID.HasValue)
        {
            ModelState.AddModelError(nameof(form.SelectedProjectID), "Choose one of your active projects.");
        }

        if (!ModelState.IsValid)
        {
            var invalidModel = await onboarding.GetWizardAsync();
            invalidModel.CurrentStep = OnboardingSteps.Project;
            invalidModel.StepNumber = 4;
            invalidModel.ProjectForm = form;
            return View(nameof(Index), invalidModel);
        }

        try
        {
            await onboarding.SaveProjectAsync(form);
        }
        catch (InvalidOperationException ex)
        {
            ModelState.AddModelError(string.Equals(form.Mode, OnboardingSelectionModes.Select, StringComparison.Ordinal)
                ? nameof(form.SelectedProjectID)
                : nameof(form.ProjectName), ex.Message);
            var invalidModel = await onboarding.GetWizardAsync();
            invalidModel.CurrentStep = OnboardingSteps.Project;
            invalidModel.StepNumber = 4;
            invalidModel.ProjectForm = form;
            return View(nameof(Index), invalidModel);
        }

        return RedirectToAction(nameof(Index));
    }

    [HttpPost("book")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Book(BookOnboardingForm form)
    {
        if (string.Equals(form.Mode, OnboardingSelectionModes.Create, StringComparison.Ordinal)
            && string.IsNullOrWhiteSpace(form.BookTitle))
        {
            ModelState.AddModelError(nameof(form.BookTitle), "Enter a book title.");
        }

        if (string.Equals(form.Mode, OnboardingSelectionModes.Select, StringComparison.Ordinal)
            && !form.SelectedBookID.HasValue)
        {
            ModelState.AddModelError(nameof(form.SelectedBookID), "Choose a book from the selected project.");
        }

        if (!ModelState.IsValid)
        {
            var invalidModel = await onboarding.GetWizardAsync();
            invalidModel.CurrentStep = OnboardingSteps.Book;
            invalidModel.StepNumber = 5;
            invalidModel.BookForm = form;
            return View(nameof(Index), invalidModel);
        }

        try
        {
            await onboarding.SaveBookAsync(form);
        }
        catch (SubscriptionLimitException ex)
        {
            ModelState.AddModelError(nameof(form.BookTitle), ex.Message);
            var invalidModel = await onboarding.GetWizardAsync();
            invalidModel.CurrentStep = OnboardingSteps.Book;
            invalidModel.StepNumber = 5;
            invalidModel.BookForm = form;
            return View(nameof(Index), invalidModel);
        }
        catch (InvalidOperationException ex)
        {
            ModelState.AddModelError(string.Equals(form.Mode, OnboardingSelectionModes.Select, StringComparison.Ordinal)
                ? nameof(form.SelectedBookID)
                : nameof(form.BookTitle), ex.Message);
            var invalidModel = await onboarding.GetWizardAsync();
            invalidModel.CurrentStep = OnboardingSteps.Book;
            invalidModel.StepNumber = 5;
            invalidModel.BookForm = form;
            return View(nameof(Index), invalidModel);
        }

        return RedirectToAction(nameof(Index));
    }

    [HttpPost("finish")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Finish()
    {
        await onboarding.MarkCompletedAsync();
        TempData["ArchiveMessage"] = "Setup saved. You can return to setup preferences from your account menu.";
        return RedirectToAction("Index", "Projects");
    }

    [HttpPost("back")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Back(string currentStep)
    {
        var targetStep = currentStep switch
        {
            OnboardingSteps.WritingJourney => OnboardingSteps.Welcome,
            OnboardingSteps.WritingSoftware => OnboardingSteps.WritingJourney,
            OnboardingSteps.Project => OnboardingSteps.WritingSoftware,
            OnboardingSteps.Book => OnboardingSteps.Project,
            OnboardingSteps.NextPathPreview => OnboardingSteps.Book,
            _ => OnboardingSteps.Welcome
        };

        await onboarding.SetCurrentStepAsync(targetStep);

        return RedirectToAction(nameof(Index));
    }
}
