﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinFormsApp2
{
    public partial class UserControl3 : UserControl
    {
        private static readonly HttpClient client;
        private List<string> statusFilters = new List<string>();
        private string connectionFilter = null;
        private System.Windows.Forms.Timer refreshTimer;
        private List<JsonElement> currentMachinesData = new List<JsonElement>();

        static UserControl3()
        {
            var handler = new HttpClientHandler
            {
                UseProxy = false
            };
            client = new HttpClient(handler);
        }

        public UserControl3()
        {
            InitializeComponent();
            InitializeControls();

            // Автообновление каждые 30 секунд
            refreshTimer = new System.Windows.Forms.Timer { Interval = 30000 };
            refreshTimer.Tick += async (s, e) => await LoadMonitorData();
            refreshTimer.Start();
        }

        private void InitializeControls()
        {
            this.Dock = DockStyle.Fill;
            this.BackColor = Color.FromArgb(240, 240, 240);

            // Главная панель
            var mainPanel = new Panel
            {
                Dock = DockStyle.Fill,
                Padding = new Padding(20),
                AutoScroll = true
            };
            this.Controls.Add(mainPanel);

            int yPos = 0;

            // Заголовок
            var titleLabel = new Label
            {
                Text = "Монитор торговых автоматов",
                Font = new Font("Segoe UI", 16, FontStyle.Bold),
                ForeColor = Color.FromArgb(33, 150, 243),
                Location = new Point(0, yPos),
                AutoSize = true
            };
            mainPanel.Controls.Add(titleLabel);

            var dateLabel = new Label
            {
                Text = $"данные актуальны на {DateTime.Now:dd.MM.yyyy HH:mm:ss} (UTC+3)",
                Font = new Font("Segoe UI", 9),
                ForeColor = Color.Gray,
                Location = new Point(0, yPos + 30),
                AutoSize = true
            };
            mainPanel.Controls.Add(dateLabel);
            yPos += 60;

            // Панель фильтров
            var filterPanel = new Panel
            {
                Location = new Point(0, yPos),
                Size = new Size(1000, 150),
                BackColor = Color.White,
                BorderStyle = BorderStyle.FixedSingle
            };
            mainPanel.Controls.Add(filterPanel);

            // Общее состояние
            var lblGeneralStatus = new Label
            {
                Text = "Общее состояние",
                Location = new Point(10, 10),
                AutoSize = true,
                Font = new Font("Segoe UI", 9, FontStyle.Bold)
            };
            filterPanel.Controls.Add(lblGeneralStatus);

            btnStatusWorking = CreateFilterButton("●", Color.Green, 10, 35, "working");
            btnStatusBroken = CreateFilterButton("●", Color.Red, 60, 35, "broken");
            btnStatusMaintenance = CreateFilterButton("●", Color.Blue, 110, 35, "maintenance");

            filterPanel.Controls.Add(btnStatusWorking);
            filterPanel.Controls.Add(btnStatusBroken);
            filterPanel.Controls.Add(btnStatusMaintenance);

            // Подключение
            var lblConnection = new Label
            {
                Text = "Подключение",
                Location = new Point(180, 10),
                AutoSize = true,
                Font = new Font("Segoe UI", 9, FontStyle.Bold)
            };
            filterPanel.Controls.Add(lblConnection);

            btnConnectionOnline = CreateFilterButton("МОБ", Color.FromArgb(33, 150, 243), 180, 35, "online", true);
            filterPanel.Controls.Add(btnConnectionOnline);

            // Сортировка
            var lblSort = new Label
            {
                Text = "Сортировка",
                Location = new Point(650, 10),
                AutoSize = true,
                Font = new Font("Segoe UI", 9, FontStyle.Bold)
            };
            filterPanel.Controls.Add(lblSort);

            var cmbSort = new ComboBox
            {
                Location = new Point(650, 35),
                Size = new Size(200, 25),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            cmbSort.Items.AddRange(new[] { "По состоянию ТА", "По названию", "По адресу" });
            cmbSort.SelectedIndex = 0;
            filterPanel.Controls.Add(cmbSort);

            // Кнопки Применить и Очистить
            var btnApply = new Button
            {
                Text = "Применить",
                Location = new Point(10, 100),
                Size = new Size(100, 30),
                BackColor = Color.FromArgb(33, 150, 243),
                ForeColor = Color.White,
                FlatStyle = FlatStyle.Flat
            };
            btnApply.Click += async (s, e) => await LoadMonitorData();
            filterPanel.Controls.Add(btnApply);

            var btnClear = new Button
            {
                Text = "Очистить",
                Location = new Point(120, 100),
                Size = new Size(100, 30),
                FlatStyle = FlatStyle.Flat
            };
            btnClear.Click += async (s, e) =>
            {
                statusFilters.Clear();
                connectionFilter = null;
                btnStatusWorking.BackColor = SystemColors.Control;
                btnStatusBroken.BackColor = SystemColors.Control;
                btnStatusMaintenance.BackColor = SystemColors.Control;
                btnConnectionOnline.BackColor = SystemColors.Control;
                await LoadMonitorData();
            };
            filterPanel.Controls.Add(btnClear);

            yPos += 160;

            // Информационная панель (итого автоматов, денег)
            lblInfo = new Label
            {
                Text = "Загрузка...",
                Location = new Point(0, yPos),
                Size = new Size(1000, 30),
                Font = new Font("Segoe UI", 10, FontStyle.Bold),
                BackColor = Color.White,
                TextAlign = ContentAlignment.MiddleLeft,
                Padding = new Padding(10, 0, 0, 0)
            };
            mainPanel.Controls.Add(lblInfo);
            yPos += 40;

            // DataGridView для отображения автоматов
            dataGridView1 = new DataGridView
            {
                Location = new Point(0, yPos),
                Size = new Size(1200, 400),
                AutoGenerateColumns = false,
                AllowUserToAddRows = false,
                ReadOnly = true,
                SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                MultiSelect = false,
                BackgroundColor = Color.White,
                BorderStyle = BorderStyle.Fixed3D,
                RowHeadersVisible = false,
                AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None,
                RowTemplate = { Height = 80 }
            };
            mainPanel.Controls.Add(dataGridView1);

            SetupDataGridView();

            // Метка "Нет данных"
            lblNoData = new Label
            {
                Text = "Нет активных торговых автоматов, соответствующих заданному фильтру",
                Location = new Point(0, yPos + 150),
                Size = new Size(1000, 50),
                Font = new Font("Segoe UI", 12),
                ForeColor = Color.Gray,
                TextAlign = ContentAlignment.MiddleCenter,
                Visible = false
            };
            mainPanel.Controls.Add(lblNoData);
        }

        private Button CreateFilterButton(string text, Color color, int x, int y, string filterValue, bool isConnection = false)
        {
            var btn = new Button
            {
                Text = text,
                Location = new Point(x, y),
                Size = new Size(40, 40),
                ForeColor = color,
                Font = new Font("Segoe UI", 16, FontStyle.Bold),
                FlatStyle = FlatStyle.Flat,
                Tag = filterValue
            };

            btn.Click += async (s, e) =>
            {
                if (isConnection)
                {
                    if (connectionFilter == filterValue)
                    {
                        connectionFilter = null;
                        btn.BackColor = SystemColors.Control;
                    }
                    else
                    {
                        connectionFilter = filterValue;
                        btn.BackColor = Color.LightBlue;
                    }
                }
                else
                {
                    if (statusFilters.Contains(filterValue))
                    {
                        statusFilters.Remove(filterValue);
                        btn.BackColor = SystemColors.Control;
                    }
                    else
                    {
                        statusFilters.Add(filterValue);
                        btn.BackColor = Color.LightGray;
                    }
                }
            };

            return btn;
        }

        private void SetupDataGridView()
        {
            dataGridView1.Columns.Clear();

            // № (ID)
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "id",
                HeaderText = "№",
                Width = 40,
                DataPropertyName = "id"
            });

            // ТП (Торговая точка)
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "name",
                HeaderText = "ТП",
                Width = 200,
                DataPropertyName = "name"
            });

            // Связь
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "connection",
                HeaderText = "Связь",
                Width = 80,
                DataPropertyName = "connection_display"
            });

            // Загрузка
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "loading",
                HeaderText = "Загрузка",
                Width = 150,
                DataPropertyName = "loading_display"
            });

            // Денежные средства
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "money",
                HeaderText = "Денежные средства",
                Width = 150,
                DataPropertyName = "money_display"
            });

            // События
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "events",
                HeaderText = "События",
                Width = 120,
                DataPropertyName = "events_display"
            });

            // Оборудование
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "equipment",
                HeaderText = "Оборудование",
                Width = 150,
                DataPropertyName = "equipment_display"
            });

            // Информация
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                Name = "info",
                HeaderText = "Информация",
                Width = 180,
                DataPropertyName = "info_display"
            });

            // Включаем перенос текста для многострочных ячеек
            dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;

            // Обработчик для установки Tag после привязки данных
            dataGridView1.DataBindingComplete += DataGridView1_DataBindingComplete;
        }

        private void DataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            // Устанавливаем Tag для каждой строки ПОСЛЕ привязки данных
            for (int i = 0; i < dataGridView1.Rows.Count && i < currentMachinesData.Count; i++)
            {
                dataGridView1.Rows[i].Tag = currentMachinesData[i];
            }
        }

        private async void UserControl3_Load(object sender, EventArgs e)
        {
            await LoadMonitorData();
        }

        private async Task LoadMonitorData()
        {
            try
            {
                lblInfo.Text = "Загрузка данных...";
                lblNoData.Visible = false;

                var url = "http://127.0.0.1:8000/monitor/vending-machines?";

                // Фильтр по статусу - отправляем только первый выбранный
                if (statusFilters.Count > 0)
                {
                    url += $"status={statusFilters[0]}&";
                }

                if (connectionFilter != null)
                {
                    url += $"connection_type={connectionFilter}&";
                }

                System.Diagnostics.Debug.WriteLine($"Запрос: {url}");

                var response = await client.GetAsync(url);
                var responseText = await response.Content.ReadAsStringAsync();

                System.Diagnostics.Debug.WriteLine($"Ответ: {responseText}");

                if (response.IsSuccessStatusCode)
                {
                    var result = JsonSerializer.Deserialize<JsonElement>(responseText);

                    var total = result.GetProperty("total").GetInt32();
                    var working = result.GetProperty("working").GetInt32();
                    var broken = result.GetProperty("broken").GetInt32();
                    var maintenance = result.GetProperty("maintenance").GetInt32();
                    var totalMoney = result.GetProperty("total_money").GetDouble();
                    var machines = result.GetProperty("machines").EnumerateArray().ToList();

                    // Сохраняем данные для последующего использования
                    currentMachinesData = machines;

                    // Обновляем информационную строку
                    lblInfo.Text = $"Итого автоматов: {total} ({working}/{broken}/{maintenance}). " +
                                   $"Денег в автоматах: {totalMoney:N0} р. (сдача)";

                    if (total == 0)
                    {
                        lblNoData.Visible = true;
                        dataGridView1.DataSource = null;
                        currentMachinesData.Clear();
                        return;
                    }

                    // Создаем таблицу для отображения
                    var dataTable = new DataTable();
                    dataTable.Columns.Add("id", typeof(int));
                    dataTable.Columns.Add("name", typeof(string));
                    dataTable.Columns.Add("connection_display", typeof(string));
                    dataTable.Columns.Add("loading_display", typeof(string));
                    dataTable.Columns.Add("money_display", typeof(string));
                    dataTable.Columns.Add("events_display", typeof(string));
                    dataTable.Columns.Add("equipment_display", typeof(string));
                    dataTable.Columns.Add("info_display", typeof(string));

                    foreach (var machine in machines)
                    {
                        var row = dataTable.NewRow();

                        row["id"] = machine.GetProperty("id").GetInt32();

                        var name = machine.GetProperty("name").GetString();
                        var address = machine.GetProperty("address").GetString();
                        row["name"] = $"{name}\n{address}";

                        var connection = machine.GetProperty("connection");
                        var connStatus = connection.GetProperty("status").GetString();
                        var signalStrength = connection.GetProperty("signal_strength").GetInt32();
                        row["connection_display"] = connStatus == "online" ? $"Онлайн ({signalStrength}/5)" : "Офлайн";

                        var loading = machine.GetProperty("loading");
                        row["loading_display"] = $"Кофе: {loading.GetProperty("coffee").GetInt32()}%\n" +
                                                  $"Молоко: {loading.GetProperty("milk").GetInt32()}%\n" +
                                                  $"Стаканы: {loading.GetProperty("cups").GetInt32()} шт";

                        var money = machine.GetProperty("money");
                        var totalMoneyMachine = money.GetProperty("total").GetInt32();
                        row["money_display"] = $"Всего: {totalMoneyMachine} р.\n" +
                                                $"Монеты: {money.GetProperty("coins").GetInt32()} р.\n" +
                                                $"Купюры: {money.GetProperty("bills").GetInt32()} р.";

                        var events = machine.GetProperty("events").EnumerateArray().ToList();
                        if (events.Count > 0)
                        {
                            var evt = events[0];
                            row["events_display"] = $"{evt.GetProperty("time").GetString()}\n" +
                                                     $"Продаж: {evt.GetProperty("count").GetInt32()}";
                        }
                        else
                        {
                            row["events_display"] = "Нет событий";
                        }

                        var equipment = machine.GetProperty("equipment");
                        var equipList = new List<string>();
                        if (equipment.GetProperty("coffee_maker").GetBoolean()) equipList.Add("Кофемашина");
                        if (equipment.GetProperty("payment_terminal").GetBoolean()) equipList.Add("Терминал");
                        if (equipment.GetProperty("cooling_system").GetBoolean()) equipList.Add("Охлаждение");
                        row["equipment_display"] = string.Join("\n", equipList);

                        var statuses = machine.GetProperty("statuses").EnumerateArray().ToList();
                        if (statuses.Count > 0)
                        {
                            row["info_display"] = string.Join("\n", statuses.Take(3).Select(s => s.GetProperty("text").GetString()));
                        }
                        else
                        {
                            row["info_display"] = "Все в порядке";
                        }

                        dataTable.Rows.Add(row);
                    }

                    dataGridView1.DataSource = dataTable;
                }
                else
                {
                    MessageBox.Show($"Ошибка загрузки данных: {responseText}", "Ошибка");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Ошибка: {ex.Message}\n{ex.StackTrace}", "Ошибка");
                System.Diagnostics.Debug.WriteLine($"Ошибка: {ex.Message}\n{ex.StackTrace}");
            }
        }

        protected override void OnHandleDestroyed(EventArgs e)
        {
            refreshTimer?.Stop();
            refreshTimer?.Dispose();
            base.OnHandleDestroyed(e);
        }

        // Поля формы
        private Button btnStatusWorking, btnStatusBroken, btnStatusMaintenance;
        private Button btnConnectionOnline;
        private Label lblInfo, lblNoData;
        private DataGridView dataGridView1;
    }
}