using System.Windows.Forms;

namespace TradeApp.WinForms.V08;

public sealed partial class OrderEditForm : Form
{
    private readonly DatabaseClient _db;
    private readonly OrderView _order;
    private readonly Dictionary<int, string> _pickupPoints;

    public OrderEditForm(DatabaseClient db, OrderView? order)
    {
        _db = db;
        _order = order ?? new OrderView();
        _pickupPoints = db.LoadPickupPoints();
        InitializeComponent();
        Text = order is null ? "Добавление заказа" : "Редактирование заказа";
        LoadLookups();
        Fill();
    }

    private void SaveButton_Click(object? sender, EventArgs e)
    {
        if (articleComboBox.SelectedItem is null || pickupPointComboBox.SelectedItem is not PickupPointItem point || string.IsNullOrWhiteSpace(statusComboBox.Text) || customerComboBox.SelectedItem is null)
        {
            MessageBox.Show("Заполните артикул, клиента, статус и пункт выдачи.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        _order.Status = statusComboBox.Text.Trim();
        _order.Customer = customerComboBox.Text.Trim();
        _order.ReceiveCode = receiveCodeTextBox.Text.Trim();
        _order.OrderDate = orderDatePicker.Checked ? orderDatePicker.Value.Date : null;
        _order.DeliveryDate = deliveryDatePicker.Checked ? deliveryDatePicker.Value.Date : null;
        _db.SaveOrder(_order, point.Id, articleComboBox.Text, (int)quantityNumeric.Value, customerComboBox.Text);
        DialogResult = DialogResult.OK;
    }

    private void LoadLookups()
    {
        articleComboBox.Items.AddRange(_db.LoadProductArticles().Cast<object>().ToArray());
        statusComboBox.Items.AddRange(_db.LoadStatuses().Cast<object>().ToArray());
        customerComboBox.Items.AddRange(_db.LoadUsers().Cast<object>().ToArray());
        foreach (var item in _pickupPoints)
        {
            pickupPointComboBox.Items.Add(new PickupPointItem(item.Key, item.Value));
        }
    }

    private void Fill()
    {
        var firstItem = _order.OrderId == 0 ? null : _db.LoadFirstOrderItem(_order.OrderId);
        if (firstItem is not null)
        {
            articleComboBox.Text = firstItem.Value.Article;
            quantityNumeric.Value = firstItem.Value.Quantity;
        }
        else if (articleComboBox.Items.Count > 0)
        {
            articleComboBox.SelectedIndex = 0;
        }
        statusComboBox.Text = string.IsNullOrWhiteSpace(_order.Status) ? FirstText(statusComboBox) : _order.Status;
        customerComboBox.Text = string.IsNullOrWhiteSpace(_order.Customer) ? FirstText(customerComboBox) : _order.Customer;
        receiveCodeTextBox.Text = string.IsNullOrWhiteSpace(_order.ReceiveCode) ? "000" : _order.ReceiveCode;
        SelectPickupPoint();
        SetDate(orderDatePicker, _order.OrderDate);
        SetDate(deliveryDatePicker, _order.DeliveryDate);
    }

    private void SelectPickupPoint()
    {
        for (var i = 0; i < pickupPointComboBox.Items.Count; i++)
        {
            if (pickupPointComboBox.Items[i] is PickupPointItem item && item.Address == _order.PickupPoint)
            {
                pickupPointComboBox.SelectedIndex = i;
                return;
            }
        }

        if (pickupPointComboBox.Items.Count > 0)
        {
            pickupPointComboBox.SelectedIndex = 0;
        }
    }

    private static string FirstText(ComboBox comboBox)
    {
        return comboBox.Items.Count > 0 ? comboBox.Items[0]?.ToString() ?? "" : "";
    }

    private static void SetDate(DateTimePicker picker, DateTime? value)
    {
        picker.Checked = value.HasValue;
        if (value.HasValue)
        {
            picker.Value = value.Value;
        }
    }

    private sealed record PickupPointItem(int Id, string Address)
    {
        public override string ToString() => Address;
    }
}