using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using OF_DL.Models.Config;
using Serilog;

namespace OF_DL.Gui.ViewModels;

public partial class CreatorConfigEditorViewModel : ViewModelBase
{
    private CreatorConfigRowViewModel? _editingRow;

    public ObservableCollection<CreatorConfigRowViewModel> Rows { get; } = [];
    public ObservableCollection<string> AvailableUsers { get; }

    [ObservableProperty] private CreatorConfigModalViewModel _modalViewModel;

    public CreatorConfigEditorViewModel(IEnumerable<string> availableUsers)
    {
        AvailableUsers = new ObservableCollection<string>(availableUsers);
        ModalViewModel = new CreatorConfigModalViewModel(AvailableUsers, OnModalClose, IsUsernameDuplicate);
    }

    public void LoadFromConfig(Dictionary<string, CreatorConfig> configs)
    {
        Rows.Clear();
        foreach (KeyValuePair<string, CreatorConfig> kvp in configs.OrderBy(c => c.Key,
                     StringComparer.OrdinalIgnoreCase))
        {
            Rows.Add(new CreatorConfigRowViewModel(kvp.Key, kvp.Value, OnDeleteRow, OnEditRow));
        }
    }

    public Dictionary<string, CreatorConfig> ToDictionary()
    {
        Dictionary<string, CreatorConfig> result = new(StringComparer.OrdinalIgnoreCase);
        foreach (CreatorConfigRowViewModel row in Rows)
        {
            result[row.Username] = row.Config;
        }

        return result;
    }

    public void UpdateAvailableUsers(IEnumerable<string> users)
    {
        AvailableUsers.Clear();
        foreach (string user in users.OrderBy(u => u, StringComparer.OrdinalIgnoreCase))
        {
            AvailableUsers.Add(user);
        }
    }

    [RelayCommand]
    private void AddCreator()
    {
        Log.Information("AddCreator command executed");
        _editingRow = null;
        ModalViewModel.OpenForAdd();
    }

    private void OnDeleteRow(CreatorConfigRowViewModel row) => Rows.Remove(row);

    private void OnEditRow(CreatorConfigRowViewModel row)
    {
        _editingRow = row;
        ModalViewModel.OpenForEdit(row.Username, row.Config);
    }

    private bool IsUsernameDuplicate()
    {
        string username = ModalViewModel.Username.Trim();
        if (_editingRow != null && string.Equals(_editingRow.Username, username, StringComparison.OrdinalIgnoreCase))
        {
            return false;
        }

        return Rows.Any(r => string.Equals(r.Username, username, StringComparison.OrdinalIgnoreCase));
    }

    private void OnModalClose(bool confirmed)
    {
        if (!confirmed)
        {
            ModalViewModel.IsOpen = false;
            return;
        }

        (string Username, CreatorConfig Config)? result = ModalViewModel.GetResult();
        if (result == null)
        {
            return;
        }

        if (_editingRow != null)
        {
            _editingRow.Username = result.Value.Username;
            _editingRow.Config = result.Value.Config;
        }
        else
        {
            Rows.Add(new CreatorConfigRowViewModel(result.Value.Username, result.Value.Config, OnDeleteRow, OnEditRow));
        }

        ModalViewModel.IsOpen = false;
    }
}
