using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Elfisa.Core;

namespace Elfisa.Avalonia.ViewModels;

public class NavItem
{
    public string Title { get; }
    public string Icon { get; }   // глиф Segoe MDL2 Assets
    public Func<ViewModelBase> Factory { get; }
    public NavItem(string title, string icon, Func<ViewModelBase> factory)
    {
        Title = title; Icon = icon; Factory = factory;
    }
}

/// <summary>Открытая вкладка-документ.</summary>
public sealed class DocumentTab
{
    public string Title { get; }
    public string Key { get; }
    public ViewModelBase Content { get; }
    public DocumentTab(string title, string key, ViewModelBase content)
    {
        Title = title; Key = key; Content = content;
    }
}

public partial class ShellViewModel : ViewModelBase
{
    private readonly Action _logout;
    private readonly ApiClient _api = new();
    private bool _sync;

    public ObservableCollection<NavItem> NavItems { get; }
    public ObservableCollection<DocumentTab> Tabs { get; } = new();

    [ObservableProperty] private NavItem? _selectedNav;
    [ObservableProperty] private DocumentTab? _activeTab;

    public string UserName => Session.Current.Username ?? "";
    public string RoleLabel => Session.Current.Role switch
    {
        "buyer" => "Покупатель",
        "supplier" => "Поставщик",
        "manager" => "Менеджер",
        "admin" => "Администратор",
        _ => Session.Current.Role ?? ""
    };

    [ObservableProperty] private string _pharmacyAddress = "";

    // Segoe MDL2 Assets — те же глифы, что в WinForms-версии
    private const string IcoPrice = "";
    private const string IcoOrders = "";
    private const string IcoInvoices = "";
    private const string IcoReports = "";
    private const string IcoUpload = "";
    private const string IcoSend = "";
    private const string IcoRefusals = "";
    private const string IcoDirectory = "";

    public ShellViewModel(Action logout)
    {
        _logout = logout;
        _api.SetToken(Session.Current.Token);

        NavItems = new ObservableCollection<NavItem>
        {
            new("Прайс-лист", IcoPrice, () => new PriceListViewModel()),
            new("Заказы", IcoOrders, () => new OrdersViewModel()),
            new("Накладные", IcoInvoices, () => new InvoicesViewModel()),
            new("Отчёты", IcoReports, () => new ReportsViewModel()),
            new("Загрузить", IcoUpload, () => new LoadPriceViewModel()),
            new("Отправить", IcoSend, () => new SendOrderViewModel()),
            new("Отказы", IcoRefusals, () => new PlaceholderPageViewModel("Отказы",
                "Отказные позиции по заказам. Нужен серверный эндпоинт (RefuseItemsCount сейчас только в локальной БД WinForms).")),
            new("Справочник", IcoDirectory, () => new DirectoryViewModel()),
        };

        SelectedNav = NavItems.First(n => n.Title == "Отчёты");
        if (Session.Current.IsAuthenticated) _ = LoadPharmacyAsync();
    }

    private async Task LoadPharmacyAsync()
    {
        try
        {
            var locs = await _api.GetBuyerLocationsAsync();
            var def = locs.FirstOrDefault(l => l.IsDefault) ?? locs.FirstOrDefault();
            PharmacyAddress = def?.Address ?? "";
        }
        catch { }
    }

    partial void OnSelectedNavChanged(NavItem? value)
    {
        if (_sync || value is null) return;
        OpenOrActivate(value);
    }

    private void OpenOrActivate(NavItem nav)
    {
        var existing = Tabs.FirstOrDefault(t => t.Key == nav.Title);
        if (existing is not null) { ActiveTab = existing; return; }
        var tab = new DocumentTab(nav.Title, nav.Title, nav.Factory());
        Tabs.Add(tab);
        ActiveTab = tab;
    }

    partial void OnActiveTabChanged(DocumentTab? value)
    {
        if (value is null) return;
        _sync = true;
        SelectedNav = NavItems.FirstOrDefault(n => n.Title == value.Key);
        _sync = false;
    }

    [RelayCommand]
    private void CloseTab(DocumentTab? tab)
    {
        if (tab is null) return;
        int idx = Tabs.IndexOf(tab);
        bool wasActive = ReferenceEquals(ActiveTab, tab);
        Tabs.Remove(tab);
        if (wasActive)
            ActiveTab = Tabs.Count == 0 ? null : Tabs[Math.Min(idx, Tabs.Count - 1)];
    }

    [RelayCommand] private void Logout() => _logout();
}
