using System.Collections.ObjectModel;
using OF_DL.Models.Config;

namespace OF_DL.Gui.ViewModels;

public sealed class ConfigCategoryViewModel : ViewModelBase
{
    private const string SpecificDateFilterOptionHelpText =
        "Downloads posts (does not apply to messages) before or after the chosen date.";

    private const string FolderStructureOptionHelpText =
        "Choose which content types get separate folders, including unlocked PPV posts and messages.";

    public ConfigCategoryViewModel(string categoryName, IEnumerable<ConfigFieldViewModel> fields)
    {
        CategoryName = categoryName;
        List<ConfigFieldViewModel> fieldList = fields.ToList();

        DownloadOnlySpecificDatesField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.DownloadOnlySpecificDates), StringComparison.Ordinal));
        DownloadDateSelectionField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.DownloadDateSelection), StringComparison.Ordinal));
        CustomDateField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.CustomDate), StringComparison.Ordinal));
        DownloadVideoResolutionField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.DownloadVideoResolution), StringComparison.Ordinal));

        LimitDownloadRateField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.LimitDownloadRate), StringComparison.Ordinal));
        DownloadLimitInMbPerSecField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.DownloadLimitInMbPerSec), StringComparison.Ordinal));

        FolderPerPaidPostField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.FolderPerPaidPost), StringComparison.Ordinal));
        FolderPerPostField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.FolderPerPost), StringComparison.Ordinal));
        FolderPerPaidMessageField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.FolderPerPaidMessage), StringComparison.Ordinal));
        FolderPerMessageField = fieldList.FirstOrDefault(field =>
            string.Equals(field.PropertyName, nameof(Config.FolderPerMessage), StringComparison.Ordinal));

        IEnumerable<ConfigFieldViewModel> visibleFields = IsExternal
            ? fieldList.Where(field => field.PropertyName is not nameof(Config.FFmpegPath)
                and not nameof(Config.FFprobePath))
            : IsDownloadBehavior
                ? fieldList.Where(field => field.PropertyName is not nameof(Config.DownloadOnlySpecificDates)
                    and not nameof(Config.DownloadDateSelection)
                    and not nameof(Config.CustomDate)
                    and not nameof(Config.DownloadVideoResolution))
                : IsPerformance
                    ? fieldList.Where(field => field.PropertyName is not nameof(Config.LimitDownloadRate)
                        and not nameof(Config.DownloadLimitInMbPerSec))
                    : IsFolderStructure
                        ? fieldList.Where(field => field.PropertyName is not nameof(Config.FolderPerPaidPost)
                            and not nameof(Config.FolderPerPost)
                            and not nameof(Config.FolderPerPaidMessage)
                            and not nameof(Config.FolderPerMessage))
                        : fieldList;

        foreach (ConfigFieldViewModel field in visibleFields)
        {
            Fields.Add(field);
        }
    }

    public string CategoryName { get; }

    public bool IsExternal =>
        string.Equals(CategoryName, "External", StringComparison.Ordinal);

    public bool IsDownloadBehavior =>
        string.Equals(CategoryName, "Download Behavior", StringComparison.Ordinal);

    public bool IsPerformance =>
        string.Equals(CategoryName, "Performance", StringComparison.Ordinal);

    public bool IsFolderStructure =>
        string.Equals(CategoryName, "Folder Structure", StringComparison.Ordinal);

    public bool IsFileNaming =>
        string.Equals(CategoryName, "File Naming", StringComparison.Ordinal);

    public ConfigFieldViewModel? DownloadOnlySpecificDatesField { get; }

    public ConfigFieldViewModel? DownloadDateSelectionField { get; }

    public ConfigFieldViewModel? CustomDateField { get; }

    public ConfigFieldViewModel? DownloadVideoResolutionField { get; }

    public ConfigFieldViewModel? LimitDownloadRateField { get; }

    public ConfigFieldViewModel? DownloadLimitInMbPerSecField { get; }

    public ConfigFieldViewModel? FolderPerPaidPostField { get; }

    public ConfigFieldViewModel? FolderPerPostField { get; }

    public ConfigFieldViewModel? FolderPerPaidMessageField { get; }

    public ConfigFieldViewModel? FolderPerMessageField { get; }

    public bool HasSpecificDateFilterFields =>
        DownloadOnlySpecificDatesField != null &&
        DownloadDateSelectionField != null &&
        CustomDateField != null;

    public bool HasDownloadVideoResolutionField => DownloadVideoResolutionField != null;

    public bool HasRateLimitFields =>
        LimitDownloadRateField != null &&
        DownloadLimitInMbPerSecField != null;

    public bool HasFolderStructureFields =>
        FolderPerPaidPostField != null &&
        FolderPerPostField != null &&
        FolderPerPaidMessageField != null &&
        FolderPerMessageField != null;

    public string SpecificDateFilterHelpText => SpecificDateFilterOptionHelpText;

    public string RateLimitHelpText
    {
        get
        {
            List<string> parts = [];
            if (!string.IsNullOrWhiteSpace(LimitDownloadRateField?.HelpText))
            {
                parts.Add(LimitDownloadRateField.HelpText);
            }

            if (!string.IsNullOrWhiteSpace(DownloadLimitInMbPerSecField?.HelpText))
            {
                parts.Add(DownloadLimitInMbPerSecField.HelpText);
            }

            return string.Join(" ", parts.Distinct(StringComparer.Ordinal));
        }
    }

    public string FolderStructureHelpText => FolderStructureOptionHelpText;

    public bool HasSpecificDateFilterHelpText => !string.IsNullOrWhiteSpace(SpecificDateFilterHelpText);

    public bool HasRateLimitHelpText => !string.IsNullOrWhiteSpace(RateLimitHelpText);

    public bool HasFolderStructureHelpText => !string.IsNullOrWhiteSpace(FolderStructureHelpText);

    public ObservableCollection<ConfigFieldViewModel> Fields { get; } = [];
}
