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

namespace PlotLine.Controllers;

[Authorize]
public sealed class ContinuityExplorerController(IStoryStateService storyState) : Controller
{
    public async Task<IActionResult> Index(
        [FromQuery] ContinuityFilter filter,
        [FromQuery] string? mode,
        [FromQuery] int? characterId,
        [FromQuery] int? assetId,
        [FromQuery] int? locationId,
        [FromQuery] int? sceneId)
    {
        ApplyDeepLinkAliases(filter, mode, characterId, assetId, locationId, sceneId);
        if (filter.ProjectID == 0)
        {
            return BadRequest("ProjectID is required.");
        }

        var model = await storyState.GetContinuityExplorerAsync(filter);
        return model is null ? NotFound() : View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult ApplyFilters(ContinuityFilter filter)
    {
        return RedirectToAction(nameof(Index), filter);
    }

    private static void ApplyDeepLinkAliases(ContinuityFilter filter, string? mode, int? characterId, int? assetId, int? locationId, int? sceneId)
    {
        if (!string.IsNullOrWhiteSpace(mode))
        {
            filter.DisplayMode = mode;
        }

        var hasFriendlyEntityFilter = characterId.HasValue || assetId.HasValue || locationId.HasValue;
        if (hasFriendlyEntityFilter)
        {
            filter.EntityTypes = [];
            if (characterId.HasValue)
            {
                filter.EntityTypes.Add("Characters");
            }

            if (assetId.HasValue)
            {
                filter.EntityTypes.Add("Assets");
            }

            if (locationId.HasValue || string.Equals(filter.DisplayMode, "LocationActivity", StringComparison.OrdinalIgnoreCase))
            {
                filter.EntityTypes.Add("Locations");
            }
        }

        if (characterId.HasValue && !filter.CharacterIDs.Contains(characterId.Value))
        {
            filter.CharacterIDs.Add(characterId.Value);
        }

        if (assetId.HasValue && !filter.AssetIDs.Contains(assetId.Value))
        {
            filter.AssetIDs.Add(assetId.Value);
        }

        if (locationId.HasValue && !filter.LocationIDs.Contains(locationId.Value))
        {
            filter.LocationIDs.Add(locationId.Value);
        }

        if (sceneId.HasValue && !filter.StartSceneID.HasValue && !filter.EndSceneID.HasValue && !filter.SelectedSceneID.HasValue)
        {
            filter.SceneRangeMode = "Custom";
            filter.StartSceneID = sceneId.Value;
            filter.EndSceneID = sceneId.Value;
            filter.SelectedSceneID = sceneId.Value;
        }
    }
}
