using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SQLite;
using System.Data.OleDb;
using System.Data.Common;
using Elfisa.UI.Controls;
using Электронная_Фармация.Classes;
using Электронная_Фармация.HelpForms;

namespace Электронная_Фармация.UserControls
{
    public partial class UCPriceList : UserControl
    {
        public UCPriceList(string workWithConsignee)
        {
            InitializeComponent();
            _WorkWithConsignee = workWithConsignee;
        }

        public string ConsigneeName => txtConsignee?.Text ?? string.Empty;

        SQLiteDataAdapter daPriceList;
        DataSet dsPriceList;
        BindingSource bsPriceList = new BindingSource();
        DataAdapter daPriceListMain;
        DataTable tablePriceList;
        string _WorkWithConsignee;
        decimal _percentageAsDefault;
        bool _suppressMarkupPersist;
        string _selectedSupplierFilter = string.Empty;
        bool _suppressSupplierFilterEvents;
        bool _suppressPriceListSelectionEvents;
        bool _suppressBrowseEvents;
        int _committedSupplierFilterIndex;
        DataTable _fullPriceTable;
        PriceBrowseMode _browseMode = PriceBrowseMode.Browse;
        string _selectedBaseName = string.Empty;
        string _selectedMg = string.Empty;
        int _browseSplitterDistance = 0;
        ModernSplitContainer splitNameMgBrowse;
        ModernDataGridView dgvBrowseNames;
        ModernDataGridView dgvBrowseMg;
        List<string> _uniqueBaseNames = new List<string>();
        Dictionary<string, List<string>> _mgByBaseName =
            new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
        Timer _searchDebounceTimer;
        const int SearchDebounceMs = 180;
        static readonly Regex DosageRegex = new Regex(
            @"(\d+(?:[.,]\d+)?\s*(?:мг|мкг|г|мл|МЕ|ме)\b)",
            RegexOptions.IgnoreCase | RegexOptions.Compiled);
        const string EmptyMgDisplay = "(без МГ)";

        private enum PriceBrowseMode
        {
            Browse,
            Offers
        }

        string connectionStringToLocalDB = AppConfig.SqliteConnectionString;

        public void RefreshFromDatabase()
        {
            loadPriceListV2();
            InitializeSupplierFilter();
            loadTempOrderItems();
            ApplyPriceListFilters();
        }

        private void UCPriceList_Load(object sender, EventArgs e)
        {
            EnsureBrowseSplit();
            EnsureChromeLayout();
            UiThemeHelper.ApplyToControlTree(this);
            Tag = "chrome-child";

            AlignSearchRow();
            LayoutContentBelowSearch();

            SizeChanged += (_, __) => LayoutContentBelowSearch();

            txtConsignee.Enabled = false;
            txtConsignee.Text = _WorkWithConsignee;
            //loadConsignees();
            //loadPriceList(string.Empty);
            loadPriceListV2();
            InitializeSupplierFilter();
            loadTempOrderItems();
            loadInfoAboutDefaultMarkup();
            txtSearchGoodNameInPriceList.Focus();
        }

        /// <summary>
        /// Поиск остаётся сверху как в оригинале; контент явно ниже — без Dock-наложения.
        /// </summary>
        private void EnsureChromeLayout()
        {
            // Убираем старую dock-панель, если осталась от прошлых сборок в той же сессии.
            var oldToolbar = Controls["priceToolbar"];
            if (oldToolbar != null)
            {
                var toRestore = oldToolbar.Controls.Cast<Control>().ToArray();
                foreach (var control in toRestore)
                {
                    oldToolbar.Controls.Remove(control);
                    Controls.Add(control);
                    control.BringToFront();
                }

                Controls.Remove(oldToolbar);
                oldToolbar.Dispose();
            }

            // Строка наценки скрыта — проценты берутся из настроек/дефолта без UI-прослойки.
            if (TLPPriceList.RowStyles.Count >= 2)
            {
                TLPPriceList.RowStyles[1].SizeType = SizeType.Absolute;
                TLPPriceList.RowStyles[1].Height = 0;
            }

            panel1.Visible = false;
            panel1.Height = 0;

            SplitPriceList.Panel1MinSize = 120;
            SplitPriceList.Panel2MinSize = 80;
            SplitPriceList.IsSplitterFixed = false;
            SplitPriceList.FixedPanel = FixedPanel.None;
            SplitPriceList.SplitterWidth = 6;

            // Восстановить положение сплиттера корзины, если пользователь уже двигал.
            RestoreCartSplitterDistance();
            SplitPriceList.SplitterMoved += (_, __) => PersistCartSplitterDistance();

            dgvPriceList.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
            dgvPriceList.ColumnHeadersVisible = true;
            dgvPriceList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            if (dgvPriceList.ColumnHeadersHeight < 34)
            {
                dgvPriceList.ColumnHeadersHeight = 36;
            }

            if (!POrderInfo.Controls.ContainsKey("cartHeader"))
            {
                var cartHeader = new ModernSectionHeader
                {
                    Name = "cartHeader",
                    Height = 32,
                    HeaderText = "Корзина"
                };
                cartHeader.ApplyTheme(Elfisa.UI.Theming.ThemeManager.Colors, cartStyle: true);
                cartHeader.Dock = DockStyle.Top;
                POrderInfo.Controls.Add(cartHeader);
                tabOrderItems.SendToBack();
                cartHeader.BringToFront();
            }
        }

        private void LayoutContentBelowSearch()
        {
            const int searchBand = 52;
            PContentPriceList.Dock = DockStyle.None;
            PContentPriceList.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
            PContentPriceList.SetBounds(
                0,
                searchBand,
                Math.Max(100, ClientSize.Width),
                Math.Max(120, ClientSize.Height - searchBand));
        }

        private void RestoreCartSplitterDistance()
        {
            try
            {
                var saved = Properties.Settings.Default.PriceListSplitterDistance;
                if (saved <= 0 || SplitPriceList.Height < 200)
                {
                    return;
                }

                var max = Math.Max(
                    SplitPriceList.Panel1MinSize,
                    SplitPriceList.Height - SplitPriceList.Panel2MinSize - SplitPriceList.SplitterWidth);
                SplitPriceList.SplitterDistance = Math.Max(SplitPriceList.Panel1MinSize, Math.Min(saved, max));
            }
            catch
            {
                // ignore until layout ready
            }
        }

        private void PersistCartSplitterDistance()
        {
            try
            {
                if (SplitPriceList.SplitterDistance > 80)
                {
                    Properties.Settings.Default.PriceListSplitterDistance = SplitPriceList.SplitterDistance;
                    Properties.Settings.Default.Save();
                }
            }
            catch
            {
                // ignore
            }
        }

        private void EnsureBrowseSplit()
        {
            if (splitNameMgBrowse != null)
            {
                return;
            }

            dgvBrowseNames = CreateBrowseGrid("dgvBrowseNames");
            dgvBrowseMg = CreateBrowseGrid("dgvBrowseMg");

            splitNameMgBrowse = new ModernSplitContainer
            {
                Name = "splitNameMgBrowse",
                Dock = DockStyle.Fill,
                Orientation = Orientation.Vertical,
                SplitterWidth = 6,
                Visible = false,
                Panel1MinSize = 100,
                Panel2MinSize = 80,
                IsSplitterFixed = false,
                FixedPanel = FixedPanel.None
            };
            splitNameMgBrowse.Panel1.Controls.Add(dgvBrowseNames);
            splitNameMgBrowse.Panel2.Controls.Add(dgvBrowseMg);

            var gridHost = TLPPriceList.Controls["priceGridHost"] as Panel;
            if (gridHost == null)
            {
                gridHost = new Panel
                {
                    Name = "priceGridHost",
                    Dock = DockStyle.Fill,
                    Margin = new Padding(0),
                    Padding = new Padding(0),
                    Tag = "chrome-child"
                };

                TLPPriceList.Controls.Remove(dgvPriceList);
                dgvPriceList.Dock = DockStyle.Fill;
                gridHost.Controls.Add(dgvPriceList);
                TLPPriceList.Controls.Add(gridHost, 0, 0);
            }

            gridHost.Controls.Add(splitNameMgBrowse);
            splitNameMgBrowse.BringToFront();

            dgvBrowseNames.SelectionChanged += dgvBrowseNames_SelectionChanged;
            dgvBrowseMg.CellClick += dgvBrowseMg_CellClick;
            dgvBrowseNames.KeyPress += dgvPriceList_KeyPress;
            dgvBrowseMg.KeyPress += dgvPriceList_KeyPress;
            splitNameMgBrowse.SplitterMoved += (_, __) =>
            {
                if (splitNameMgBrowse.SplitterDistance > 80)
                {
                    _browseSplitterDistance = splitNameMgBrowse.SplitterDistance;
                }
            };
        }

        private static ModernDataGridView CreateBrowseGrid(string name)
        {
            var grid = new ModernDataGridView
            {
                Name = name,
                Dock = DockStyle.Fill,
                AllowUserToAddRows = false,
                AllowUserToDeleteRows = false,
                AllowUserToResizeRows = false,
                AllowUserToResizeColumns = true,
                MultiSelect = false,
                ReadOnly = true,
                RowHeadersVisible = false,
                SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                AutoGenerateColumns = true,
                Font = new Font("Segoe UI", 13F, FontStyle.Regular),
                TabStop = true
            };
            return grid;
        }

        private void AlignSearchRow()
        {
            const int searchY = 10;
            const int searchHeight = 32;
            const int clearGap = 4;
            const int leftPad = 10;

            label2.Location = new Point(leftPad, searchY + 4);
            txtSearchGoodNameInPriceList.SetBounds(label2.Right + 6, searchY, 300, searchHeight);
            btnClearSearchInPriceList.SetBounds(
                txtSearchGoodNameInPriceList.Right + clearGap,
                searchY,
                32,
                searchHeight);
            ModernButtonStyles.ApplyClear(btnClearSearchInPriceList);

            lblSupplierFilter.Location = new Point(btnClearSearchInPriceList.Right + 16, searchY + 4);
            comboSupplierFilter.SetBounds(lblSupplierFilter.Right + 6, searchY, 240, searchHeight);
            btnClearSupplierFilter.SetBounds(comboSupplierFilter.Right + clearGap, searchY, 32, searchHeight);
            btnClearSupplierFilter.Height = searchHeight;

            // Поиск всегда поверх контента, но контент начинается ниже searchBand.
            label2.BringToFront();
            txtSearchGoodNameInPriceList.BringToFront();
            btnClearSearchInPriceList.BringToFront();
            lblSupplierFilter.BringToFront();
            comboSupplierFilter.BringToFront();
            btnClearSupplierFilter.BringToFront();
        }

        private void LayoutMarkupRow()
        {
            // UI наценки скрыт; метод оставлен на случай повторного включения.
        }

        private void InitializeSupplierFilter()
        {
            try
            {
                _suppressSupplierFilterEvents = true;
                comboSupplierFilter.BeginUpdate();
                comboSupplierFilter.Items.Clear();
                comboSupplierFilter.Items.Add("Все поставщики");

                var suppliers = new List<string>();
                using (var con = new SQLiteConnection(connectionStringToLocalDB))
                {
                    con.Open();
                    using (var cmd = new SQLiteCommand("select SupplierName from PriceList where SupplierName is not null and SupplierName <> '' group by SupplierName order by SupplierName asc;", con))
                    {
                        using (var reader = cmd.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                var value = reader.GetString(0);
                                if (!string.IsNullOrWhiteSpace(value))
                                {
                                    suppliers.Add(value);
                                }
                            }
                        }
                    }
                }

                foreach (var s in suppliers)
                {
                    comboSupplierFilter.Items.Add(s);
                }

                comboSupplierFilter.SelectedIndex = 0;
                _selectedSupplierFilter = string.Empty;
                _committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;
                btnClearSupplierFilter.Visible = false;
            }
            finally
            {
                comboSupplierFilter.EndUpdate();
                _suppressSupplierFilterEvents = false;
            }
        }

        private void ApplyPriceListFilters()
        {
            if (_browseMode == PriceBrowseMode.Browse)
            {
                ShowBrowseView();
                return;
            }

            if (_fullPriceTable == null)
            {
                return;
            }

            // Фильтр по базовому имени/МГ применим только к полной таблице прайса.
            if (!ReferenceEquals(bsPriceList.DataSource, _fullPriceTable)
                || !_fullPriceTable.Columns.Contains("Базовое наименование")
                || !_fullPriceTable.Columns.Contains("МГ"))
            {
                ShowOffersView(_selectedBaseName, string.IsNullOrEmpty(_selectedMg) ? EmptyMgDisplay : _selectedMg);
                return;
            }

            var parts = new List<string>();

            if (!string.IsNullOrWhiteSpace(_selectedSupplierFilter))
            {
                var escapedSupplier = _selectedSupplierFilter.Replace("'", "''");
                parts.Add($"[Поставщик] = '{escapedSupplier}'");
            }

            if (!string.IsNullOrWhiteSpace(_selectedBaseName))
            {
                var escapedName = _selectedBaseName.Replace("'", "''");
                var escapedMg = (_selectedMg ?? string.Empty).Replace("'", "''");
                parts.Add($"[Базовое наименование] = '{escapedName}'");
                parts.Add($"[МГ] = '{escapedMg}'");
            }
            else if (!string.IsNullOrWhiteSpace(GoodsFilter))
            {
                var escaped = GoodsFilter.Replace("'", "''");
                parts.Add($"[Наименование] like '%{escaped}%'");
            }

            try
            {
                bsPriceList.Filter = parts.Count == 0 ? string.Empty : string.Join(" AND ", parts);
            }
            catch (EvaluateException)
            {
                ShowOffersView(_selectedBaseName, string.IsNullOrEmpty(_selectedMg) ? EmptyMgDisplay : _selectedMg);
            }
        }

        private void comboSupplierFilter_SelectionChangeCommitted(object sender, EventArgs e)
        {
            // Defer until the dropdown has fully closed.
            BeginInvoke(new Action(ApplySupplierFilterFromCombo));
        }

        private void ApplySupplierFilterFromCombo()
        {
            if (_suppressSupplierFilterEvents)
            {
                return;
            }

            if (comboSupplierFilter.SelectedIndex == _committedSupplierFilterIndex)
            {
                return;
            }

            _committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;

            var selected = comboSupplierFilter.SelectedItem as string;
            if (string.IsNullOrWhiteSpace(selected) || selected == "Все поставщики")
            {
                _selectedSupplierFilter = string.Empty;
                btnClearSupplierFilter.Visible = false;
            }
            else
            {
                _selectedSupplierFilter = selected;
                btnClearSupplierFilter.Visible = true;
            }

            ApplyPriceListFilters();
        }

        private void btnClearSupplierFilter_Click(object sender, EventArgs e)
        {
            _suppressSupplierFilterEvents = true;
            comboSupplierFilter.SelectedIndex = 0;
            _suppressSupplierFilterEvents = false;

            _committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;
            _selectedSupplierFilter = string.Empty;
            btnClearSupplierFilter.Visible = false;
            ApplyPriceListFilters();
        }

        private DataTable LoadPriceListTable(string supplierName)
        {
            var tablePrice = new DataTable();

            var q = "select * from PriceList";
            if (!string.IsNullOrWhiteSpace(supplierName))
            {
                q += " where SupplierName = @supplierName";
            }

            using (var con = new SQLiteConnection(connectionStringToLocalDB))
            {
                con.Open();
                using (var cmd = new SQLiteCommand(q, con))
                {
                    if (!string.IsNullOrWhiteSpace(supplierName))
                    {
                        cmd.Parameters.AddWithValue("@supplierName", supplierName);
                    }

                    using (var da = new SQLiteDataAdapter(cmd))
                    {
                        da.Fill(tablePrice);
                    }
                }
            }

            return tablePrice;
        }

        private void ApplyPriceListTable(DataTable tablePrice)
        {
            // Keep existing logic: just rename columns and re-bind.
            tablePrice.Columns[0].ColumnName = "ИД товара";
            tablePrice.Columns[1].ColumnName = "Код товара";
            tablePrice.Columns[2].ColumnName = "ИД поставщика";
            tablePrice.Columns[3].ColumnName = "Наименование";
            tablePrice.Columns[4].ColumnName = "Поставщик";
            tablePrice.Columns[5].ColumnName = "Цена";
            tablePrice.Columns[6].ColumnName = "Остаток";
            tablePrice.Columns[7].ColumnName = "Срок годности";
            tablePrice.Columns[8].ColumnName = "Описание";
            tablePrice.Columns[9].ColumnName = "Заказ";
            tablePrice.Columns[10].ColumnName = "Сумма";
            tablePrice.Columns[12].ColumnName = "ИДПрайсЛистАйтем";

            if (tablePrice.Columns.Contains("TradeName"))
            {
                tablePrice.Columns["TradeName"].ColumnName = "Торговое название";
            }

            if (tablePrice.Columns.Contains("Dosage"))
            {
                tablePrice.Columns["Dosage"].ColumnName = "Дозировка";
            }

            if (tablePrice.Columns.Contains("MarkupPercent"))
            {
                tablePrice.Columns["MarkupPercent"].ColumnName = "Наценка %";
            }

            EnsureDerivedBrowseColumns(tablePrice);
            _fullPriceTable = tablePrice;
            RebuildBrowseIndex(tablePrice);
            _selectedBaseName = string.Empty;
            _selectedMg = string.Empty;
            ShowBrowseView();
        }

        private void RebuildBrowseIndex(DataTable tablePrice)
        {
            var names = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
            var mgMap = new Dictionary<string, SortedSet<string>>(StringComparer.OrdinalIgnoreCase);

            foreach (DataRow row in tablePrice.Rows)
            {
                var baseName = row["Базовое наименование"]?.ToString() ?? string.Empty;
                if (string.IsNullOrWhiteSpace(baseName))
                {
                    continue;
                }

                names.Add(baseName);
                if (!mgMap.TryGetValue(baseName, out var dosages))
                {
                    dosages = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
                    mgMap[baseName] = dosages;
                }

                dosages.Add(row["МГ"]?.ToString() ?? string.Empty);
            }

            _uniqueBaseNames = names.ToList();
            _mgByBaseName = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
            foreach (var pair in mgMap)
            {
                var list = new List<string>(pair.Value.Count);
                foreach (var dosage in pair.Value)
                {
                    list.Add(string.IsNullOrEmpty(dosage) ? EmptyMgDisplay : dosage);
                }

                _mgByBaseName[pair.Key] = list;
            }
        }

        private void EnsureSearchDebounceTimer()
        {
            if (_searchDebounceTimer != null)
            {
                return;
            }

            _searchDebounceTimer = new Timer { Interval = SearchDebounceMs };
            _searchDebounceTimer.Tick += (_, __) =>
            {
                _searchDebounceTimer.Stop();
                ResetBrowseToNames();
            };
        }

        private void ScheduleBrowseSearchRefresh(bool immediate = false)
        {
            EnsureSearchDebounceTimer();
            _searchDebounceTimer.Stop();
            if (immediate)
            {
                ResetBrowseToNames();
                return;
            }

            _searchDebounceTimer.Start();
        }

        private void HideOptionalColumn(string columnName)
        {
            if (dgvPriceList.Columns.Contains(columnName))
            {
                dgvPriceList.Columns[columnName].Visible = false;
            }
        }

        private void EnsureDerivedBrowseColumns(DataTable tablePrice)
        {
            if (!tablePrice.Columns.Contains("Базовое наименование"))
            {
                tablePrice.Columns.Add("Базовое наименование", typeof(string));
            }

            if (!tablePrice.Columns.Contains("МГ"))
            {
                tablePrice.Columns.Add("МГ", typeof(string));
            }

            foreach (DataRow row in tablePrice.Rows)
            {
                var drugName = row["Наименование"]?.ToString() ?? string.Empty;
                var tradeName = tablePrice.Columns.Contains("Торговое название")
                    ? row["Торговое название"]?.ToString()
                    : null;
                var dosage = tablePrice.Columns.Contains("Дозировка")
                    ? row["Дозировка"]?.ToString()
                    : null;

                if (string.IsNullOrWhiteSpace(dosage))
                {
                    dosage = ExtractDosageFromName(drugName);
                }

                dosage = (dosage ?? string.Empty).Trim();
                row["МГ"] = dosage;
                row["Базовое наименование"] = BuildBaseName(drugName, tradeName, dosage);
            }
        }

        private static string ExtractDosageFromName(string drugName)
        {
            if (string.IsNullOrWhiteSpace(drugName))
            {
                return string.Empty;
            }

            var match = DosageRegex.Match(drugName);
            return match.Success ? match.Value.Trim() : string.Empty;
        }

        private static string BuildBaseName(string drugName, string tradeName, string dosage)
        {
            if (!string.IsNullOrWhiteSpace(tradeName))
            {
                return tradeName.Trim();
            }

            var name = drugName ?? string.Empty;
            if (!string.IsNullOrWhiteSpace(dosage))
            {
                var idx = name.IndexOf(dosage, StringComparison.OrdinalIgnoreCase);
                if (idx >= 0)
                {
                    name = name.Remove(idx, dosage.Length);
                }
            }

            name = Regex.Replace(name, @"\s{2,}", " ").Trim(' ', ',', '-', '.', ';');
            return string.IsNullOrWhiteSpace(name) ? (drugName ?? string.Empty).Trim() : name;
        }

        private void ShowBrowseView()
        {
            if (_fullPriceTable == null)
            {
                return;
            }

            EnsureBrowseSplit();
            _browseMode = PriceBrowseMode.Browse;
            _selectedMg = string.Empty;

            try
            {
                bsPriceList.RemoveFilter();
            }
            catch
            {
                bsPriceList.Filter = string.Empty;
            }

            var search = (GoodsFilter ?? string.Empty).Trim();
            IList<string> namesToShow;
            if (string.IsNullOrWhiteSpace(search))
            {
                namesToShow = _uniqueBaseNames;
            }
            else
            {
                var matching = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                foreach (DataRow row in _fullPriceTable.Rows)
                {
                    var baseName = row["Базовое наименование"]?.ToString() ?? string.Empty;
                    if (string.IsNullOrWhiteSpace(baseName) || matching.Contains(baseName))
                    {
                        continue;
                    }

                    var drugName = row["Наименование"]?.ToString() ?? string.Empty;
                    var mgText = row["МГ"]?.ToString() ?? string.Empty;
                    if (baseName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0
                        || drugName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0
                        || mgText.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        matching.Add(baseName);
                    }
                }

                namesToShow = matching
                    .OrderBy(n => n, StringComparer.OrdinalIgnoreCase)
                    .ToList();
            }

            var namesTable = new DataTable();
            namesTable.Columns.Add("Наименование", typeof(string));
            namesTable.BeginLoadData();
            foreach (var baseName in namesToShow)
            {
                namesTable.Rows.Add(baseName);
            }
            namesTable.EndLoadData();

            try
            {
                _suppressBrowseEvents = true;
                dgvBrowseNames.SuspendLayout();
                dgvBrowseNames.DataSource = namesTable;
                ConfigureSingleColumnGrid(dgvBrowseNames, "Наименование");
                ClearMgPanel();

                if (!string.IsNullOrWhiteSpace(_selectedBaseName))
                {
                    SelectBrowseName(_selectedBaseName);
                }
                else
                {
                    dgvBrowseNames.ClearSelection();
                }
            }
            finally
            {
                dgvBrowseNames.ResumeLayout();
                _suppressBrowseEvents = false;
            }

            ShowBrowsePanels(true);
            if (!string.IsNullOrWhiteSpace(_selectedBaseName) && dgvBrowseNames.SelectedRows.Count > 0)
            {
                FillMgPanelForName(_selectedBaseName);
            }

            ShowMePriceWithMarkupPercentForSelectedGood();
        }

        private void ClearMgPanel()
        {
            var empty = new DataTable();
            empty.Columns.Add("МГ", typeof(string));
            dgvBrowseMg.DataSource = empty;
            ConfigureSingleColumnGrid(dgvBrowseMg, "МГ");
            dgvBrowseMg.ClearSelection();
        }

        private void FillMgPanelForName(string baseName)
        {
            var mgTable = new DataTable();
            mgTable.Columns.Add("МГ", typeof(string));

            if (_mgByBaseName.TryGetValue(baseName, out var dosages))
            {
                foreach (var dosage in dosages)
                {
                    mgTable.Rows.Add(dosage);
                }
            }

            try
            {
                _suppressBrowseEvents = true;
                dgvBrowseMg.DataSource = mgTable;
                ConfigureSingleColumnGrid(dgvBrowseMg, "МГ");
                dgvBrowseMg.ClearSelection();
            }
            finally
            {
                _suppressBrowseEvents = false;
            }
        }

        private void ConfigureSingleColumnGrid(ModernDataGridView grid, string columnName)
        {
            grid.AutoGenerateColumns = true;
            grid.AllowUserToResizeColumns = true;
            grid.Font = new Font("Segoe UI", 13F, FontStyle.Regular);

            foreach (DataGridViewColumn column in grid.Columns)
            {
                var match = string.Equals(column.Name, columnName, StringComparison.Ordinal)
                    || string.Equals(column.HeaderText, columnName, StringComparison.Ordinal);
                column.Visible = match;
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                column.Resizable = DataGridViewTriState.True;
                column.MinimumWidth = 80;
            }
        }

        private void SelectBrowseName(string baseName)
        {
            for (var i = 0; i < dgvBrowseNames.Rows.Count; i++)
            {
                var value = dgvBrowseNames.Rows[i].Cells["Наименование"]?.Value?.ToString();
                if (string.Equals(value, baseName, StringComparison.OrdinalIgnoreCase))
                {
                    dgvBrowseNames.ClearSelection();
                    dgvBrowseNames.Rows[i].Selected = true;
                    if (dgvBrowseNames.Columns.Contains("Наименование"))
                    {
                        dgvBrowseNames.CurrentCell = dgvBrowseNames.Rows[i].Cells["Наименование"];
                    }

                    dgvBrowseNames.FirstDisplayedScrollingRowIndex = Math.Max(0, i);
                    return;
                }
            }
        }

        private void ShowBrowsePanels(bool browseVisible)
        {
            EnsureBrowseSplit();

            var gridHost = TLPPriceList.Controls["priceGridHost"] as Panel;
            if (gridHost != null)
            {
                gridHost.Dock = DockStyle.Fill;
                if (gridHost.Padding.Top < 8)
                {
                    gridHost.Padding = new Padding(0, 8, 0, 0);
                }
            }

            if (browseVisible)
            {
                dgvPriceList.Visible = false;
                splitNameMgBrowse.Visible = true;
                splitNameMgBrowse.Dock = DockStyle.Fill;
                splitNameMgBrowse.BringToFront();

                var width = Math.Max(200, splitNameMgBrowse.Width);
                var preferred = _browseSplitterDistance > 80
                    ? _browseSplitterDistance
                    : Math.Max(180, width / 2);
                preferred = Math.Min(preferred, Math.Max(120, width - 120));
                try
                {
                    splitNameMgBrowse.SplitterDistance = preferred;
                }
                catch
                {
                    // splitter not ready yet
                }
            }
            else
            {
                if (splitNameMgBrowse.SplitterDistance > 80)
                {
                    _browseSplitterDistance = splitNameMgBrowse.SplitterDistance;
                }

                splitNameMgBrowse.Visible = false;
                dgvPriceList.Visible = true;
                dgvPriceList.Dock = DockStyle.Fill;
                dgvPriceList.ColumnHeadersVisible = true;
                dgvPriceList.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
                dgvPriceList.BringToFront();
            }
        }

        private void ShowOffersView(string baseName, string mgDisplay)
        {
            if (_fullPriceTable == null || string.IsNullOrWhiteSpace(baseName))
            {
                return;
            }

            if (splitNameMgBrowse != null && splitNameMgBrowse.SplitterDistance > 80)
            {
                _browseSplitterDistance = splitNameMgBrowse.SplitterDistance;
            }

            _selectedBaseName = baseName;
            _selectedMg = string.Equals(mgDisplay, EmptyMgDisplay, StringComparison.Ordinal)
                ? string.Empty
                : (mgDisplay ?? string.Empty);

            _suppressSupplierFilterEvents = true;
            if (comboSupplierFilter.Items.Count > 0)
            {
                comboSupplierFilter.SelectedIndex = 0;
            }
            _suppressSupplierFilterEvents = false;
            _committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;
            _selectedSupplierFilter = string.Empty;
            btnClearSupplierFilter.Visible = false;

            BindOffersTable();
            ApplyOffersColumns();
            ShowBrowsePanels(false);

            var escapedName = _selectedBaseName.Replace("'", "''");
            var escapedMg = _selectedMg.Replace("'", "''");
            try
            {
                bsPriceList.Filter = $"[Базовое наименование] = '{escapedName}' AND [МГ] = '{escapedMg}'";
            }
            catch (EvaluateException ex)
            {
                AppDebugLog.Error("PriceList", "Не удалось применить фильтр наименование+МГ", ex);
                bsPriceList.RemoveFilter();
            }

            FocusOffersGridForInput();
        }

        private void FocusOffersGridForInput()
        {
            if (!IsHandleCreated)
            {
                return;
            }

            BeginInvoke(new Action(() =>
            {
                if (_browseMode != PriceBrowseMode.Offers || !dgvPriceList.Visible)
                {
                    return;
                }

                EnsureOffersRowSelected();
                dgvPriceList.Focus();
            }));
        }

        private bool EnsureOffersRowSelected()
        {
            if (_browseMode != PriceBrowseMode.Offers || dgvPriceList.Rows.Count == 0)
            {
                return false;
            }

            if (dgvPriceList.SelectedRows.Count > 0)
            {
                return true;
            }

            for (var i = 0; i < dgvPriceList.Rows.Count; i++)
            {
                var row = dgvPriceList.Rows[i];
                if (row.IsNewRow)
                {
                    continue;
                }

                _suppressPriceListSelectionEvents = true;
                try
                {
                    row.Selected = true;
                    var columnIndex = GetPreferredOffersSelectionColumnIndex();
                    if (columnIndex >= 0 && columnIndex < row.Cells.Count)
                    {
                        dgvPriceList.CurrentCell = row.Cells[columnIndex];
                    }
                }
                finally
                {
                    _suppressPriceListSelectionEvents = false;
                }

                ShowMePriceWithMarkupPercentForSelectedGood();
                return true;
            }

            return false;
        }

        private int GetPreferredOffersSelectionColumnIndex()
        {
            if (dgvPriceList.Columns.Contains("Наименование"))
            {
                return dgvPriceList.Columns["Наименование"].Index;
            }

            return dgvPriceList.Columns.Count > 3 ? 3 : 0;
        }

        private void BindOffersTable()
        {
            try
            {
                _suppressBrowseEvents = true;
                _suppressPriceListSelectionEvents = true;
                _browseMode = PriceBrowseMode.Offers;

                try
                {
                    bsPriceList.RemoveFilter();
                }
                catch
                {
                    bsPriceList.Filter = string.Empty;
                }

                bsPriceList.DataSource = _fullPriceTable;
                dgvPriceList.DataSource = bsPriceList;
                dgvPriceList.AutoGenerateColumns = true;
                dgvPriceList.Font = new Font("Segoe UI", 13, FontStyle.Regular);
                dgvPriceList.AllowUserToResizeColumns = true;
                if (dgvPriceList.Rows.Count > 0)
                {
                    dgvPriceList.ClearSelection();
                }
            }
            finally
            {
                _suppressPriceListSelectionEvents = false;
                _suppressBrowseEvents = false;
                ShowMePriceWithMarkupPercentForSelectedGood();
            }
        }

        private void ApplyOffersColumns()
        {
            if (dgvPriceList.Columns.Count == 0)
            {
                return;
            }

            foreach (DataGridViewColumn column in dgvPriceList.Columns)
            {
                column.Visible = true;
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                column.Resizable = DataGridViewTriState.True;
            }

            if (dgvPriceList.Columns.Count > 0) dgvPriceList.Columns[0].Visible = false;
            if (dgvPriceList.Columns.Count > 1) dgvPriceList.Columns[1].Visible = false;
            if (dgvPriceList.Columns.Count > 2) dgvPriceList.Columns[2].Visible = false;
            if (dgvPriceList.Columns.Count > 7) dgvPriceList.Columns[7].Visible = true;
            if (dgvPriceList.Columns.Count > 8) dgvPriceList.Columns[8].Visible = false;
            if (dgvPriceList.Columns.Count > 11) dgvPriceList.Columns[11].Visible = false;
            if (dgvPriceList.Columns.Count > 12) dgvPriceList.Columns[12].Visible = false;

            HideOptionalColumn("Торговое название");
            HideOptionalColumn("Дозировка");
            HideOptionalColumn("Наценка %");
            HideOptionalColumn("Базовое наименование");
            HideOptionalColumn("МГ");

            if (dgvPriceList.Columns.Count > 3) dgvPriceList.Columns[3].Width = 760;
            if (dgvPriceList.Columns.Count > 4) dgvPriceList.Columns[4].Width = 150;
            if (dgvPriceList.Columns.Count > 5) dgvPriceList.Columns[5].Width = 120;
            if (dgvPriceList.Columns.Count > 6) dgvPriceList.Columns[6].Width = 100;
            if (dgvPriceList.Columns.Count > 7) dgvPriceList.Columns[7].Width = 140;
            if (dgvPriceList.Columns.Count > 9) dgvPriceList.Columns[9].Width = 100;
            if (dgvPriceList.Columns.Count > 10) dgvPriceList.Columns[10].Width = 100;
        }

        private void dgvBrowseNames_SelectionChanged(object sender, EventArgs e)
        {
            if (_suppressBrowseEvents || _browseMode != PriceBrowseMode.Browse)
            {
                return;
            }

            if (dgvBrowseNames.SelectedRows.Count == 0)
            {
                _selectedBaseName = string.Empty;
                ClearMgPanel();
                return;
            }

            var name = dgvBrowseNames.SelectedRows[0].Cells["Наименование"]?.Value?.ToString() ?? string.Empty;
            _selectedBaseName = name;
            _selectedMg = string.Empty;
            if (string.IsNullOrWhiteSpace(name))
            {
                ClearMgPanel();
                return;
            }

            FillMgPanelForName(name);
            ShowMePriceWithMarkupPercentForSelectedGood();
        }

        private void dgvBrowseMg_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (_suppressBrowseEvents || e.RowIndex < 0 || e.RowIndex >= dgvBrowseMg.Rows.Count)
            {
                return;
            }

            if (_browseMode != PriceBrowseMode.Browse || string.IsNullOrWhiteSpace(_selectedBaseName))
            {
                return;
            }

            var mg = dgvBrowseMg.Rows[e.RowIndex].Cells["МГ"]?.Value?.ToString() ?? string.Empty;
            ShowOffersView(_selectedBaseName, mg);
        }

        private void NavigateBrowseBack()
        {
            if (_browseMode == PriceBrowseMode.Offers)
            {
                // Оставляем выбранное наименование, справа снова покажем его МГ.
                _selectedMg = string.Empty;
                ShowBrowseView();
            }
        }

        private void ResetBrowseToNames()
        {
            _selectedBaseName = string.Empty;
            _selectedMg = string.Empty;
            ShowBrowseView();
        }

        private void HandleBackspaceInPriceList(int rowIndex, string idPriceListItem)
        {
            if (_browseMode == PriceBrowseMode.Offers)
            {
                if (rowIndex >= 0
                    && rowIndex < dgvPriceList.Rows.Count
                    && dgvPriceList.Rows[rowIndex].Cells.Count > 9)
                {
                    var qty = dgvPriceList.Rows[rowIndex].Cells[9].Value?.ToString() ?? string.Empty;
                    if (!string.IsNullOrWhiteSpace(qty))
                    {
                        if (!string.IsNullOrEmpty(idPriceListItem))
                        {
                            deleteGood(rowIndex, idPriceListItem);
                        }
                        else
                        {
                            dgvPriceList.Rows[rowIndex].Cells[9].Value = string.Empty;
                            dgvPriceList.Rows[rowIndex].Cells[10].Value = string.Empty;
                        }

                        return;
                    }
                }

                ResetBrowseToNames();
                if (dgvBrowseNames != null && dgvBrowseNames.Visible)
                {
                    dgvBrowseNames.Focus();
                }

                return;
            }

            if (GoodsFilter.Length == 0)
            {
                return;
            }

            GoodsFilter = GoodsFilter.Substring(0, GoodsFilter.Length - 1);
            txtSearchGoodNameInPriceList.Text = GoodsFilter;
            ScheduleBrowseSearchRefresh(immediate: GoodsFilter.Length == 0);

            if (GoodsFilter.Length == 0)
            {
                timerForResetSearch.Enabled = false;
                timerForResetSearch.Stop();
            }
            else
            {
                timerForResetSearch.Enabled = true;
                timerForResetSearch.Start();
            }
        }


        void loadInfoAboutDefaultMarkup()
        {
            decimal percentageMarkupDefault = 0m;
            var fromConsignee = ConsigneeHelper.GetClientMarkupPercent(_WorkWithConsignee);
            if (fromConsignee.HasValue)
            {
                percentageMarkupDefault = fromConsignee.Value;
            }
            else
            {
                percentageMarkupDefault = Properties.Settings.Default.ClientMarkupPercent;
                if (percentageMarkupDefault <= 0)
                {
                    percentageMarkupDefault = Properties.Settings.Default.IntDefaultPercentMarkup;
                }

                if (percentageMarkupDefault < 0)
                {
                    percentageMarkupDefault = MarkupHelper.FallbackMarkupPercent;
                }

                // Первый запуск для этой аптеки — сразу закрепим текущее значение за аптекой.
                if (!string.IsNullOrWhiteSpace(_WorkWithConsignee))
                {
                    try
                    {
                        ConsigneeHelper.SetClientMarkupPercent(_WorkWithConsignee, percentageMarkupDefault);
                    }
                    catch
                    {
                        // колонка может ещё не быть — при следующем старте миграция добавит
                    }
                }
            }

            _percentageAsDefault = percentageMarkupDefault;
            _suppressMarkupPersist = true;
            try
            {
                numericPercent.DecimalPlaces = 2;
                numericPercent.Increment = 0.1m;
                numericPercent.Value = Math.Max(
                    numericPercent.Minimum,
                    Math.Min(numericPercent.Maximum, percentageMarkupDefault));
            }
            finally
            {
                _suppressMarkupPersist = false;
            }
        }

        private decimal GetMarkupPercentForRow(DataGridViewRow row)
        {
            // Для превью/спиннера всегда используем процент аптеки, который задал клиент.
            // Серверные значения в колонке «Наценка %» не перетирают ручной ввод.
            return _percentageAsDefault;
        }

        public void loadSupplierTabs(string SupplierName)
        {
            string tabName;

            if (SupplierName == string.Empty)
            {
                tabName = "Корзина";
            }
            else
            {
                tabName = SupplierName;
            }

            TabPage pageSupplier = new TabPage($"{tabName}");
            if (SupplierName == string.Empty)
            {
                pageSupplier.Tag = "cart";
            }

            UCOrderItems UCOrderItemsBySuppliers = new UCOrderItems(SupplierName);
            UCOrderItemsBySuppliers.ParentForm = this;
            UCOrderItemsBySuppliers.Dock = DockStyle.Fill;

            pageSupplier.Controls.Add(UCOrderItemsBySuppliers);

            tabOrderItems.TabPages.Add(pageSupplier);
            tabOrderItems.SelectTab(pageSupplier);
        }

        public void loadTempOrderItems()
        {
            string connectionStringToLocalDB = AppConfig.SqliteConnectionString;

            List<String> SuppliersFromOrder = new List<String>();

            var consigneeSafe = (_WorkWithConsignee ?? string.Empty).Replace("'", "''");
            string qShowMeSuppliersFromOrder = $@"
select 
[SupplierName]
from [TempOrderItems]
where [ConsigneeName] = '{consigneeSafe}'
group by [SupplierName]
";

            tabOrderItems.TabPages.Clear();

            int tabPagesCount = tabOrderItems.TabCount;

            loadSupplierTabs(string.Empty);

            using (SQLiteConnection conSuppliersTempOrderGroup = new SQLiteConnection(connectionStringToLocalDB))
            {
                try
                {
                    conSuppliersTempOrderGroup.Open();
                    SQLiteCommand cmdShowMeSuppliersFromOrder = new SQLiteCommand(qShowMeSuppliersFromOrder, conSuppliersTempOrderGroup);
                    SQLiteDataReader dr = cmdShowMeSuppliersFromOrder.ExecuteReader();

                    while (dr.Read())
                    {
                        loadSupplierTabs(dr.GetString(0));
                    }
                }
                catch(Exception ex)
                {
                    ToastNotification.ShowError($"Ошибка при создании вкладок: {ex.Message}");
                }
                finally
                {
                    conSuppliersTempOrderGroup.Close();
                }
            }
            dgvPriceList.Focus();
        }


        public void loadPriceListV2()
        {
            ApplyPriceListTable(LoadPriceListTable(string.Empty));
            ApplyPriceListFilters();
        }

        private void loadPriceListV2(string supplierFilter)
        {
            ApplyPriceListTable(LoadPriceListTable(string.Empty));
            _selectedSupplierFilter = supplierFilter ?? string.Empty;
            ApplyPriceListFilters();
        }

        #region старая загрузка прайсов
        public void loadPriceListV1(string FilterAddon)
        {
            string connectionStringToLocalDB = AppConfig.SqliteConnectionString;

            string qShowMePriceList = $@"
select
pl.[GoodCode] as [Код товара],
pl.[GoodName] as [Наименование],
pl.[ProducerName] as [Производитель],
pl.[SupplierName] as [Поставщик],
pl.[BestBefore] as [Срок годности],
pl.[JNVLS] as [ЖНВЛП?],
pl.[AvaibleCount] as [Доступно],
pl.[PriceSupplierWithNDS] as [Цена],
pl.[CountIWantBuy] as [Заказано],
pl.[SumIWantBuy] as [Сумма],
pl.[Marked] as [Признак маркировки]
from [PriceList] pl
where pl.AvaibleCount > 0
and pl.ConsigneesCode = (select codeConsignees from Consignees where ConsigneesName = '{_WorkWithConsignee}')
{FilterAddon}
order by pl.goodname asc
";

            SQLiteConnection conPriceList = new SQLiteConnection(connectionStringToLocalDB);
            try
            {
                conPriceList.Open();
                daPriceList = new SQLiteDataAdapter(qShowMePriceList, conPriceList);
                dsPriceList = new DataSet();
                daPriceList.Fill(dsPriceList, "PriceList");


                dgvPriceList.DataSource = dsPriceList.Tables["PriceList"];

                //dgvPriceList.AutoGenerateColumns = true;
                BindingSource bsPriceList = new BindingSource();
                bsPriceList.DataSource = dsPriceList.Tables["PriceList"];



                dgvPriceList.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing;
                dgvPriceList.RowHeadersVisible = false;

                dgvPriceList.Columns[0].ReadOnly = true;
                dgvPriceList.Columns[1].ReadOnly = true;
                dgvPriceList.Columns[2].ReadOnly = true;
                dgvPriceList.Columns[3].ReadOnly = true;
                dgvPriceList.Columns[4].ReadOnly = true;
                dgvPriceList.Columns[5].ReadOnly = true;
                dgvPriceList.Columns[6].ReadOnly = true;
                dgvPriceList.Columns[7].ReadOnly = true;
                dgvPriceList.Columns[8].ReadOnly = true;
                dgvPriceList.Columns[9].ReadOnly = false;
                dgvPriceList.Columns[10].ReadOnly = true;

                dgvPriceList.Columns[9].DefaultCellStyle.Format = "N0";

                dgvPriceList.DefaultCellStyle.Font = new Font("Segoe UI", 10, FontStyle.Regular);


                //dgvPriceList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;

                dgvPriceList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;

                dgvPriceList.Columns["Код товара"].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                dgvPriceList.Columns["Код товара"].Width = 1;

                dgvPriceList.Columns["Наименование"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                dgvPriceList.Columns["Производитель"].Width = 200;
                dgvPriceList.Columns["Поставщик"].Width = 130;
                dgvPriceList.Columns["Срок годности"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                //dgvPriceList.Columns["Доступно"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                //dgvPriceList.Columns["Цена"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                //dgvPriceList.Columns["Заказано"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                //dgvPriceList.Columns["Сумма"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                //dgvPriceList.Columns["Признак маркировки"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

                dgvPriceList.Columns["ЖНВЛП?"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

            }
            catch (Exception ex)
            {
                ToastNotification.ShowError($"Ошибка загрузки прайс-листа: {ex.Message}");
            }
            finally
            {
                conPriceList.Close();
            }

        }
        #endregion



        void AddItemInOrdersItems(string GoodCode, string GoodName, string SupplierName, string ItemConsigner, string BestBefore, string CountItem, string SumItem, string PriceItem)
        {
            string connectionStringToLocalDB = AppConfig.SqliteConnectionString;

            using (SQLiteConnection conTempOrder = new SQLiteConnection(connectionStringToLocalDB))
            {


                string qInsertDataInTempTableOrderItems = $@"
insert into [TempOrderItems] values (
'{GoodCode}',
'{GoodName}',
'{SupplierName}',
'{ItemConsigner}',
'{CountItem}',
'{SumItem}',
'{PriceItem}',
'{BestBefore}'
)
";

                string qShowMeCountsOfOrderedThatGood = $@"
select count(GoodCode) from TempOrderItems where
GoodCode = '{GoodCode}' and
GoodName = '{GoodName}' and
SupplierName = '{SupplierName}' and
ConsigneesName = '{ItemConsigner}' and
SupplierPrice = '{PriceItem}' and
BestBefore  = '{BestBefore}'
";

                string qUpdateOrderedPriceListItems = $@"
update TempOrderItems
set OrderedCountItems = '{CountItem}',
SumOrderedItems = '{SumItem}'
where
GoodCode = '{GoodCode}' and
GoodName = '{GoodName}' and
SupplierName = '{SupplierName}' and
ConsigneesName = '{ItemConsigner}' and
SupplierPrice = '{PriceItem}' and
BestBefore  = '{BestBefore}'
";

                try
                {
                    conTempOrder.Open();
                    int RowCountsOfThatGood = 0;
                    SQLiteCommand cmdCheckCountOfOrderedItems = new SQLiteCommand(qShowMeCountsOfOrderedThatGood, conTempOrder);
                    RowCountsOfThatGood = Convert.ToInt32(cmdCheckCountOfOrderedItems.ExecuteScalar());
                    if (RowCountsOfThatGood > 0)
                    {
                        SQLiteCommand cmdUpdatePriceListItems = new SQLiteCommand(qUpdateOrderedPriceListItems, conTempOrder);
                        cmdUpdatePriceListItems.ExecuteNonQuery();
                    }
                    else
                    {
                        SQLiteCommand cmdFillTempOrderItems = new SQLiteCommand(qInsertDataInTempTableOrderItems, conTempOrder);
                        cmdFillTempOrderItems.ExecuteNonQuery();
                    }
                }
                catch (Exception ex)
                {
                    ToastNotification.ShowError($"Ошибка заполнения корзины: {ex.Message}");
                }
                finally
                {
                    conTempOrder.Close();
                }
                loadTempOrderItems();
            }
        }

        private void btnSendOrder_Click(object sender, EventArgs e)
        {
            string connectionStringToLocalDB = AppConfig.SqliteConnectionString;

            string OrderNumber = OrderNumberHelper.AllocateForNewOrder();
            string OrderDate = DateTime.Now.ToString("yyyy-MM-dd");//DateTime.Now.ToShortDateString();

            

            using (SQLiteConnection conCreateOrder = new SQLiteConnection(connectionStringToLocalDB))
            {
                try
                {
                    conCreateOrder.Open();

                    string CountOrderedItems;
                    string SumOrderedItems;

                    string qShowMeCountOrderedItems = "select count(GoodCode) from TempOrderItems where OrderedCountItems > 0";
                    string qShowMeSumOrderedItems = "select sum(SumOrderedItems) from TempOrderItems where OrderedCountItems > 0";

                    SQLiteCommand cmdShowMeCountOfOrderedItems = new SQLiteCommand(qShowMeCountOrderedItems, conCreateOrder);
                    SQLiteCommand cmdShowMeSumOfOrderedItems = new SQLiteCommand(qShowMeSumOrderedItems, conCreateOrder);

                    qShowMeCountOrderedItems = Convert.ToString(cmdShowMeCountOfOrderedItems.ExecuteScalar());
                    qShowMeSumOrderedItems = Convert.ToString(cmdShowMeSumOfOrderedItems.ExecuteScalar());

                    string qCreateOrder = $@"
insert into [Orders] (OrderNumber, OrderDate, OrderedItemsCount, OrderSum, OrderState)
values
(
'{OrderNumber}',
select strftime('%Y-%m-%d','{OrderDate}'),
'{qShowMeCountOrderedItems}',
'{qShowMeSumOrderedItems}',
'SAVE'
)
";

                    

                    SQLiteCommand cmdCreateOrder = new SQLiteCommand(qCreateOrder, conCreateOrder);
                    cmdCreateOrder.ExecuteNonQuery();

                    foreach (DataGridViewRow row in dgvOrder.Rows)
                    {
                        string qCreateOrderItems = $@"
    insert into OrderItems (idOrder, GoodCode, GoodName, codeSuppliers, codeConsignees, OrderedCountItems, SupplierPrice, SumOrderedItems, BestBefore, ProducerName, ProducerPrice)
    values
    (
        (select idOrder from Orders where OrderNumber = '{OrderNumber}'),
        '{row.Cells[0].Value.ToString()}',
        '{row.Cells[1].Value.ToString()}',
        (select codeSuppliers from Suppliers where SuppliersName = '{row.Cells[2].Value.ToString()}'),
        (select codeConsignees from Consignees where ConsigneesName = '{row.Cells[3].Value.ToString()}'),
        '{row.Cells[5].Value.ToString()}',
        '{row.Cells[4].Value.ToString()}',
        '{row.Cells[6].Value.ToString()}',
        '{row.Cells[7].Value.ToString()}',
        '{row.Cells[8].Value.ToString()}',
        '{row.Cells[9].Value.ToString()}'
    )
    ";

                        SQLiteCommand cmdCreateOrderItems = new SQLiteCommand(qCreateOrderItems, conCreateOrder);
                        cmdCreateOrderItems.ExecuteNonQuery();
                    }
                    EraseOrder();
                }
                catch (Exception ex)
                {
                    ToastNotification.ShowError($"Ошибка формирования заказа: {ex.Message}");
                }
                finally
                {
                    conCreateOrder.Close();
                    
                }
            }
        }


        #region TODO: что-то с заказом, потом доделать под актуальную версию
//        void IWantBuyThisGood()
//        {
//            int selectedRowIndex = dgvPriceList.CurrentRow.Index;
//            //int IWantBuyGood = Convert.ToInt32(dgvPriceList.Rows[selectedRowIndex].Cells[10].Value.ToString());
//            int IWantBuyGood = Convert.ToInt32(dgvPriceList.Rows[selectedRowIndex].Cells[8].Value.ToString());

//            if (IWantBuyGood <= 0)
//            {
//                ErasePriceListOrderItem();
//            }
//            else if (IWantBuyGood > 0)
//            {
//                double SuppliersPrice = Convert.ToDouble(dgvPriceList.Rows[selectedRowIndex].Cells[7].Value.ToString());
//                double SumGoodsIWantBuy = SuppliersPrice * IWantBuyGood;
//                string sumBuy = SumGoodsIWantBuy.ToString();
//                dgvPriceList.Rows[selectedRowIndex].Cells[9].Value = sumBuy.ToString();
//                //dgvPriceList.Rows[selectedRowIndex].Cells[11].Value = "1";//SumGoodsIWantBuy.ToString();
//                //dgvPriceList.CurrentRow.Cells[11].Value =  SumGoodsIWantBuy.ToString();

//                string qUpdateCountAndSumInPriceListTable = $@"
//update PriceList set 
//[CountIWantBuy] = '{IWantBuyGood.ToString()}',
//[SumIWantBuy] = '{sumBuy.ToString()}'
//where 
//[GoodCode] = '{dgvPriceList.Rows[selectedRowIndex].Cells[0].Value.ToString()}'
//and [GoodName] = '{dgvPriceList.Rows[selectedRowIndex].Cells[1].Value.ToString()}'
//and [ProducerName] = '{dgvPriceList.Rows[selectedRowIndex].Cells[2].Value.ToString()}'
//and [SupplierName] = '{dgvPriceList.Rows[selectedRowIndex].Cells[3].Value.ToString()}'
//and [ConsigneesCode] = (select codeConsignees from Consignees where ConsigneesName = '{_WorkWithConsignee}')
//";
//                string connectionStringToLocalDB = AppConfig.SqliteConnectionString;

//                //dgvPriceList.Rows[selectedRowIndex].DefaultCellStyle.Font = new Font("Segoe UI", 10, FontStyle.Bold);

//                using (SQLiteConnection conUpdateBuyingGoods = new SQLiteConnection(connectionStringToLocalDB))
//                {
//                    try
//                    {
//                        conUpdateBuyingGoods.Open();
//                        SQLiteCommand cmdUpdateBuyingGoods = new SQLiteCommand(qUpdateCountAndSumInPriceListTable, conUpdateBuyingGoods);
//                        cmdUpdateBuyingGoods.ExecuteNonQuery();
//                    }
//                    catch (Exception ex)
//                    {
//                        MessageBox.Show($"Возникла ошибка при обновлении данных о закупке товаров. Текст ошибки:\n{ex.ToString()}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
//                    }
//                    finally
//                    {
//                        conUpdateBuyingGoods.Close();
//                    }
//                }



//                string ItemConsigner = txtConsignee.Text;
//                //if (ItemConsigner == "" | ItemConsigner == "Грузополучатель")
//                //{
//                //    MessageBox.Show("Пожалуйста, укажите грузополучателя.", "Предупреждение", MessageBoxButtons.OK, MessageBoxIcon.Hand);
//                //}
//                //else
//                //{
//                    string GoodCode = dgvPriceList.Rows[selectedRowIndex].Cells[0].Value.ToString();
//                    string GoodName = dgvPriceList.Rows[selectedRowIndex].Cells[1].Value.ToString();
//                    string SupplierName = dgvPriceList.Rows[selectedRowIndex].Cells[3].Value.ToString();
//                    string BestBefore = dgvPriceList.Rows[selectedRowIndex].Cells[4].Value.ToString();
//                    string CountItem = dgvPriceList.Rows[selectedRowIndex].Cells[8].Value.ToString();
//                    string SumItem = dgvPriceList.Rows[selectedRowIndex].Cells[9].Value.ToString();
//                    string PriceItem = dgvPriceList.Rows[selectedRowIndex].Cells[7].Value.ToString();

//                    AddItemInOrdersItems(GoodCode, GoodName, SupplierName, ItemConsigner, BestBefore, CountItem, SumItem, PriceItem);
//                //}

//            }
            
//        }
        #endregion

        private void dgvPriceList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
           //IWantBuyThisGood();

            //int RowIndex = dgvPriceList.SelectedRows[0].Index;
            //if (dgvPriceList.Rows[RowIndex].Cells[4].Value != string.Empty)
            //{

            //    Font customFont = new Font("Segoe UI", 13, FontStyle.Bold);

            //    dgvPriceList.Rows[RowIndex].DefaultCellStyle.Font = customFont;
            //}

        }


        private void btnClearSearchInPriceList_Click(object sender, EventArgs e)
        {
            txtSearchGoodNameInPriceList.Text = string.Empty;
            GoodsFilter = string.Empty;
            ScheduleBrowseSearchRefresh(immediate: true);
            //loadPriceList(string.Empty);
        }


        private void btnEraseOrder_Click(object sender, EventArgs e)
        {
            //DialogResult drAreYouSeriesAboutEraseOrder = MessageBox.Show("Вы уверены, что хотите очистить корзину?", "Сообщение", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            //if (drAreYouSeriesAboutEraseOrder == DialogResult.Yes)
            //{
            //    EraseOrder();
            //}

        }

        void EraseOrder()
        {
            string connectionStringToLocalDB = AppConfig.SqliteConnectionString;

            string qUpdatePriceListBuyingItems = $@"
update PriceList set 
[CountIWantBuy] = null,
[SumIWantBuy] = null
from (select GoodCode, GoodName, SupplierName, SupplierPrice from TempOrderItems) as tempOrder
where
tempOrder.GoodCode = PriceList.GoodCode
and tempOrder.GoodName = PriceList.GoodName
";
            string qEraseOrder = "delete from TempOrderItems";

            using (SQLiteConnection conEraseOrder = new SQLiteConnection(connectionStringToLocalDB))
            {
                try
                {
                    conEraseOrder.Open();
                    SQLiteCommand cmdUpdateBuyingItems = new SQLiteCommand(qUpdatePriceListBuyingItems, conEraseOrder);
                    SQLiteCommand cmdEraseOrder = new SQLiteCommand(qEraseOrder, conEraseOrder);
                    cmdUpdateBuyingItems.ExecuteNonQuery();
                    cmdEraseOrder.ExecuteNonQuery();
                    loadTempOrderItems();
                    //loadPriceList(string.Empty);
                }
                catch (Exception ex)
                {
                    ToastNotification.ShowError($"Ошибка очистки корзины: {ex.Message}");
                }
                finally
                {
                    conEraseOrder.Close();
                }
            }
        }

        string SumIWantBuy = string.Empty;
        int lastSelectedRowIndex;
        string GoodsFilter = string.Empty;
        string stringIWantBuy = string.Empty;

        private static bool IsGoodsSearchKey(char keyChar, bool allowDigitsAndSeparators = true)
        {
            if ((keyChar >= 'A' && keyChar <= 'Z')
                || (keyChar >= 'a' && keyChar <= 'z')
                || (keyChar >= 'А' && keyChar <= 'Я')
                || (keyChar >= 'а' && keyChar <= 'я')
                || keyChar == (char)Keys.Subtract)
            {
                return true;
            }

            if (!allowDigitsAndSeparators)
            {
                return false;
            }

            return (keyChar >= '0' && keyChar <= '9')
                || keyChar == ' '
                || keyChar == '.'
                || keyChar == ',';
        }

        private void dgvPriceList_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (Char)Keys.Escape)
            {
                if (_browseMode != PriceBrowseMode.Browse)
                {
                    NavigateBrowseBack();
                }
                else
                {
                    txtSearchGoodNameInPriceList.Text = string.Empty;
                    GoodsFilter = string.Empty;
                    ScheduleBrowseSearchRefresh(immediate: true);
                }

                return;
            }

            int RowIndex = -1;
            string idPriceListItem = string.Empty;

            if (_browseMode == PriceBrowseMode.Offers)
            {
                if (IsOrderQuantityStartKey(e.KeyChar))
                {
                    EnsureOffersRowSelected();
                    if (!dgvPriceList.Focused)
                    {
                        dgvPriceList.Focus();
                    }
                }

                if (dgvPriceList.SelectedRows.Count > 0)
                {
                    RowIndex = dgvPriceList.SelectedRows[0].Index;
                    if (RowIndex >= 0
                        && RowIndex < dgvPriceList.Rows.Count
                        && dgvPriceList.Rows[RowIndex].Cells.Count > 11)
                    {
                        idPriceListItem = dgvPriceList.Rows[RowIndex].Cells[11].Value?.ToString() ?? string.Empty;
                    }
                }
            }

            if (e.KeyChar == (Char)Keys.Back)
            {
                HandleBackspaceInPriceList(RowIndex, idPriceListItem);
                return;
            }

            if (_browseMode != PriceBrowseMode.Offers)
            {
                if (IsGoodsSearchKey(e.KeyChar))
                {
                    dgvPriceList.ClearSelection();
                    GoodsFilter += e.KeyChar.ToString();
                    txtSearchGoodNameInPriceList.Text = GoodsFilter;
                    ScheduleBrowseSearchRefresh();
                    timerForResetSearch.Enabled = true;
                    timerForResetSearch.Start();
                }

                return;
            }

            if (IsGoodsSearchKey(e.KeyChar, allowDigitsAndSeparators: false))
            {
                dgvPriceList.ClearSelection();
                GoodsFilter += e.KeyChar.ToString();
                txtSearchGoodNameInPriceList.Text = GoodsFilter;
                ScheduleBrowseSearchRefresh();
                timerForResetSearch.Enabled = true;
                timerForResetSearch.Start();
                return;
            }
            else if ((e.KeyChar >= (Char)Keys.D1 && e.KeyChar <= (Char)Keys.D9) ||
               (e.KeyChar >= (Char)Keys.NumPad1 && e.KeyChar <= (Char)Keys.NumPad9) || (RowIndex >= 0 && e.KeyChar == (Char)Keys.D0 && dgvPriceList.Rows[RowIndex].Cells[10].Value.ToString().Length > 1) || (RowIndex >= 0 && e.KeyChar == (Char)Keys.NumPad0 && dgvPriceList.Rows[RowIndex].Cells[10].Value.ToString().Length > 1))
            {
                    if (RowIndex < 0)
                    {
                        return;
                    }

                    if (!TryReadInt32(dgvPriceList.Rows[RowIndex].Cells[6].Value, out var quantityForSale))
                    {
                        return;
                    }

                    stringIWantBuy = dgvPriceList.Rows[RowIndex].Cells[9].Value.ToString() + e.KeyChar.ToString();
                    if (!TryReadInt32(stringIWantBuy, out var iWantBuy))
                    {
                        return;
                    }

                    if (iWantBuy <= quantityForSale)
                    {
                        dgvPriceList.Rows[RowIndex].Cells[9].Value = iWantBuy.ToString();

                        if (!TryReadDecimal(dgvPriceList.Rows[RowIndex].Cells[5].Value, out var priceForOne))
                        {
                            return;
                        }

                        dgvPriceList.Rows[RowIndex].Cells[10].Value = (iWantBuy * priceForOne).ToString();
                    }
                    else if (iWantBuy > quantityForSale)
                    {
                        DialogResult drIWantBuyAll = UiDialogs.ConfirmYesNoCancel($"Для заказа доступно только {quantityForSale.ToString()}. Заказать доступное количество?", "Заказ", FindForm());

                        if (drIWantBuyAll == DialogResult.Yes)
                        {
                            dgvPriceList.Rows[RowIndex].Cells[9].Value = quantityForSale.ToString();

                            if (!TryReadDecimal(dgvPriceList.Rows[RowIndex].Cells[5].Value, out var priceForOne))
                            {
                                return;
                            }

                            dgvPriceList.Rows[RowIndex].Cells[10].Value = (quantityForSale * priceForOne).ToString();
                        }
                    }
            }
            else if (e.KeyChar == (Char)Keys.Delete)
            {
                if (RowIndex < 0 || string.IsNullOrEmpty(idPriceListItem)) return;
                deleteGood(RowIndex, idPriceListItem);
            }
            else if (RowIndex >= 0 && dgvPriceList.Rows[RowIndex].Cells[9].Value?.ToString() == string.Empty  && e.KeyChar == (Char)Keys.D0)
            {
                
            }
            else if (e.KeyChar == (Char)Keys.Down || e.KeyChar == (Char)Keys.Up)
            {
                if (RowIndex < 0 || string.IsNullOrEmpty(idPriceListItem)) return;
                timerForResetSearch.Enabled = false;
                timerForResetSearch.Stop();

                foreach (DataGridViewRow row in dgvPriceList.Rows)
                {
                    if (TryReadInt32(row.Cells[9].Value, out var orderedCount) && orderedCount == 0)
                    {
                        int rowIndex = row.Index;
                        deleteGood(rowIndex, idPriceListItem);
                    }
                }
            }

            if (RowIndex < 0 || RowIndex >= dgvPriceList.Rows.Count) return;

            string summaZakaza = dgvPriceList.Rows[RowIndex].Cells[10].Value?.ToString() ?? string.Empty;


            if (summaZakaza.Trim().Length > 0)
            {
                string Zakaz = dgvPriceList.Rows[RowIndex].Cells[9].Value.ToString();

                creatingTempOrder(idPriceListItem, Zakaz, summaZakaza);

            }

            #region старое добавление товара в PLI
            //tabOrderItems.

            //dgvPriceList.EndEdit();
            //bsPriceList.EndEdit();

            //daPriceListMain.Update(dsPriceList);

            ////dsPriceList.Tables.Clear();
            //dsPriceList.WriteXml("PriceList.xml", XmlWriteMode.DiffGram);
            //dsPriceList.Tables.Add(tablePriceList.Copy());

            //dsPriceList.Tables["PriceList"].AcceptChanges();

            //tablePriceList = (dgvPriceList.DataSource as DataTable);



            //daPriceListMain.Update();
            //bsPriceList.DataSource = (dgvPriceList.DataSource as DataTable);
            //daPriceListMain.Update(dsPriceList);
            #endregion
        }

        void creatingTempOrder(string idPriceListItem, string zakaz, string summaZakaza)
        {
            var consigneeSafe = (_WorkWithConsignee ?? string.Empty).Replace("'", "''");
            string qUpdatePriceList = $"update [PriceList] set [Zakaz] = '{zakaz}', [SummaZakaza] = '{summaZakaza}' where [id_PriceList_Item] = '{idPriceListItem}'";
            string qDeleteFromTempOrder = $"delete from [TempOrderItems] where [id_PriceList_Item] = '{idPriceListItem}' and [ConsigneeName] = '{consigneeSafe}'";
            string qCreateNewTempOrder = $"insert into TempOrderItems([ConsigneeName],[guid_es],[es_code],[supplier_id],[DrugName],[SupplierName],[Price],[Quantity],[ExpiryPeriod],[Description],[Zakaz],[SummaZakaza],[id_PriceList_Item],[supplier_price_id]) select '{consigneeSafe}',[guid_es],[es_code],[supplier_id],[DrugName],[SupplierName],[Price],[Quantity],[ExpiryPeriod],[Description],[Zakaz],[SummaZakaza],[id_PriceList_Item],[supplier_price_id] from [PriceList] where [id_PriceList_Item] = '{idPriceListItem}'";

            using(SQLiteConnection sqlCon = new SQLiteConnection(connectionStringToLocalDB))
            {
                try
                {
                    sqlCon.Open();

                    SQLiteCommand cmdUpdatePriceList = new SQLiteCommand(qUpdatePriceList, sqlCon);
                    SQLiteCommand cmdDeleteFromTempOrder = new SQLiteCommand(qDeleteFromTempOrder, sqlCon);
                    SQLiteCommand cmdCreateNewTempOrder = new SQLiteCommand(qCreateNewTempOrder, sqlCon);

                    cmdUpdatePriceList.ExecuteNonQuery();
                    cmdDeleteFromTempOrder.ExecuteNonQuery();
                    cmdCreateNewTempOrder.ExecuteNonQuery();

                    loadTempOrderItems();
                    
                }
                catch(Exception ex)
                {
                    //MessageBox.Show($"Возникла ошибка при обновлении данных прайс-листов. Текст ошибки:\n{ex.ToString()}", "Обработка прайс-листов", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    sqlCon.Close();
                }
            }

        }
        

        void deleteGood(int index, string IdPriceListItem)
        {
            var consigneeSafe = (_WorkWithConsignee ?? string.Empty).Replace("'", "''");
            dgvPriceList.Rows[index].Cells[9].Value = string.Empty;
            dgvPriceList.Rows[index].Cells[10].Value = string.Empty;

            string IdPLI = IdPriceListItem;

            string qClearPriceList = $"update [PriceList] set [Zakaz] = null, [SummaZakaza] = null where id_PriceList_Item = '{IdPLI}'";
            string qDeleteFromTempOrder = $"delete from [TempOrderItems] where [id_PriceList_Item] = '{IdPLI}' and [ConsigneeName] = '{consigneeSafe}'";

            using(SQLiteConnection sqlCon = new SQLiteConnection(connectionStringToLocalDB))
            {
                try
                {
                    sqlCon.Open();

                    SQLiteCommand cmdClearPriceListItem = new SQLiteCommand(qClearPriceList, sqlCon);
                    SQLiteCommand cmdDeleteFromTempOrder = new SQLiteCommand(qDeleteFromTempOrder, sqlCon);

                    cmdClearPriceListItem.ExecuteNonQuery();
                    cmdDeleteFromTempOrder.ExecuteNonQuery();

                    loadTempOrderItems();
                }
                catch(Exception ex)
                {
                    //MessageBox.Show($"При обновлении данных прайс-листа возникла ошибка. Текст ошибки:\n{ex.ToString()}", "Обработка прайс-листов", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    sqlCon.Close();
                }
            }
        }

        #region TODO: старый метод, не работает
        //private void dgvPriceList_KeyPress(object sender, KeyPressEventArgs e)
        //{

        //    if ((e.KeyChar >= 'A' && e.KeyChar <= 'Z') || (e.KeyChar >= 'a' && e.KeyChar <= 'z') || (e.KeyChar >= 'А' && e.KeyChar <= 'Я') || (e.KeyChar >= 'а' && e.KeyChar <= 'я') || (e.KeyChar == (Char)Keys.Subtract))
        //    {
        //        if (e.KeyChar == (Char)Keys.Enter || e.KeyChar == (Char)Keys.Tab)
        //        {

        //        }
        //        else
        //        {
        //            timerForResetSearch.Enabled = false;
        //            timerForResetSearch.Stop();
        //            txtSearchGoodNameInPriceList.Text += e.KeyChar.ToString();



        //            string GoodNameFilter = txtSearchGoodNameInPriceList.Text;
        //            //GoodNameFilter = GoodNameFilter.Replace(" ", "%");
        //            //GoodNameFilter = GoodNameFilter.Replace("   ", "%");
        //            //string filterAddon = $" and pl.[GoodName] LIKE '%{GoodNameFilter.ToLower()}%'";
        //            //MessageBox.Show(GoodNameFilter);
        //            (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = $"[Наименование] like '%{GoodNameFilter.ToLower()}%'";

        //            timerForResetSearch.Enabled = true;
        //            timerForResetSearch.Start();

        //            if (dgvPriceList.RowCount < 1)
        //            {
        //                MessageBox.Show($"Подходящий товар не найден.", "Поиск", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        //                txtSearchGoodNameInPriceList.Text = string.Empty;
        //                //loadPriceList(string.Empty);

        //                (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = string.Empty;
        //                timerForResetSearch.Stop();
        //            }


        //        }

        //    }
        //    else if ((e.KeyChar >= (Char)Keys.D0 && e.KeyChar <= (Char)Keys.D9) ||
        //        (e.KeyChar >= (Char)Keys.NumPad0 && e.KeyChar <= (Char)Keys.NumPad9))
        //    {
        //        txtSearchGoodNameInPriceList.Text = string.Empty;
        //        int selectedRowIndex = dgvPriceList.SelectedCells[0].RowIndex;
        //        if (selectedRowIndex != lastSelectedRowIndex)
        //        {
        //            SumIWantBuy = string.Empty;
        //        }
        //        SumIWantBuy += e.KeyChar.ToString();
        //        if (SumIWantBuy == "0")
        //        {
        //            ErasePriceListOrderItem();
        //        }
        //        else
        //        {
        //            int AvaibleCountGood = Convert.ToInt32(dgvPriceList.Rows[selectedRowIndex].Cells[6].Value.ToString());


        //            if (AvaibleCountGood < Convert.ToInt32(SumIWantBuy))
        //            {
        //                MessageBox.Show("Заказано максимальное количество товара", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        //                SumIWantBuy = AvaibleCountGood.ToString();
        //            }
        //            dgvPriceList.Rows[selectedRowIndex].Cells[8].Value = SumIWantBuy;
        //            //IWantBuyThisGood();
        //            lastSelectedRowIndex = selectedRowIndex;
        //        }
        //    }
        //    else if (e.KeyChar == (Char)Keys.Back || e.KeyChar == (Char)Keys.Escape)
        //    {
        //        txtSearchGoodNameInPriceList.Text = string.Empty;
        //        (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = string.Empty;
        //        //loadPriceList(string.Empty);
        //    }
        //    else if (e.KeyChar == (Char)Keys.Delete)
        //    {
        //        ErasePriceListOrderItem();
        //    }
        //    else if (e.KeyChar != (Char)Keys.Enter)
        //    {
        //        txtSearchGoodNameInPriceList.Text += e.KeyChar.ToString();

        //        string GoodNameFilter = txtSearchGoodNameInPriceList.Text;
        //        //GoodNameFilter = GoodNameFilter.Replace(" ", "%");
        //        //string filterAddon = $" and pl.[GoodName] LIKE '%{GoodNameFilter.ToLower()}%'";

        //        (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = $"[Наименование] like '%{GoodNameFilter.ToLower()}%'";

        //        if (dgvPriceList.RowCount < 1)
        //        {
        //            MessageBox.Show($"Подходящий товар не найден.", "Поиск", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        //            txtSearchGoodNameInPriceList.Text = string.Empty;
        //            (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = string.Empty;
        //            //loadPriceList(string.Empty);
        //        }
        //    }
        //}
        #endregion

        void ErasePriceListOrderItem()
        {
            int rowIndex = dgvPriceList.SelectedCells[0].RowIndex;

            string goodCode = dgvPriceList.Rows[rowIndex].Cells[0].Value.ToString();
            string goodName = dgvPriceList.Rows[rowIndex].Cells[1].Value.ToString();
            string SupplierName = dgvPriceList.Rows[rowIndex].Cells[3].Value.ToString();
            string PriceGood = dgvPriceList.Rows[rowIndex].Cells[7].Value.ToString();
            string SumOrder = dgvPriceList.Rows[rowIndex].Cells[9].Value.ToString();

            string qUpdatePriceList = $@"update PriceList set 
[CountIWantBuy] = null,
[SumIWantBuy] = null
where [GoodCode] = '{goodCode}'
and [GoodName] = '{goodName}'
and [SupplierName] = '{SupplierName}'";


            string qDeleteFromTempOrder = $@"delete from TempOrderItems
where [GoodCode] = '{goodCode}'
and [GoodName] = '{goodName}'
and [SupplierName] = '{SupplierName}'
and [SupplierPrice] = '{PriceGood}'
and SumOrderedItems = '{SumOrder}'";

            string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
            using (SQLiteConnection conEraceOrderOfSelectedGood = new SQLiteConnection(connectionStringToLocalDB))
            {
                try
                {
                    conEraceOrderOfSelectedGood.Open();

                    SQLiteCommand cmdEraseOrderedGoodFromPriceList = new SQLiteCommand(qUpdatePriceList, conEraceOrderOfSelectedGood);
                    SQLiteCommand cmdDeleteOrderedGoodFromTempOrder = new SQLiteCommand(qDeleteFromTempOrder, conEraceOrderOfSelectedGood);

                    cmdEraseOrderedGoodFromPriceList.ExecuteNonQuery();
                    cmdDeleteOrderedGoodFromTempOrder.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    ToastNotification.ShowError($"Ошибка удаления из заказа: {ex.Message}");
                }
                finally
                {
                    conEraceOrderOfSelectedGood.Close();
                    //loadPriceList(string.Empty);
                    loadTempOrderItems();
                }
            }
        }

        void ShowMePriceWithMarkupPercentForSelectedGood()
        {
            try
            {
                if (_browseMode != PriceBrowseMode.Offers)
                {
                    if (!string.IsNullOrWhiteSpace(_selectedBaseName))
                    {
                        lblSelectedGoodName.Text = _selectedBaseName;
                    }
                    else if (dgvBrowseNames?.SelectedRows.Count > 0 && dgvBrowseNames.Columns.Contains("Наименование"))
                    {
                        lblSelectedGoodName.Text = dgvBrowseNames.SelectedRows[0].Cells["Наименование"]?.Value?.ToString() ?? string.Empty;
                    }
                    else
                    {
                        lblSelectedGoodName.Text = string.Empty;
                    }

                    lblPriceForGood.Text = string.Empty;
                    return;
                }

                var currentRow = dgvPriceList.CurrentRow;
                if (currentRow == null || currentRow.IsNewRow)
                {
                    lblSelectedGoodName.Text = string.Empty;
                    lblPriceForGood.Text = string.Empty;
                    return;
                }

                var nameCell = currentRow.Cells[3].Value;
                lblSelectedGoodName.Text = nameCell == null || nameCell == DBNull.Value
                    ? string.Empty
                    : nameCell.ToString();

                if (!TryReadDouble(currentRow.Cells[5].Value, out var priceForGood))
                {
                    lblPriceForGood.Text = string.Empty;
                    return;
                }

                var markupPercentage = GetMarkupPercentForRow(currentRow);
                _suppressMarkupPersist = true;
                try
                {
                    numericPercent.Value = Math.Max(
                        numericPercent.Minimum,
                        Math.Min(numericPercent.Maximum, markupPercentage));
                }
                finally
                {
                    _suppressMarkupPersist = false;
                }

                lblPriceForGood.Text = $"= {priceForGood:0.##} руб";
            }
            catch
            {
                lblSelectedGoodName.Text = string.Empty;
                lblPriceForGood.Text = string.Empty;
            }
        }

        private static bool TryReadDouble(object value, out double result)
        {
            return TryReadNumber(value, out result);
        }

        private static bool TryReadDecimal(object value, out decimal result)
        {
            return TryReadNumber(value, out result);
        }

        private static bool TryReadInt32(object value, out int result)
        {
            return TryReadNumber(value, out result);
        }

        private static bool TryReadNumber<T>(object value, out T result) where T : struct
        {
            result = default;

            if (value == null || value == DBNull.Value)
            {
                return false;
            }

            if (value is T typedValue)
            {
                result = typedValue;
                return true;
            }

            if (value is decimal decimalValue && typeof(T) == typeof(double))
            {
                result = (T)(object)(double)decimalValue;
                return true;
            }

            if (value is double doubleValue && typeof(T) == typeof(decimal))
            {
                result = (T)(object)(decimal)doubleValue;
                return true;
            }

            if (value is float floatValue && typeof(T) == typeof(double))
            {
                result = (T)(object)(double)floatValue;
                return true;
            }

            if (value is float floatValueDecimal && typeof(T) == typeof(decimal))
            {
                result = (T)(object)(decimal)floatValueDecimal;
                return true;
            }

            var text = NormalizeNumberText(value.ToString());
            if (string.IsNullOrEmpty(text))
            {
                return false;
            }

            if (typeof(T) == typeof(double))
            {
                if (double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out var invariantDouble))
                {
                    result = (T)(object)invariantDouble;
                    return true;
                }

                if (double.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var currentDouble))
                {
                    result = (T)(object)currentDouble;
                    return true;
                }

                if (double.TryParse(text.Replace(',', '.'), NumberStyles.Number, CultureInfo.InvariantCulture, out var normalizedDouble))
                {
                    result = (T)(object)normalizedDouble;
                    return true;
                }

                return false;
            }

            if (typeof(T) == typeof(decimal))
            {
                if (decimal.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out var invariantDecimal))
                {
                    result = (T)(object)invariantDecimal;
                    return true;
                }

                if (decimal.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var currentDecimal))
                {
                    result = (T)(object)currentDecimal;
                    return true;
                }

                if (decimal.TryParse(text.Replace(',', '.'), NumberStyles.Number, CultureInfo.InvariantCulture, out var normalizedDecimal))
                {
                    result = (T)(object)normalizedDecimal;
                    return true;
                }

                return false;
            }

            if (typeof(T) == typeof(int))
            {
                if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var invariantInt))
                {
                    result = (T)(object)invariantInt;
                    return true;
                }

                if (int.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out var currentInt))
                {
                    result = (T)(object)currentInt;
                    return true;
                }
            }

            return false;
        }

        private static string NormalizeNumberText(string text)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return string.Empty;
            }

            text = text.Trim().Replace('\u00A0', ' ').Replace(" ", string.Empty).Replace(',', '.');
            var builder = new StringBuilder();
            var started = false;
            var hasDecimalSeparator = false;

            foreach (var ch in text)
            {
                if (char.IsDigit(ch))
                {
                    builder.Append(ch);
                    started = true;
                    continue;
                }

                if (ch == '.' && started && !hasDecimalSeparator)
                {
                    builder.Append(ch);
                    hasDecimalSeparator = true;
                    continue;
                }

                if (ch == '-' && !started)
                {
                    builder.Append(ch);
                    continue;
                }

                if (started)
                {
                    break;
                }
            }

            return builder.ToString();
        }

        private static bool IsOrderQuantityStartKey(char keyChar)
        {
            return (keyChar >= (char)Keys.D1 && keyChar <= (char)Keys.D9)
                || (keyChar >= (char)Keys.NumPad1 && keyChar <= (char)Keys.NumPad9);
        }

        private void dgvPriceList_SelectionChanged(object sender, EventArgs e)
        {
            if (_suppressPriceListSelectionEvents)
            {
                return;
            }

            try
            {
                SumIWantBuy = string.Empty;

                if (timerForResetSearch.Enabled == true)
                {
                    timerForResetSearch.Enabled = false;
                    timerForResetSearch.Stop();
                }

                ShowMePriceWithMarkupPercentForSelectedGood();
            }
            catch
            {
                lblSelectedGoodName.Text = string.Empty;
                lblPriceForGood.Text = string.Empty;
            }
        }

        

        private void btnImport_Click(object sender, EventArgs e)
        {
            #region импорт из FTP
            string fileName = "0027379.dbf";
            string filePath = @"ftp:\\lboefc91:Oop3OoF4@lbo.protek.ru\session\Rostov_na_Donu\TestFTPFile\";
            string connectionToDbf = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Extended Properties=dBASE IV;User ID=Admin;Password=;";

            using (OleDbConnection oleCon = new OleDbConnection(connectionToDbf))
            {
                var sql = $"select '{DateTime.Now.ToShortDateString()}' as [DatePriceList], '1' as [ConsigneesCode], '2' as [SupplierCode], CODE, PRODUCT, PRODUCER, 'Поставщик 2' as [SupplierName], EXP, VTIMPORT, REGCOST, QUANTITY, COST, COUNTRY, NDS, PRODCOST, '0' as [Marked] from {fileName}";
                OleDbCommand cmd = new OleDbCommand(sql, oleCon);
                oleCon.Open();
                OleDbDataAdapter daDbfReader = new OleDbDataAdapter(cmd);
                DataTable tablePriceFromDbf = new DataTable();
                daDbfReader.Fill(tablePriceFromDbf);


                string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
                using (SQLiteConnection conFillPriceListByNewData = new SQLiteConnection(connectionStringToLocalDB))
                {
                    try
                    {
                        conFillPriceListByNewData.Open();

                        foreach (DataRow dr in tablePriceFromDbf.Rows)
                        {
                            string dbfPriceListDate = dr["DatePriceList"].ToString();
                            string dbfConsigneesCode = dr["ConsigneesCode"].ToString();
                            string dbfCode = dr["CODE"].ToString();
                            string dbfGood = dr["PRODUCT"].ToString().ToLower();
                            string dbfProducer = dr["PRODUCER"].ToString();
                            string dbfSupplierCode = dr["SupplierCode"].ToString();
                            string dbfBestBefore = Convert.ToDateTime(dr["EXP"]).ToShortDateString();
                            string dbfJNVLS = dr["VTIMPORT"].ToString();
                            string dbfPriceReestr = dr["REGCOST"].ToString();
                            string dbfQuantity = dr["QUANTITY"].ToString();
                            string dbfPriceSupplierWithNds = dr["COST"].ToString();
                            string dbfCountry = dr["COUNTRY"].ToString();
                            string dbfNDS = dr["NDS"].ToString();
                            string dbfPriceProducer = dr["PRODCOST"].ToString();
                            string dbfMarked = dr["Marked"].ToString();

                            dbfGood = dbfGood.Replace("'", "");
                            dbfProducer = dbfProducer.Replace("'", "");
                            //dbfSupplierName = dbfSupplierName.Replace("'", "");
                            dbfCountry = dbfCountry.Replace("'", "");

                            string qShowMeLastDateOfPriceList = $"select PriceListDate from PriceListFromSuppliers where ConsigneesCode = '{dbfConsigneesCode}' and CodeSuppliers = '{dbfSupplierCode}'";
                            SQLiteCommand cmdShowMeLastPriceListDate = new SQLiteCommand(qShowMeLastDateOfPriceList, conFillPriceListByNewData);

                            DateTime dateLastPriceListDate = Convert.ToDateTime(cmdShowMeLastPriceListDate.ExecuteScalar().ToString());
                            MessageBox.Show($"{dbfPriceListDate} \n{dateLastPriceListDate}");

                            if (Convert.ToDateTime(dbfPriceListDate) > dateLastPriceListDate)
                            {

                            }

                            string qInsertDataInLocalDB = $@"insert into PriceList (PriceListDate, GoodCode, GoodName, ProducerName, SupplierName, BestBefore, JNVLS, PriceReestr, AvaibleCount, PriceSupplierWithNDS, NDS , Marked)
                                    values ('{dbfPriceListDate}','{dbfCode}','{dbfGood}','{dbfProducer}', '3','{dbfBestBefore}','{dbfJNVLS}','{dbfPriceReestr}', '{dbfQuantity}', '{dbfPriceSupplierWithNds}', '{dbfCountry}', '{dbfNDS}', '{dbfPriceProducer}', '{dbfMarked}')
                                    ";
                            MessageBox.Show(qInsertDataInLocalDB);

                            SQLiteCommand cmdInsertDataInPriceList = new SQLiteCommand(qInsertDataInLocalDB, conFillPriceListByNewData);
                            cmdInsertDataInPriceList.ExecuteNonQuery();
                        }
                    }
                    catch { }
                }
            }

            #endregion


            #region старыйИмпорт из локального файла
            //string fileName = "0027379.dbf";
            //string filePath = @"C:\!ElectroPharmacy\ElectoPharmacyOrder\";
            //string connectionToDbf = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Extended Properties=dBASE IV;User ID=Admin;Password=;";

            //using (OleDbConnection oleCon = new OleDbConnection(connectionToDbf))
            //{
            //    var sql = $"select '{DateTime.Now.ToShortDateString()}' as [DatePriceList], '1' as [ConsigneesCode], '2' as [SupplierCode], CODE, PRODUCT, PRODUCER, 'Поставщик 2' as [SupplierName], EXP, VTIMPORT, REGCOST, QUANTITY, COST, COUNTRY, NDS, PRODCOST, '0' as [Marked] from {fileName}";
            //    OleDbCommand cmd = new OleDbCommand(sql, oleCon);
            //    oleCon.Open();
            //    OleDbDataAdapter daDbfReader = new OleDbDataAdapter(cmd);
            //    DataTable tablePriceFromDbf = new DataTable();
            //    daDbfReader.Fill(tablePriceFromDbf);


            //    string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
            //    using (SQLiteConnection conFillPriceListByNewData = new SQLiteConnection(connectionStringToLocalDB))
            //    {
            //        try
            //        {
            //            conFillPriceListByNewData.Open();

            //            foreach (DataRow dr in tablePriceFromDbf.Rows)
            //            {
            //                string dbfPriceListDate = dr["DatePriceList"].ToString();
            //                string dbfConsigneesCode = dr["ConsigneesCode"].ToString();
            //                string dbfCode = dr["CODE"].ToString();
            //                string dbfGood = dr["PRODUCT"].ToString().ToLower();
            //                string dbfProducer = dr["PRODUCER"].ToString();
            //                string dbfSupplierCode = dr["SupplierCode"].ToString();
            //                string dbfBestBefore = Convert.ToDateTime(dr["EXP"]).ToShortDateString();
            //                string dbfJNVLS = dr["VTIMPORT"].ToString();
            //                string dbfPriceReestr = dr["REGCOST"].ToString();
            //                string dbfQuantity = dr["QUANTITY"].ToString();
            //                string dbfPriceSupplierWithNds = dr["COST"].ToString();
            //                string dbfCountry = dr["COUNTRY"].ToString();
            //                string dbfNDS = dr["NDS"].ToString();
            //                string dbfPriceProducer = dr["PRODCOST"].ToString();
            //                string dbfMarked = dr["Marked"].ToString();

            //                dbfGood = dbfGood.Replace("'", "");
            //                dbfProducer = dbfProducer.Replace("'", "");
            //                //dbfSupplierName = dbfSupplierName.Replace("'", "");
            //                dbfCountry = dbfCountry.Replace("'", "");

            //                string qShowMeLastDateOfPriceList = $"select PriceListDate from PriceListFromSuppliers where ConsigneesCode = '{dbfConsigneesCode}' and CodeSuppliers = '{dbfSupplierCode}'";
            //                SQLiteCommand cmdShowMeLastPriceListDate = new SQLiteCommand(qShowMeLastDateOfPriceList, conFillPriceListByNewData);

            //                DateTime dateLastPriceListDate = Convert.ToDateTime(cmdShowMeLastPriceListDate.ExecuteScalar().ToString());
            //                MessageBox.Show($"{dbfPriceListDate} \n{dateLastPriceListDate}");

            //                if (Convert.ToDateTime(dbfPriceListDate) > dateLastPriceListDate)
            //                {

            //                }

            //                string qInsertDataInLocalDB = $@"insert into PriceList (PriceListDate, GoodCode, GoodName, ProducerName, SupplierName, BestBefore, JNVLS, PriceReestr, AvaibleCount, PriceSupplierWithNDS, NDS , Marked)
            //                values ('{dbfPriceListDate}','{dbfCode}','{dbfGood}','{dbfProducer}', '{dbfSupplierCode}','{dbfBestBefore}','{dbfJNVLS}','{dbfPriceReestr}', '{dbfQuantity}', '{dbfPriceSupplierWithNds}', '{dbfCountry}', '{dbfNDS}', '{dbfPriceProducer}', '{dbfMarked}')
            //                ";
            //                //MessageBox.Show(qInsertDataInLocalDB);

            //                SQLiteCommand cmdInsertDataInPriceList = new SQLiteCommand(qInsertDataInLocalDB, conFillPriceListByNewData);
            //                cmdInsertDataInPriceList.ExecuteNonQuery();
            //            }
            //        }
            //        catch(Exception ex)
            //        {
            //            MessageBox.Show(ex.ToString());
            //        }
            //        finally
            //        {
            //            conFillPriceListByNewData.Close();
            //            loadPriceList(string.Empty);
            //        }
            //    }
            //}
            #endregion
        }

        private void dgvPriceList_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            if (e.RowIndex == this.dgvPriceList.RowCount - 1) return;

        }

        private void txtSearchGoodNameInPriceList_Enter(object sender, EventArgs e)
        {
            dgvPriceList.Focus();
        }

        private void numericPercent_ValueChanged(object sender, EventArgs e)
        {
            if (!_suppressMarkupPersist)
            {
                PersistClientMarkupPercent();
            }

            if (numericPercent.Value != _percentageAsDefault)
            {
                checkUsePercentageAsDefault.Checked = false;
            }

            ShowMePriceWithMarkupPercentForSelectedGood();
        }

        private void PersistClientMarkupPercent()
        {
            var value = numericPercent.Value;
            _percentageAsDefault = value;

            if (!string.IsNullOrWhiteSpace(_WorkWithConsignee))
            {
                try
                {
                    ConsigneeHelper.SetClientMarkupPercent(_WorkWithConsignee, value);
                }
                catch
                {
                    // ignore transient DB errors; value stays in UI
                }
            }

            // Глобальный fallback на случай новой аптеки без своего значения.
            Properties.Settings.Default.ClientMarkupPercent = value;
            Properties.Settings.Default.IntDefaultPercentMarkup =
                Convert.ToInt32(Math.Round(value, MidpointRounding.AwayFromZero));
            Properties.Settings.Default.Save();
        }

        private void UCPriceList_Paint(object sender, PaintEventArgs e)
        {
            if (comboSupplierFilter.DroppedDown)
            {
                return;
            }

            dgvPriceList.Focus();
        }

        private void btnImport_MouseEnter(object sender, EventArgs e)
        {
            //btnImport.Focus();
        }

        private void btnImport_MouseLeave(object sender, EventArgs e)
        {
            //dgvPriceList.Focus()
        }

        private void checkUsePercentageAsDefault_CheckedChanged(object sender, EventArgs e)
        {
            if (checkUsePercentageAsDefault.Checked)
            {
                PersistClientMarkupPercent();
            }
        }

        private void timerForResetSearch_Tick(object sender, EventArgs e)
        {
            txtSearchGoodNameInPriceList.Text = string.Empty;
            GoodsFilter = string.Empty;
            ScheduleBrowseSearchRefresh(immediate: true);
            timerForResetSearch.Enabled = false;
            timerForResetSearch.Stop();
        }

        private void btnMoreInfoAboutGood_Click(object sender, EventArgs e)
        {
            if (dgvPriceList.CurrentRow == null)
            {
                return;
            }

            var goodName = dgvPriceList.CurrentRow.Cells["Наименование"]?.Value?.ToString()
                ?? dgvPriceList.CurrentRow.Cells[2]?.Value?.ToString()
                ?? string.Empty;
            var description = dgvPriceList.CurrentRow.Cells["Описание"]?.Value?.ToString()
                ?? dgvPriceList.CurrentRow.Cells[8]?.Value?.ToString()
                ?? string.Empty;

            var aboutGood = new HelpForms.HF_AboutGood
            {
                goodName = goodName,
                goodDescription = description
            };
            UiThemeHelper.ApplyToControlTree(aboutGood);
            aboutGood.ShowDialog(FindForm());
        }




        //private void dgvPriceList_Paint(object sender, PaintEventArgs e)
        //{
        //    //foreach (DataGridViewRow row in dgvPriceList.Rows)
        //    //{

        //    //    if (row.Cells[8].Value.ToString() != "")
        //    //    {

        //    //        row.DefaultCellStyle.Font = new Font("Segoe UI", 10, FontStyle.Bold);
        //    //    }
        //    //}

        //    //dgvPriceList.Focus();
        //}
    }
}


