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;

/// <summary>
/// Отправить — отправка НЕОТПРАВЛЕННЫХ накладных (черновиков заказов из раздела
/// «Заказы»). Список готовых накладных, кнопка «Отправить» (создаёт реальный заказ
/// у поставщика). Без поиска по прайсу и наименований — только сами накладные.
/// </summary>
public partial class SendOrderViewModel : ViewModelBase
{
    private readonly ApiClient _api = new();

    /// <summary>Неотправленные накладные (черновики).</summary>
    public ObservableCollection<DraftOrder> Drafts { get; } = new();

    [ObservableProperty] private DraftOrder? _selected;
    [ObservableProperty] private bool _busy;
    [ObservableProperty] private string? _status;
    [ObservableProperty] private decimal _totalSum;
    [ObservableProperty] private bool _isEmpty = true;
    [ObservableProperty] private int _count;

    public SendOrderViewModel()
    {
        _api.SetToken(Session.Current.Token);
        Load();
    }

    [RelayCommand]
    private void Refresh() => Load();

    private void Load()
    {
        Drafts.Clear();
        foreach (var d in DraftStore.All.OrderByDescending(x => x.CreatedAt))
            Drafts.Add(d);
        TotalSum = Drafts.Sum(d => d.Total);
        Count = Drafts.Count;
        IsEmpty = Drafts.Count == 0;
        if (Selected is null || !Drafts.Contains(Selected))
            Selected = Drafts.FirstOrDefault();
    }

    /// <summary>Отправить одну накладную.</summary>
    [RelayCommand]
    private async Task SendAsync(DraftOrder? draft)
    {
        var d = draft ?? Selected;
        if (d is null) { Status = "Выберите накладную для отправки."; return; }
        Status = null;
        try
        {
            Busy = true;
            var resp = await CreateFromDraft(d);
            DraftStore.Remove(d.Id);
            Status = $"✓ Накладная {resp.GlobalSign ?? resp.OrderId} отправлена ({resp.ItemsCount} поз., {resp.TotalAmount:N2}).";
        }
        catch (Exception ex) { Status = "Ошибка отправки: " + ex.Message; }
        finally { Busy = false; Load(); }
    }

    /// <summary>Отправить все неотправленные накладные.</summary>
    [RelayCommand]
    private async Task SendAllAsync()
    {
        if (Drafts.Count == 0) { Status = "Нет неотправленных накладных."; return; }
        Status = null;
        int ok = 0;
        string? lastErr = null;
        try
        {
            Busy = true;
            foreach (var d in DraftStore.All.ToList())
            {
                try
                {
                    await CreateFromDraft(d);
                    DraftStore.Remove(d.Id);
                    ok++;
                }
                catch (Exception ex) { lastErr = ex.Message; }
            }
        }
        finally { Busy = false; Load(); }

        Status = lastErr is null
            ? $"✓ Отправлено накладных: {ok}."
            : $"Отправлено: {ok}. Не удалось часть — {lastErr}";
    }

    /// <summary>Удалить неотправленную накладную (не отправляя).</summary>
    [RelayCommand]
    private void Delete(DraftOrder? draft)
    {
        var d = draft ?? Selected;
        if (d is null) return;
        DraftStore.Remove(d.Id);
        Load();
        Status = "Накладная удалена.";
    }

    private async Task<BuyerOrderResponse> CreateFromDraft(DraftOrder d)
    {
        var req = new BuyerOrderCreateRequest
        {
            // Номер EX резервировался при сохранении черновика — используем его.
            GlobalSign = d.Number.StartsWith("EX-", StringComparison.OrdinalIgnoreCase) ? d.Number : null,
            LocationId = d.LocationId,
            Comment = d.Comment,
            Items = d.Items.Select(i => new BuyerOrderItemReq
            {
                SupplierPriceId = i.SupplierPriceId,
                Qty = (double)i.Qty,
                ItemName = i.Name,
                Barcode = i.Barcode
            }).ToList()
        };
        return await _api.CreateOrderAsync(req);
    }
}
