using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Elfisa.UI.Controls;
using Elfisa.UI.Helpers;
using Elfisa.UI.Loading;
using Elfisa.UI.Notifications;
using Elfisa.UI.Theming;
using Электронная_Фармация.Classes;
using Электронная_Фармация.Properties;
using Электронная_Фармация.Forms;
using Электронная_Фармация.HelpForms;
using Электронная_Фармация.UserControls;

namespace Электронная_Фармация
{
    public partial class ElectroPharmacy
    {
        private readonly Dictionary<string, Control> _documentContents = new Dictionary<string, Control>();
        private readonly ThemeService _themeService = new ThemeService();
        private ToastService _toastService;
        private LoadingOverlay _loadingOverlay;
        private ModernAppHeader _appHeader;
        private ModernTitleBar _titleBar;
        private ModernDocumentTabStrip _documentTabStrip;
        private Panel _documentHost;
        private Panel _statusFooter;
        private Label _lblCurrentUser;
        private ModernButton _btnSettings;
        private ContextMenuStrip _directoryMenu;
        private ContextMenuStrip _documentTabMenu;
        private ToolStripMenuItem _documentCloseTabMenuItem;
        private ToolStripMenuItem _documentCloseAllTabsMenuItem;

        partial void InitializeModernShell()
        {
            Font = new Font("Segoe UI", 12f);
            AutoScaleMode = AutoScaleMode.Dpi;
            KeyPreview = true;
            FormBorderStyle = FormBorderStyle.None;
            MaximizeBox = true;
            MinimizeBox = true;
            MinimumSize = new Size(900, 620);

            bindControl.Visible = false;
            tabContent.Visible = false;

            _toastService = new ToastService(this);
            AppServices.Initialize(_toastService);
            _loadingOverlay = new LoadingOverlay { Name = "loadingOverlay", Dock = DockStyle.Fill };

            _titleBar = new ModernTitleBar { Name = "titleBar" };
            _titleBar.Attach(this);
            _titleBar.ApplyTheme(ThemeManager.Colors);

            _appHeader = new ModernAppHeader { Name = "appHeader", Dock = DockStyle.Top };
            _appHeader.SetItems(new[]
            {
                new SidebarItem { Key = "price", Text = "Прайс-лист", IconGlyph = "\uE14C" },
                new SidebarItem { Key = "orders", Text = "Заказы", IconGlyph = "\uE7BF" },
                new SidebarItem { Key = "invoices", Text = "Накладные", IconGlyph = "\uE8A5" },
                new SidebarItem { Key = "reports", Text = "Отчёты", IconGlyph = "" },
                new SidebarItem { Key = "upload", Text = "Загрузить", IconGlyph = "\uE896" },
                new SidebarItem { Key = "send", Text = "Отправить", IconGlyph = "\uE725" },
                new SidebarItem { Key = "refusals", Text = "Отказы", IconGlyph = "\uE7BA" },
                new SidebarItem { Key = "directory", Text = "Справочник", IconGlyph = "\uE8F1" },
                new SidebarItem { Key = "auth", Text = "Вход", IconGlyph = "\uE192" }
            });

            _documentTabStrip = new ModernDocumentTabStrip { Name = "documentTabStrip", Dock = DockStyle.Top };
            _documentHost = new Panel { Name = "documentHost", Dock = DockStyle.Fill, Tag = "chrome-child" };

            _statusFooter = new Panel
            {
                Name = "statusFooter",
                Dock = DockStyle.Bottom,
                Height = 32,
                Tag = "status-footer",
                Padding = new Padding(12, 0, 8, 0)
            };
            _statusFooter.Paint += (_, e) =>
            {
                var theme = ThemeManager.Colors;
                var g = e.Graphics;
                using (var fill = new SolidBrush(theme.CartHeaderBackground))
                {
                    g.FillRectangle(fill, _statusFooter.ClientRectangle);
                }

                using (var pen = new Pen(theme.AccentPrimaryBorder))
                {
                    g.DrawLine(pen, 0, 0, _statusFooter.Width, 0);
                }
            };

            _lblCurrentUser = new Label
            {
                Name = "lblCurrentUser",
                Dock = DockStyle.Fill,
                TextAlign = ContentAlignment.MiddleLeft,
                AutoEllipsis = true,
                Tag = "muted",
                Padding = new Padding(0, 0, 4, 0)
            };
            _btnSettings = new ModernButton
            {
                Name = "btnSettings",
                Dock = DockStyle.Right,
                Margin = new Padding(0, 2, 2, 2),
                Text = "Настройки",
                CompactIconMode = false,
                AllowTextEllipsis = false,
                MinimumSize = new Size(88, 22),
                Size = new Size(88, 22),
                Padding = new Padding(6, 0, 6, 0),
                Font = new Font("Segoe UI Semibold", 8.5f, FontStyle.Bold),
                TabIndex = 0
            };
            _btnSettings.Click += (_, __) => OpenSettingsDialog();
            // Сначала Fill (пользователь), потом Right (кнопка) — кнопка справа, текст не перекрывается.
            _statusFooter.Controls.Add(_lblCurrentUser);
            _statusFooter.Controls.Add(_btnSettings);

            // Клик по строке "аптека" открывает выбор грузополучателя без перезапуска приложения.
            // Т.к. метка у нас одна (Dock=Fill), обработчик навешиваем на весь Label.
            _lblCurrentUser.Cursor = Cursors.Hand;
            _lblCurrentUser.Click += (_, __) => SwitchConsignee();

            Controls.Add(_loadingOverlay);
            Controls.Add(_documentHost);
            Controls.Add(_statusFooter);
            Controls.Add(_documentTabStrip);
            Controls.Add(_appHeader);
            Controls.Add(_titleBar);

            _directoryMenu = new ContextMenuStrip();
            var contractorsItem = new ToolStripMenuItem("Поставщики");
            contractorsItem.Click += (_, __) => tsItemContractors_Click(_, __);
            var consigneesItem = new ToolStripMenuItem("Грузополучатели");
            consigneesItem.Click += (_, __) => tsConsignee_Click(_, __);
            var switchConsigneeItem = new ToolStripMenuItem("Сменить грузополучателя");
            switchConsigneeItem.Click += (_, __) => SwitchConsignee();
            var invoicesItem = new ToolStripMenuItem("Накладные");
            invoicesItem.Click += (_, __) => tsItemInvoices_Click(_, __);
            var debugItem = new ToolStripMenuItem("Отладка");
            debugItem.Click += (_, __) => tsDebug_Click(_, __);
            _directoryMenu.Items.AddRange(new ToolStripItem[]
            {
                contractorsItem,
                consigneesItem,
                switchConsigneeItem,
                invoicesItem,
                new ToolStripSeparator(),
                debugItem
            });

            _appHeader.ItemSelected += OnAppHeaderItemSelected;
            _documentTabStrip.ThemeToggleClicked += OnThemeToggleClicked;
            _documentTabStrip.TabSelected += OnDocumentTabSelected;
            _documentTabStrip.TabClosed += OnDocumentTabClosed;
            _documentTabStrip.TabCloseAllRequested += OnDocumentTabCloseAll;

            _documentCloseTabMenuItem = new ToolStripMenuItem("Закрыть вкладку");
            _documentCloseTabMenuItem.Click += (_, __) =>
            {
                var tabId = _documentTabStrip.ActiveTabId;
                if (!string.IsNullOrEmpty(tabId))
                {
                    CloseDocumentTab(tabId);
                }
            };

            _documentCloseAllTabsMenuItem = new ToolStripMenuItem("Закрыть все вкладки");
            _documentCloseAllTabsMenuItem.Click += (_, __) => ClearDocumentTabs();

            _documentTabMenu = new ContextMenuStrip();
            _documentTabMenu.Items.Add(_documentCloseTabMenuItem);
            _documentTabMenu.Items.Add(_documentCloseAllTabsMenuItem);

            ThemeManager.ThemeChanged += (_, __) =>
            {
                UiThemeHelper.ApplyToControlTree(this);
                UpdateThemeToggleState();
                _titleBar?.ApplyTheme(ThemeManager.Colors);
                WindowChromeHelper.ApplyTitleBarTheme(this, ThemeManager.Colors);
            };

            HandleCreated += (_, __) => WindowChromeHelper.ApplyTitleBarTheme(this, ThemeManager.Colors);
        }

        protected override void WndProc(ref Message m)
        {
            if (FormBorderStyle == FormBorderStyle.None
                && WindowChromeHelper.TryHandleNcHitTest(this, ref m))
            {
                return;
            }

            base.WndProc(ref m);
        }

        private void UpdateThemeToggleState()
        {
            if (_documentTabStrip != null)
            {
                _documentTabStrip.IsDarkTheme = ThemeManager.IsDarkProductivityActive;
            }
        }

        private void OnThemeToggleClicked(object sender, EventArgs e)
        {
            ThemeManager.ToggleProductivityTheme();
            Settings.Default.UseDarkTheme = ThemeManager.IsDarkProductivityActive;
            Settings.Default.Save();
            UpdateThemeToggleState();
        }

        partial void FinalizeModernShell()
        {
            ThemeManager.CurrentVariant = Settings.Default.UseDarkTheme
                ? ThemeVariant.DarkProductivity
                : ThemeVariant.ClinicalPro;
            _themeService.Initialize(this);
            UpdateThemeToggleState();
            UiThemeHelper.ApplyToControlTree(this);
            _titleBar?.ApplyTheme(ThemeManager.Colors);
            WindowChromeHelper.ApplyTitleBarTheme(this, ThemeManager.Colors);
            try
            {
                Icon = CreateAppIcon();
            }
            catch
            {
                // keep default
            }
            RefreshCurrentUserStatus();
        }

        private static Icon CreateAppIcon()
        {
            using (var bmp = new Bitmap(32, 32))
            using (var g = Graphics.FromImage(bmp))
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.Clear(Color.Transparent);
                using (var brush = new SolidBrush(Color.FromArgb(15, 118, 110)))
                {
                    g.FillEllipse(brush, 1, 1, 30, 30);
                }

                using (var pen = new Pen(Color.White, 3f)
                {
                    StartCap = System.Drawing.Drawing2D.LineCap.Round,
                    EndCap = System.Drawing.Drawing2D.LineCap.Round
                })
                {
                    g.DrawLine(pen, 16, 8, 16, 24);
                    g.DrawLine(pen, 8, 16, 24, 16);
                }

                return Icon.FromHandle(bmp.GetHicon());
            }
        }

        private void RefreshCurrentUserStatus()
        {
            if (_lblCurrentUser == null)
            {
                return;
            }

            var login = Settings.Default.stringLogin?.Trim();
            var hasToken = !string.IsNullOrWhiteSpace(Settings.Default.stringToken);
            var pharmacy = ConsigneeName?.Trim();
            if (hasToken &&
                (string.IsNullOrWhiteSpace(pharmacy) || pharmacy == "Прайс-Лист"))
            {
                pharmacy = ConsigneeHelper.GetDefaultConsigneeName();
                if (!string.IsNullOrWhiteSpace(pharmacy) &&
                    (string.IsNullOrWhiteSpace(ConsigneeName) || ConsigneeName == "Прайс-Лист"))
                {
                    ConsigneeName = pharmacy;
                }
            }

            string userPart;
            if (!string.IsNullOrWhiteSpace(login) && hasToken)
            {
                userPart = $"Пользователь: {login}";
            }
            else if (!string.IsNullOrWhiteSpace(login))
            {
                userPart = $"Пользователь: {login} (не авторизован)";
            }
            else
            {
                userPart = "Пользователь не авторизован";
            }

            if (hasToken && !string.IsNullOrWhiteSpace(pharmacy) && pharmacy != "Прайс-Лист")
            {
                _lblCurrentUser.Text = $"{userPart}  |  Аптека: {pharmacy}";
            }
            else
            {
                _lblCurrentUser.Text = $"{userPart}  |  Аптека: не выбрана";
            }
        }

        private void OnAppHeaderItemSelected(object sender, string key)
        {
            switch (key)
            {
                case "price":
                    loadDefaultPriceList();
                    break;
                case "orders":
                    OpenOrdersTab();
                    break;
                case "invoices":
                    OpenInvoicesTab();
                    break;
                case "reports":
                    OpenReportsTab();
                    break;
                case "upload":
                    tsBtnDownloadData_Click(this, EventArgs.Empty);
                    _appHeader.SetActive("upload");
                    break;
                case "send":
                    tsBtnSentData_Click(this, EventArgs.Empty);
                    _appHeader.SetActive("send");
                    break;
                case "refusals":
                    OpenRefusalsTab();
                    break;
                case "directory":
                    _directoryMenu.Show(_appHeader, new Point(_appHeader.Width - 220, _appHeader.Height - 4));
                    break;
                case "auth":
                    tsBtnAuth_Click(this, EventArgs.Empty);
                    break;
            }
        }

        private void OnDocumentTabSelected(object sender, string tabId)
        {
            ShowDocumentTab(tabId);
            var tab = _documentTabStrip.Tabs.FirstOrDefault(item => item.Id == tabId);
            if (tab != null)
            {
                _appHeader.SetActive(tab.NavKey);
            }
        }

        private string OpenDocumentTab(string title, string navKey, Control content, bool allowDuplicate)
        {
            if (!allowDuplicate)
            {
                var existing = _documentTabStrip.FindByNavKey(navKey);
                if (existing != null)
                {
                    _documentTabStrip.SelectTab(existing.Id);
                    ShowDocumentTab(existing.Id);
                    _appHeader.SetActive(navKey);
                    return existing.Id;
                }
            }

            var tabId = _documentTabStrip.AddTab(title, navKey);
            content.Dock = DockStyle.Fill;
            content.Tag = "chrome-child";
            content.Visible = false;
            _documentContents[tabId] = content;
            _documentHost.Controls.Add(content);
            UiThemeHelper.ApplyToControlTree(content);
            WireDocumentContextMenu(content);
            _documentTabStrip.SelectTab(tabId);
            ShowDocumentTab(tabId);
            _appHeader.SetActive(navKey);
            return tabId;
        }

        private void ShowDocumentTab(string tabId)
        {
            foreach (var pair in _documentContents)
            {
                pair.Value.Visible = pair.Key == tabId;
            }
        }

        private void OnDocumentTabClosed(object sender, string tabId)
        {
            CloseDocumentTab(tabId);
        }

        private void OnDocumentTabCloseAll(object sender, EventArgs e)
        {
            ClearDocumentTabs();
        }

        private void WireDocumentContextMenu(Control control)
        {
            control.MouseUp -= OnDocumentContentMouseUp;
            control.MouseUp += OnDocumentContentMouseUp;
            foreach (Control child in control.Controls)
            {
                WireDocumentContextMenu(child);
            }
        }

        private void OnDocumentContentMouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Right || _documentTabStrip.Tabs.Count == 0)
            {
                return;
            }

            if (sender is Control clicked && HasDedicatedContextMenu(clicked))
            {
                return;
            }

            _documentCloseTabMenuItem.Enabled = !string.IsNullOrEmpty(_documentTabStrip.ActiveTabId);
            _documentCloseAllTabsMenuItem.Enabled = _documentTabStrip.Tabs.Count > 0;

            var screenPoint = (sender as Control)?.PointToScreen(e.Location) ?? Cursor.Position;
            _documentTabMenu.Show(screenPoint);
        }

        private static bool HasDedicatedContextMenu(Control control)
        {
            for (var current = control; current != null; current = current.Parent)
            {
                if (current.ContextMenuStrip != null)
                {
                    return true;
                }
            }

            return false;
        }

        private void CloseDocumentTab(string tabId)
        {
            if (_documentContents.TryGetValue(tabId, out var control))
            {
                _documentHost.Controls.Remove(control);
                control.Dispose();
                _documentContents.Remove(tabId);
            }

            _documentTabStrip.RemoveTab(tabId);
        }

        private void ClearDocumentTabs()
        {
            foreach (var control in _documentContents.Values)
            {
                _documentHost.Controls.Remove(control);
                control.Dispose();
            }

            _documentContents.Clear();
            _documentTabStrip.ClearTabs();
        }

        private void OpenOrdersTab()
        {
            var orders = new FOrders
            {
                Dock = DockStyle.Fill,
                TopLevel = false,
                TopMost = true
            };
            OpenDocumentTab("Заказы", "orders", orders, allowDuplicate: true);
            orders.Show();
        }

        public void OpenInvoicesTab(string sourceOrderId = null)
        {
            var existing = _documentTabStrip.FindByNavKey("invoices");
            if (existing != null &&
                _documentContents.TryGetValue(existing.Id, out var existingControl) &&
                existingControl is UCInvoices existingInvoices)
            {
                existingInvoices.SetSourceOrderFilter(sourceOrderId);
                _documentTabStrip.SelectTab(existing.Id);
                ShowDocumentTab(existing.Id);
                _appHeader.SetActive("invoices");
                return;
            }

            var invoices = new UCInvoices(sourceOrderId);
            OpenDocumentTab("Накладные", "invoices", invoices, allowDuplicate: false);
        }

        private void OpenRefusalsTab()
        {
            var refusals = new UCRefusals();
            OpenDocumentTab("Отказы", "refusals", refusals, allowDuplicate: false);
        }

        private void OpenReportsTab()
        {
            var reports = new UCReports();
            OpenDocumentTab("Отчёты", "reports", reports, allowDuplicate: false);
        }

        partial void ShowShellLoading(string message)
        {
            _loadingOverlay?.Show(message);
            _loadingOverlay?.BringToFront();
        }

        partial void HideShellLoading()
        {
            _loadingOverlay?.HideOverlay();
        }

        private bool HasDocumentTabs()
        {
            return _documentContents.Count > 0;
        }

        partial void RefreshOpenPriceLists()
        {
            foreach (var control in _documentContents.Values.OfType<UCPriceList>())
            {
                control.RefreshFromDatabase();
            }

            if (!_documentContents.Values.OfType<UCPriceList>().Any())
            {
                loadDefaultPriceList();
            }
        }
    }
}
