@using JSMR.Application.Enums
@using JSMR.Application.VoiceWorks.Queries.Search
@using JSMR.Domain.Enums
@using JSMR.Domain.ValueObjects
@using JSMR.UI.Blazor.Enums
@using JSMR.UI.Blazor.Filters
@using JSMR.UI.Blazor.Services

<div class="search-toolbar">
    <BitMenuButton TItem="BitMenuButtonItem" Text="Presets" Items="presets" Variant="BitVariant.Outline" OnClick="test" />
    <BitToggleButton @bind-IsChecked="showAdvancedFilters" Text="@(showAdvancedFilters ? "Advanced" : "Basic")" Variant="BitVariant.Outline" />
</div>

<div class="search-filter-control-container">
    <div class="search-filter-control-span-2">
        <BitTextField Prefix="Keywords"
                      Immediate="true" DebounceTime="500"
                      Value="@Value.Keywords"
                      ValueChanged="@(value => Update(Value with { Keywords = value }))">
            <PrefixTemplate>
                <InputPrefix Graphic="Graphic.Search" Tooltip="Keywords"></InputPrefix>
            </PrefixTemplate>
        </BitTextField>
    </div>
    <div class="search-filter-control-span-1">
        <BitDropdown Prefix="Languages"
                     MultiSelect
                     Items="languages"
                     Placeholder="Select..."
                     TItem="BitDropdownItem<Language>"
                     TValue="Language"
                     Values="@Value.SupportedLanguages"
                     ValuesChanged="@(values => Update(Value with { SupportedLanguages = [.. values] }))">
            <PrefixTemplate>
                <InputPrefix Graphic="Graphic.Translate" Tooltip="Supported Languages"></InputPrefix>
            </PrefixTemplate>
        </BitDropdown>
    </div>
    <div class="search-filter-control-span-1">
        <BitDropdown Prefix="Locale"
                     Items="locales"
                     Placeholder="Select..."
                     TItem="BitDropdownItem<Locale>"
                     TValue="Locale"
                     Value="@Value.Locale"
                     ValueChanged="@(value => Update(Value with { Locale = value }))">
            <PrefixTemplate>
                <InputPrefix Graphic="Graphic.Globe" Tooltip="Locale"></InputPrefix>
            </PrefixTemplate>
        </BitDropdown>
    </div>
    <!-- Row 2 -->
    <div class="search-filter-control-span-1">
        <BitDropdown Prefix="Sale Status"
                     Items="saleStatuses"
                     Placeholder="Select..."
                     TItem="BitDropdownItem<SaleStatus?>"
                     TValue="SaleStatus ?"
                     Value="@Value.SaleStatus"
                     ValueChanged="@(value => Update(Value with { SaleStatus = value }))">
            <PrefixTemplate>
                <InputPrefix Graphic="Graphic.Cart" Tooltip="Keywords"></InputPrefix>
            </PrefixTemplate>
        </BitDropdown>
    </div>
    <div class="search-filter-control-span-1">
        <BitDropdown Prefix="Circles"
                     Items="circleStatuses"
                     Placeholder="Select..."
                     TItem="BitDropdownItem<CircleStatus?>"
                     TValue="CircleStatus ?"
                     Value="@Value.CircleStatus"
                     ValueChanged="@(value => Update(Value with { CircleStatus = value }))">
            <PrefixTemplate>
                <InputPrefix Graphic="Graphic.Circle" Tooltip="Circles"></InputPrefix>
            </PrefixTemplate>
        </BitDropdown>
    </div>
    <div class="search-filter-control-span-1">
        <BitDropdown Prefix="Tags"
                     Items="tagStatuses"
                     Placeholder="Select..."
                     TItem="BitDropdownItem<TagStatus?>"
                     TValue="TagStatus ?"
                     Value="@Value.TagStatus"
                     ValueChanged="@(value => Update(Value with { TagStatus = value }))">
            <PrefixTemplate>
                <InputPrefix Graphic="Graphic.Tag" Tooltip="Tags"></InputPrefix>
            </PrefixTemplate>
        </BitDropdown>
    </div>
    <div class="search-filter-control-span-1">
        <BitDropdown Prefix="Creators"
                     Items="creatorStatuses"
                     Placeholder="Select..."
                     TItem="BitDropdownItem<CreatorStatus?>"
                     TValue="CreatorStatus ?"
                     Value="@Value.CreatorStatus"
                     ValueChanged="@(value => Update(Value with { CreatorStatus = value }))">
            <PrefixTemplate>
                <InputPrefix Graphic="Graphic.Person" Tooltip="Creators"></InputPrefix>
            </PrefixTemplate>
        </BitDropdown>
    </div>
    @if (showAdvancedFilters)
    {
        <!-- Row 3 -->
        <div class="search-filter-control-span-2">
            <BitDropdown Prefix="Tags"
                         Items="tags"
                         MultiSelect
                         Virtualize
                         ShowSearchBox
                         AutoFocusSearchBox
                         Chips
                         Placeholder="Select..."
                         TItem="BitDropdownItem<int>"
                         TValue="int"
                         Values="@Value.TagIds"
                         ValuesChanged="@(values => Update(Value with { TagIds = [.. values] }))">
                <PrefixTemplate>
                    <InputPrefix Graphic="Graphic.Tag" Tooltip="Tags"></InputPrefix>
                </PrefixTemplate>
            </BitDropdown>
        </div>
        <div class="search-filter-control-span-1">
            <BitCheckbox Label="Include All Tags"
                         Value="@Value.IncludeAllTags"
                         ValueChanged="@(value => Update(Value with { IncludeAllTags = value }))" />
        </div>
        <div class="search-filter-control-span-1"></div>
        <!-- Row 4 -->
        <div class="search-filter-control-span-2">
            <BitDropdown Prefix="Creators"
                         Items="creators"
                         MultiSelect
                         Virtualize
                         ShowSearchBox
                         AutoFocusSearchBox
                         Chips
                         Placeholder="Select..."
                         TItem="BitDropdownItem<int>"
                         TValue="int"
                         Values="@Value.CreatorIds"
                         ValuesChanged="@(values => Update(Value with { CreatorIds = [.. values] }))">
                <PrefixTemplate>
                    <InputPrefix Graphic="Graphic.Person" Tooltip="Creators"></InputPrefix>
                </PrefixTemplate>
            </BitDropdown>
        </div>
        <div class="search-filter-control-span-1">
            <BitCheckbox Label="Include All Creators"
                         Value="@Value.IncludeAllCreators"
                         ValueChanged="@(value => Update(Value with { IncludeAllCreators = value }))" />
        </div>
        <div class="search-filter-control-span-1"></div>
        <!-- Row 5 -->
        <div class="search-filter-control-span-1">
            <BitCheckbox Label="Show Only Favorite Works"
                         Value="@Value.ShowFavorite"
                         ValueChanged="@(value => Update(Value with { ShowFavorite = value }))" />
        </div>
        <div class="search-filter-control-span-1">
            <BitCheckbox Label="Show Only Invalid Works"
                         Value="@Value.ShowInvalid"
                         ValueChanged="@(value => Update(Value with { ShowInvalid = value }))" />
        </div>
        <div class="search-filter-control-span-2"></div>
        <div class="search-filter-control-span-1">
            <BitDropdown MultiSelect
                         Items="ageRatings"
                         Placeholder="Select..."
                         TItem="BitDropdownItem<AgeRating>"
                         TValue="AgeRating"
                         Values="@Value.AgeRatings"
                         ValuesChanged="@(values => Update(Value with { AgeRatings = [.. values] }))">
                         <PrefixTemplate>
                    <InputPrefix Graphic="Graphic.Age" Tooltip="Age Rating"></InputPrefix>
                </PrefixTemplate>
                         </BitDropdown>
        </div>
        <div class="search-filter-control-span-1">
            <BitDatePicker IconLocation="BitIconLocation.Left"
                           ShowClearButton="true"
                           Value="@ToDto(Value.ReleaseDateStart)"
                           ValueChanged="@(value => Update(Value with { ReleaseDateStart = FromDto(value) }))">
                           <IconTemplate>
                               <InputPrefix Graphic="Graphic.Calendar" Tooltip="Release Date Start"></InputPrefix>
                           </IconTemplate>
                           </BitDatePicker>
        </div>
        <div class="search-filter-control-span-1">
            <BitDatePicker IconLocation="BitIconLocation.Left"
                           ShowClearButton="true"
                           Value="@ToDto(Value.ReleaseDateEnd)"
                           ValueChanged="@(value => Update(Value with { ReleaseDateEnd = FromDto(value) }))">
                           <IconTemplate>
                               <InputPrefix Graphic="Graphic.Calendar" Tooltip="Release Date End"></InputPrefix>
                           </IconTemplate>
                           </BitDatePicker>
        </div>
        @* <div class="search-filter-control-span-1">
        <BitSlider Label="Downloads" Min="0" Max="100000" Value="MinDownloads" ValueChanged="OnMinDownloadsChanged" />
    </div> *@
    }
</div>

@code {
    [Inject]
    ILookupDataService Lookups { get; set; } = default!;

    [Parameter]
    public VoiceWorkFilterState Value { get; set; } = new();

    [Parameter]
    public EventCallback<VoiceWorkFilterState> ValueChanged { get; set; }

    private bool showAdvancedFilters { get; set; }

    List<BitDropdownItem<Locale>> locales = [];
    List<BitDropdownItem<SaleStatus?>> saleStatuses = [];
    List<BitDropdownItem<CircleStatus?>> circleStatuses = [];
    List<BitDropdownItem<TagStatus?>> tagStatuses = [];
    List<BitDropdownItem<CreatorStatus?>> creatorStatuses = [];
    List<BitDropdownItem<Language>> languages = [];
    List<BitDropdownItem<AgeRating>> ageRatings = [];
    List<BitDropdownItem<VoiceWorkSort>> sortOptions = [];
    List<BitDropdownItem<int>> tags = [];
    List<BitDropdownItem<int>> creators = [];

    private List<BitMenuButtonItem> presets =
    [
        new() { Text = "Default", Key = "Default" },
        new() { Text = "Released English", Key = "Released-English" },
        new() { Text = "Popular Upcoming", Key = "Favorite-Upcoming" },
        new() { Text = "Popular This Week", Key = "Popular-ThisWeek" },
        new() { Text = "Popular This Month", Key = "Popular-ThisMonth" },
        new() { Text = "Popular This Year", Key = "Popular-ThisYear" },
    ];

    protected override async Task OnInitializedAsync()
    {
        locales = Lookups.GetLocales();
        saleStatuses = Lookups.GetSaleStatuses();
        circleStatuses = Lookups.GetCircleStatuses();
        tagStatuses = Lookups.GetTagStatuses();
        creatorStatuses = Lookups.GetCreatorStatuses();
        languages = Lookups.GetLanguages();
        ageRatings = Lookups.GetAgeRatings();
        sortOptions = Lookups.GetSortOptions();

        (tags, creators) = (await Lookups.GetTagsAsync(), await Lookups.GetCreatorsAsync());
    }

    private Task Update(VoiceWorkFilterState next)
        => ValueChanged.InvokeAsync(next with { PageNumber = 1 });

    // Map DateOnly? -> DateTimeOffset? (UTC midnight to avoid TZ drift)
    private static DateTimeOffset? ToDto(DateOnly? d) =>
        d is null ? null
                  : new DateTimeOffset(d.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified), TimeSpan.Zero);

    // Map DateTimeOffset? -> DateOnly?
    private static DateOnly? FromDto(DateTimeOffset? dto) =>
        dto is null ? null : DateOnly.FromDateTime(dto.Value.Date);

    private async Task test(BitMenuButtonItem? item)
    {
        if (item is null)
            return;

        if (item.Key == "Default")
        {
            Value = new()
            {
                SaleStatus = SaleStatus.Available,
                CircleStatus = CircleStatus.NotBlacklisted,
                TagStatus = TagStatus.NotBlacklisted,
                CreatorStatus = CreatorStatus.NotBlacklisted,
                SupportedLanguages = [Language.Japanese, Language.English],
                Locale = Locale.English
            };

            _ = Update(Value);
        }
        else if (item.Key == "Released-English")
        {
            Value = new()
            {
                SaleStatus = SaleStatus.Available,
                SupportedLanguages = [Language.English],
                Locale = Locale.English,
                Sort = VoiceWorkSort.ReleaseDateNewToOld
            };

            _ = Update(Value);
        }
        else if (item.Key == "Favorite-Upcoming")
        {
            Value = new()
            {
                SaleStatus = SaleStatus.Upcoming,
                CircleStatus = CircleStatus.Favorited,
                SupportedLanguages = [Language.Japanese, Language.English],
                Locale = Locale.English,
                Sort = VoiceWorkSort.MostFavorited
            };

            _ = Update(Value);
        }
        else if (item.Key == "Popular-ThisWeek")
        {
            Value = new()
            {
                SaleStatus = SaleStatus.Available,
                SupportedLanguages = [Language.Japanese, Language.English],
                Locale = Locale.English,
                Sort = VoiceWorkSort.BestSelling,
                ReleaseDateStart = DateOnly.FromDateTime(DateTime.Now.AddDays(-8))
            };

            _ = Update(Value);
        }
        else if (item.Key == "Popular-ThisMonth")
        {
            Value = new()
            {
                SaleStatus = SaleStatus.Available,
                SupportedLanguages = [Language.Japanese, Language.English],
                Locale = Locale.English,
                Sort = VoiceWorkSort.BestSelling,
                ReleaseDateStart = DateOnly.FromDateTime(DateTime.Now.AddDays(-29))
            };

            _ = Update(Value);
        }
        else if (item.Key == "Popular-ThisYear")
        {
            Value = new()
            {
                SaleStatus = SaleStatus.Available,
                SupportedLanguages = [Language.Japanese, Language.English],
                Locale = Locale.English,
                Sort = VoiceWorkSort.BestSelling,
                ReleaseDateStart = DateOnly.FromDateTime(DateTime.Now.AddDays(-366))
            };

            _ = Update(Value);
        }
    }
}