using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Электронная_Фармация.Classes;
using Электронная_Фармация.Properties;

namespace Электронная_Фармация.UserControls
{
    /// <summary>
    /// Раздел «Отчёты» покупателя. Данные тянутся с сервера (/api/buyer/report),
    /// который скоупит их по JWT покупателя — клиент видит ТОЛЬКО свои заказы.
    /// Все 4 отчёта агрегируются на клиенте из одного набора строк.
    /// </summary>
    public class UCReports : UserControl
    {
        private readonly DateTimePicker _dtFrom;
        private readonly DateTimePicker _dtTo;
        private readonly ComboBox _cboReport;
        private readonly Button _btnBuild;
        private readonly Label _lblTotals;
        private readonly DataGridView _grid;
        private readonly TextBox _txtPrompt;
        private readonly ComboBox _cboFormat;
        private readonly Button _btnAi;
        private List<BuyerReportLineDto> _lines = new List<BuyerReportLineDto>();

        // Палитра под общий стиль приложения (бирюза шапки #0F766E).
        private static readonly Color Accent      = Color.FromArgb(15, 118, 110);
        private static readonly Color AccentHover = Color.FromArgb(13, 148, 136);
        private static readonly Color TextMain    = Color.FromArgb(31, 41, 55);
        private static readonly Color TextMuted   = Color.FromArgb(120, 128, 134);
        private static readonly Color RowAlt      = Color.FromArgb(247, 250, 250);
        private static readonly Color SelBack     = Color.FromArgb(178, 240, 230);
        private static readonly Color GridLine    = Color.FromArgb(230, 234, 236);

        private static void StylePrimaryButton(Button b)
        {
            b.FlatStyle = FlatStyle.Flat;
            b.FlatAppearance.BorderSize = 0;
            b.FlatAppearance.MouseOverBackColor = AccentHover;
            b.FlatAppearance.MouseDownBackColor = AccentHover;
            b.BackColor = Accent;
            b.ForeColor = Color.White;
            b.Cursor = Cursors.Hand;
            b.Font = new Font("Segoe UI", 9F, FontStyle.Regular);
        }

        public UCReports()
        {
            Dock = DockStyle.Fill;

            var uiFont = new Font("Segoe UI", 9F);
            var top = new Panel { Dock = DockStyle.Top, Height = 100, BackColor = Color.White };

            // --- строка 1: период + готовый отчёт по данным ---
            var lblFrom = new Label { Text = "С", AutoSize = true, Left = 12, Top = 17, ForeColor = TextMain, Font = uiFont };
            _dtFrom = new DateTimePicker { Format = DateTimePickerFormat.Short, Width = 112, Left = 32, Top = 13, Value = DateTime.Today.AddMonths(-1), Font = uiFont };
            var lblTo = new Label { Text = "по", AutoSize = true, Left = 150, Top = 17, ForeColor = TextMain, Font = uiFont };
            _dtTo = new DateTimePicker { Format = DateTimePickerFormat.Short, Width = 112, Left = 176, Top = 13, Value = DateTime.Today, Font = uiFont };
            _cboReport = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Width = 190, Left = 298, Top = 13, Font = uiFont, FlatStyle = FlatStyle.Flat };
            _cboReport.Items.AddRange(new object[] { "Мои заказы", "По поставщикам", "По товарам", "По аптекам" });
            _cboReport.SelectedIndex = 0;
            _btnBuild = new Button { Text = "Сформировать", Left = 498, Top = 12, Width = 140, Height = 28 };
            _lblTotals = new Label { AutoSize = true, Left = 654, Top = 17, Text = "", ForeColor = Accent, Font = new Font("Segoe UI", 9F, FontStyle.Bold) };

            top.Controls.AddRange(new Control[] { lblFrom, _dtFrom, lblTo, _dtTo, _cboReport, _btnBuild, _lblTotals });

            // --- строка 2: свободный запрос к ИИ (клиент пишет словами -> Word/Excel) ---
            var lblAi = new Label { Text = "Запрос ИИ:", AutoSize = true, Left = 12, Top = 61, ForeColor = TextMain, Font = uiFont };
            _txtPrompt = new TextBox { Left = 92, Top = 57, Width = 470, Font = uiFont, BorderStyle = BorderStyle.FixedSingle };
            _cboFormat = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Left = 574, Top = 57, Width = 92, Font = uiFont, FlatStyle = FlatStyle.Flat };
            _cboFormat.Items.AddRange(new object[] { "Word", "Excel" });
            _cboFormat.SelectedIndex = 0;
            _btnAi = new Button { Text = "🤖 Сформировать ИИ", Left = 676, Top = 56, Width = 170, Height = 28 };
            _btnAi.Text = "Сформировать ИИ";   // без эмодзи (криво рендерился в кнопке)
            var lblHint = new Label { AutoSize = true, Left = 92, Top = 83, ForeColor = TextMuted, Font = new Font("Segoe UI", 8F),
                Text = "Напр.: «закупки по поставщикам за июль», «топ товаров за 3 месяца», «заказы у Farmsnab»" };

            StylePrimaryButton(_btnBuild);
            StylePrimaryButton(_btnAi);

            var tip = new ToolTip();
            tip.SetToolTip(_txtPrompt, "Опишите нужный отчёт словами — ИИ подберёт тип, период и соберёт документ.");

            top.Controls.AddRange(new Control[] { lblAi, _txtPrompt, _cboFormat, _btnAi, lblHint });

            _grid = new DataGridView
            {
                Dock = DockStyle.Fill,
                ReadOnly = true,
                AllowUserToAddRows = false,
                AllowUserToDeleteRows = false,
                AllowUserToResizeRows = false,
                RowHeadersVisible = false,
                SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,
                BorderStyle = BorderStyle.None,
                BackgroundColor = Color.White,
                EnableHeadersVisualStyles = false,
                ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.None,
                ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing,
                ColumnHeadersHeight = 34,
                CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal,
                GridColor = GridLine,
                RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.None
            };
            _grid.ColumnHeadersDefaultCellStyle.BackColor = Accent;
            _grid.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
            _grid.ColumnHeadersDefaultCellStyle.Font = new Font("Segoe UI", 9.5F, FontStyle.Bold);
            _grid.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
            _grid.ColumnHeadersDefaultCellStyle.Padding = new Padding(6, 0, 0, 0);
            _grid.DefaultCellStyle.Font = new Font("Segoe UI", 9.5F);
            _grid.DefaultCellStyle.ForeColor = TextMain;
            _grid.DefaultCellStyle.SelectionBackColor = SelBack;
            _grid.DefaultCellStyle.SelectionForeColor = TextMain;
            _grid.DefaultCellStyle.Padding = new Padding(6, 0, 6, 0);
            _grid.AlternatingRowsDefaultCellStyle.BackColor = RowAlt;
            _grid.RowTemplate.Height = 30;

            Controls.Add(_grid);
            Controls.Add(top);

            _btnBuild.Click += async (_, __) => await LoadAsync();
            _cboReport.SelectedIndexChanged += (_, __) => Render();
            _btnAi.Click += async (_, __) => await BuildAiAsync();
            _txtPrompt.KeyDown += async (_, e) =>
            {
                if (e.KeyCode == Keys.Enter) { e.SuppressKeyPress = true; await BuildAiAsync(); }
            };
        }

        private async Task BuildAiAsync()
        {
            var prompt = _txtPrompt.Text?.Trim();
            if (string.IsNullOrWhiteSpace(prompt))
            {
                ToastNotification.ShowError("Введите запрос для ИИ.");
                return;
            }

            var token = Settings.Default.stringToken;
            if (string.IsNullOrWhiteSpace(token))
            {
                ToastNotification.ShowError("Не найден токен авторизации. Войдите в систему.");
                return;
            }

            try
            {
                _btnAi.Enabled = false;
                _btnAi.Text = "Формирую…";

                var fmt = _cboFormat.SelectedIndex == 1 ? "xlsx" : "docx";
                var client = new ApiClient();
                client.SetToken(token);
                var result = await client.GenerateAiReportAsync(prompt, fmt);

                var dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                var safe = string.Join("_", (result.FileName ?? "Отчёт").Split(Path.GetInvalidFileNameChars()));
                var path = Path.Combine(dir, safe);
                if (File.Exists(path))
                {
                    var name = Path.GetFileNameWithoutExtension(safe);
                    var ext = Path.GetExtension(safe);
                    path = Path.Combine(dir, $"{name}_{DateTime.Now:yyyyMMdd_HHmmss}{ext}");
                }

                File.WriteAllBytes(path, result.Content);
                ToastNotification.ShowCustom("Отчёт готов, открываю…", Color.SeaGreen, Color.White);
                Process.Start(new ProcessStartInfo { FileName = path, UseShellExecute = true });
            }
            catch (Exception ex)
            {
                AppDebugLog.Error("UCReports", "Ошибка ИИ-отчёта", ex);
                ToastNotification.ShowError("Ошибка ИИ-отчёта: " + ex.Message);
            }
            finally
            {
                _btnAi.Enabled = true;
                _btnAi.Text = "🤖 Сформировать ИИ";
            }
        }

        private async Task LoadAsync()
        {
            try
            {
                _btnBuild.Enabled = false;
                var token = Settings.Default.stringToken;
                if (string.IsNullOrWhiteSpace(token))
                {
                    ToastNotification.ShowError("Не найден токен авторизации. Войдите в систему.");
                    return;
                }

                var client = new ApiClient();
                client.SetToken(token);
                _lines = await client.GetBuyerReportAsync(_dtFrom.Value.Date, _dtTo.Value.Date)
                         ?? new List<BuyerReportLineDto>();
                Render();

                if (_lines.Count == 0)
                {
                    ToastNotification.ShowCustom("За выбранный период заказов нет.", Color.DarkOrange, Color.White);
                }
            }
            catch (Exception ex)
            {
                AppDebugLog.Error("UCReports", "Ошибка формирования отчёта", ex);
                ToastNotification.ShowError("Ошибка отчёта: " + ex.Message);
            }
            finally
            {
                _btnBuild.Enabled = true;
            }
        }

        private void Render()
        {
            var dt = new DataTable();

            switch (_cboReport.SelectedIndex)
            {
                case 0: // Мои заказы (по заказу)
                    dt.Columns.Add("Дата", typeof(string));
                    dt.Columns.Add("Номер", typeof(string));
                    dt.Columns.Add("Поставщик", typeof(string));
                    dt.Columns.Add("Аптека", typeof(string));
                    dt.Columns.Add("Позиций", typeof(int));
                    dt.Columns.Add("Сумма", typeof(decimal));
                    dt.Columns.Add("Статус", typeof(string));
                    foreach (var g in _lines.GroupBy(l => l.OrderID)
                                            .OrderByDescending(x => x.First().OrderDate ?? DateTime.MinValue))
                    {
                        var f = g.First();
                        var suppliers = string.Join(", ", g.Select(x => x.Supplier)
                            .Where(s => !string.IsNullOrWhiteSpace(s)).Distinct());
                        dt.Rows.Add(
                            f.OrderDate?.ToLocalTime().ToString("dd.MM.yyyy") ?? "",
                            f.GlobalSign,
                            suppliers,
                            f.Location,
                            g.Count(),
                            g.Sum(x => x.Sum),
                            f.Status);
                    }
                    break;

                case 1: // По поставщикам
                    dt.Columns.Add("Поставщик", typeof(string));
                    dt.Columns.Add("Заказов", typeof(int));
                    dt.Columns.Add("Позиций", typeof(int));
                    dt.Columns.Add("Сумма", typeof(decimal));
                    foreach (var g in _lines.GroupBy(l => string.IsNullOrWhiteSpace(l.Supplier) ? "(не указан)" : l.Supplier)
                                            .OrderByDescending(x => x.Sum(y => y.Sum)))
                    {
                        dt.Rows.Add(g.Key, g.Select(x => x.OrderID).Distinct().Count(), g.Count(), g.Sum(x => x.Sum));
                    }
                    break;

                case 2: // По товарам
                    dt.Columns.Add("Товар", typeof(string));
                    dt.Columns.Add("Код", typeof(string));
                    dt.Columns.Add("Кол-во", typeof(decimal));
                    dt.Columns.Add("Сумма", typeof(decimal));
                    foreach (var g in _lines.GroupBy(l => ((l.ItemName ?? "").Trim() + "|" + (l.ItemCode ?? "")))
                                            .OrderByDescending(x => x.Sum(y => y.Sum)))
                    {
                        var f = g.First();
                        dt.Rows.Add(f.ItemName, f.ItemCode, g.Sum(x => x.Qty), g.Sum(x => x.Sum));
                    }
                    break;

                case 3: // По аптекам (грузополучателям)
                    dt.Columns.Add("Аптека", typeof(string));
                    dt.Columns.Add("Заказов", typeof(int));
                    dt.Columns.Add("Позиций", typeof(int));
                    dt.Columns.Add("Сумма", typeof(decimal));
                    foreach (var g in _lines.GroupBy(l => string.IsNullOrWhiteSpace(l.Location) ? "(не указана)" : l.Location)
                                            .OrderByDescending(x => x.Sum(y => y.Sum)))
                    {
                        dt.Rows.Add(g.Key, g.Select(x => x.OrderID).Distinct().Count(), g.Count(), g.Sum(x => x.Sum));
                    }
                    break;
            }

            _grid.DataSource = dt;
            foreach (DataGridViewColumn c in _grid.Columns)
            {
                bool numeric = c.Name == "Сумма" || c.Name == "Кол-во" || c.Name == "Позиций" || c.Name == "Заказов";
                if (c.Name == "Сумма") c.DefaultCellStyle.Format = "N2";
                if (c.Name == "Кол-во") c.DefaultCellStyle.Format = "N3";
                if (numeric)
                {
                    c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                    c.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                    c.HeaderCell.Style.Padding = new Padding(0, 0, 6, 0);
                }
                // Узкие числовые колонки, широкие — текстовые (Fill распределит по весу).
                if (c.Name == "Позиций" || c.Name == "Заказов") c.FillWeight = 45;
                else if (c.Name == "Сумма" || c.Name == "Кол-во") c.FillWeight = 70;
                else if (c.Name == "Дата" || c.Name == "Статус" || c.Name == "Код") c.FillWeight = 75;
                else if (c.Name == "Номер") c.FillWeight = 90;
                else c.FillWeight = 150; // Поставщик / Товар / Аптека
            }

            int orders = _lines.Select(l => l.OrderID).Distinct().Count();
            decimal totalSum = _lines.Sum(l => l.Sum);
            _lblTotals.Text = $"Заказов: {orders}    Позиций: {_lines.Count}    Сумма: {totalSum:N2}";
        }
    }
}
