using System.Collections.Generic;
using System.Linq;
using CommunityToolkit.Diagnostics;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders;

namespace Wino.Core.Domain.MenuItems;

/// <summary>
/// Menu item that holds a list of folders under the merged account menu item.
/// </summary>
public partial class MergedAccountFolderMenuItem : MenuItemBase<List<IMailItemFolder>, IMenuItem>, IMergedAccountFolderMenuItem
{
    public SpecialFolderType FolderType { get; }

    public string FolderName { get; private set; }

    // Any of the folders is enough to determine the synchronization enable/disable state.
    public bool IsSynchronizationEnabled => HandlingFolders.Any(a => a.IsSynchronizationEnabled);
    public bool IsMoveTarget => HandlingFolders.All(a => a.IsMoveTarget);
    public IEnumerable<IMailItemFolder> HandlingFolders => Parameter;

    // All folders in the list should have the same type.
    public SpecialFolderType SpecialFolderType => HandlingFolders.First().SpecialFolderType;

    public bool IsSticky => true;

    public bool IsSystemFolder => true;

    public string AssignedAccountName => MergedInbox?.Name;

    public MergedInbox MergedInbox { get; set; }

    public bool ShowUnreadCount => HandlingFolders?.Any(a => a.ShowUnreadCount) ?? false;

    public new IEnumerable<IMenuItem> SubMenuItems => base.SubMenuItems;

    [ObservableProperty]
    private int unreadItemCount;

    // Merged account's shared folder menu item does not have an entity id.
    // Navigations to specific folders are done by explicit folder id if needed.

    public MergedAccountFolderMenuItem(List<IMailItemFolder> parameter, IMenuItem parentMenuItem, MergedInbox mergedInbox) : base(parameter, null, parentMenuItem)
    {
        Guard.IsNotNull(mergedInbox, nameof(mergedInbox));
        Guard.IsNotNull(parameter, nameof(parameter));
        Guard.HasSizeGreaterThan(parameter, 0, nameof(parameter));

        MergedInbox = mergedInbox;

        SetFolderName();

        // All folders in the list should have the same type.
        FolderType = parameter[0].SpecialFolderType;
    }

    private void SetFolderName()
    {
        // Folders that hold more than 1 folder belong to merged account.
        // These folders will be displayed as their localized names based on the
        // special type they have.

        if (HandlingFolders.Count() > 1)
        {
            FolderName = GetSpecialFolderName(HandlingFolders.First());
        }
        else
        {
            // Folder only holds 1 Id, but it's displayed as merged account folder.
            FolderName = HandlingFolders.First().FolderName;
        }
    }

    private string GetSpecialFolderName(IMailItemFolder folder)
    {
        var specialType = folder.SpecialFolderType;

        // We only handle 5 different types for combining folders.
        // Rest of the types are not supported.

        return specialType switch
        {
            SpecialFolderType.Inbox => Translator.MergedAccountCommonFolderInbox,
            SpecialFolderType.Draft => Translator.MergedAccountCommonFolderDraft,
            SpecialFolderType.Sent => Translator.MergedAccountCommonFolderSent,
            SpecialFolderType.Deleted => Translator.MergedAccountCommonFolderTrash,
            SpecialFolderType.Junk => Translator.MergedAccountCommonFolderJunk,
            SpecialFolderType.Archive => Translator.MergedAccountCommonFolderArchive,
            _ => folder.FolderName,
        };
    }

    public void UpdateFolder(IMailItemFolder folder)
    {
        var existingFolder = Parameter.FirstOrDefault(a => a.Id == folder.Id);

        if (existingFolder == null) return;

        Parameter.Remove(existingFolder);
        Parameter.Add(folder);

        SetFolderName();
        OnPropertyChanged(nameof(ShowUnreadCount));
        OnPropertyChanged(nameof(IsSynchronizationEnabled));
    }
}
