using Npgsql;
using TravelAgencyWinForms.Data;
using TravelAgencyWinForms.Models;
using TravelAgencyWinForms.Services;
using TravelAgencyWinForms.Utils;

namespace TravelAgencyWinForms.Forms;

public partial class MainForm : Form
{
    private Button? _activeMenuButton;

    public MainForm()
    {
        InitializeComponent();
        ApplyStyle();
        LoadBanner();
        BuildMenu();
        LoadDashboard();
        FormClosing += (_, _) => CurrentUser.Clear();
    }

    private void ApplyStyle()
    {
        AppTheme.ApplyForm(this);

        menuPanel.BackColor = Color.FromArgb(76, 150, 138);
        menuHeaderPanel.BackColor = Color.FromArgb(76, 150, 138);
        menuItemsPanel.BackColor = Color.FromArgb(76, 150, 138);

        appTitleLabel.ForeColor = Color.White;
        modeLabel.ForeColor = Color.FromArgb(227, 247, 242);
        loginLabel.ForeColor = Color.FromArgb(227, 247, 242);
        userNameLabel.ForeColor = Color.White;

        contentPanel.BackColor = AppTheme.Background;
        heroPanel.BackColor = AppTheme.Surface;
        heroTitleLabel.ForeColor = AppTheme.Text;
        heroSubtitleLabel.ForeColor = AppTheme.Muted;

        upcomingGroupBox.ForeColor = AppTheme.Text;
        bookingsGroupBox.ForeColor = AppTheme.Text;

        AppTheme.StyleGrid(upcomingGrid);
        AppTheme.StyleGrid(bookingsGrid);

        appTitleLabel.Text = "Турагентство";
        modeLabel.Text = CurrentUser.IsAdmin ? "Панель администратора" : "Личный кабинет клиента";
        loginLabel.Text = CurrentUser.Login;
        userNameLabel.Text = string.IsNullOrWhiteSpace(CurrentUser.ClientName) ? CurrentUser.Login : CurrentUser.ClientName;
        heroTitleLabel.Text = CurrentUser.IsAdmin ? "Панель управления" : "Личный кабинет";
        heroSubtitleLabel.Text = CurrentUser.IsAdmin
            ? "Быстрый доступ к данным, отчётам и журналу операций"
            : "Просмотр туров, расписания и своих бронирований";
    }

    private void LoadBanner()
    {
        var image = AppTheme.LoadImage("main_dashboard_banner.png");
        if (image != null)
            bannerPictureBox.Image = image;
    }

    private void BuildMenu()
    {
        menuItemsPanel.Controls.Clear();

        AddMenuButton("Главная", LoadDashboard, true);

        if (CurrentUser.IsAdmin)
        {
            AddSection("Данные");
            AddMenuButton("Клиенты", () => OpenTable(EntityConfigs.Clients, true));
            AddMenuButton("Должности", () => OpenTable(EntityConfigs.Positions, true));
            AddMenuButton("Сотрудники", () => OpenTable(EntityConfigs.Employees, true));
            AddMenuButton("Города", () => OpenTable(EntityConfigs.Cities, true));
            AddMenuButton("Туры", () => OpenTable(EntityConfigs.Tours, true));
            AddMenuButton("Маршруты", () => OpenTable(EntityConfigs.TourCities, true));
            AddMenuButton("Расписание", () => OpenTable(EntityConfigs.TourList, true));
            AddMenuButton("Бронирования", () => OpenTable(EntityConfigs.Bookings, true));

            AddSection("Отчёты");
            AddMenuButton("Сводка", () => new ReportsForm().ShowDialog(this));
            AddMenuButton("Просроченные", () => OpenTable(EntityConfigs.OverdueView, false));
            AddMenuButton("Журнал", () => OpenTable(EntityConfigs.AuditLog, false));

            AddSection("Сервис");
            AddMenuButton("Пользователи", () => OpenTable(EntityConfigs.AppUsers, true));
        }
        else
        {
            AddSection("Мои данные");
            AddMenuButton("Личные данные", () => OpenTable(EntityConfigs.ClientDetails, false));
            AddMenuButton("Бронирования", () => OpenTable(EntityConfigs.UserBookings, false));
            AddMenuButton("Просроченные", () => OpenTable(EntityConfigs.UserOverdue, false));

            AddSection("Справочники");
            AddMenuButton("Города", () => OpenTable(EntityConfigs.Cities, false));
            AddMenuButton("Туры", () => OpenTable(EntityConfigs.Tours, false));
            AddMenuButton("Расписание", () => OpenTable(EntityConfigs.TourScheduleView, false));
            AddMenuButton("Отчёты", () => new ReportsForm().ShowDialog(this));
        }

        AddSection(string.Empty);
        AddMenuButton("Выход", Close);
    }

    private void AddMenuButton(string text, Action action, bool selected = false)
    {
        var button = new Button
        {
            Text = text,
            Width = 220,
            Height = 38,
            Margin = new Padding(0, 3, 0, 3)
        };

        AppTheme.StyleMenuButton(button);

        if (selected)
            SetActiveMenuButton(button);

        button.Click += (_, _) =>
        {
            SetActiveMenuButton(button);
            action();
        };

        menuItemsPanel.Controls.Add(button);
    }

    private void SetActiveMenuButton(Button button)
    {
        if (_activeMenuButton != null)
            AppTheme.StyleMenuButton(_activeMenuButton);

        _activeMenuButton = button;
        button.BackColor = Color.FromArgb(98, 181, 166);
    }

    private void AddSection(string text)
    {
        if (string.IsNullOrWhiteSpace(text))
        {
            menuItemsPanel.Controls.Add(new Panel { Height = 12, Width = 220 });
            return;
        }

        var label = new Label
        {
            Text = text.ToUpperInvariant(),
            Width = 220,
            Height = 26,
            ForeColor = Color.FromArgb(216, 243, 237),
            Font = new Font("Segoe UI Semibold", 8.5F),
            Margin = new Padding(0, 14, 0, 2)
        };

        menuItemsPanel.Controls.Add(label);
    }

    private void OpenTable(EntityConfig config, bool canEdit)
    {
        using var form = new TableEditorForm(config, canEdit);
        form.ShowDialog(this);
        LoadDashboard();
    }

    private void LoadDashboard()
    {
        LoadStats();
        LoadDashboardTables();
    }

    private void LoadStats()
    {
        statsPanel.Controls.Clear();

        foreach (var card in LoadStatCards())
            statsPanel.Controls.Add(card);
    }

    private IEnumerable<Control> LoadStatCards()
    {
        if (CurrentUser.IsAdmin)
        {
            yield return AppTheme.CreateCard("Клиенты", ScalarInt("SELECT COUNT(*) FROM clients"));
            yield return AppTheme.CreateCard("Сотрудники", ScalarInt("SELECT COUNT(*) FROM employees"));
            yield return AppTheme.CreateCard("Туры", ScalarInt("SELECT COUNT(*) FROM tours"));
            yield return AppTheme.CreateCard("Бронирования", ScalarInt("SELECT COUNT(*) FROM bookings"));
            yield return AppTheme.CreateCard("Просроченные", ScalarInt("SELECT COUNT(*) FROM v_overdue_client_bookings"));
        }
        else
        {
            yield return AppTheme.CreateCard("Бронирования", ScalarInt("SELECT COUNT(*) FROM bookings WHERE client_id = @client_id", new NpgsqlParameter("client_id", CurrentUser.ClientId ?? -1)));
            yield return AppTheme.CreateCard("Просроченные", ScalarInt("SELECT COUNT(*) FROM v_overdue_client_bookings WHERE client_id = @client_id", new NpgsqlParameter("client_id", CurrentUser.ClientId ?? -1)));
            yield return AppTheme.CreateCard("Туры", ScalarInt("SELECT COUNT(*) FROM tours"));
            yield return AppTheme.CreateCard("Рейсы", ScalarInt("SELECT COUNT(*) FROM tour_list WHERE start_date >= CURRENT_DATE"), "будущие даты");
        }
    }

    private void LoadDashboardTables()
    {
        upcomingGrid.DataSource = Db.Query(@"
SELECT
    tour_name AS ""Тур"",
    start_date AS ""Дата начала"",
    end_date AS ""Дата окончания"",
    duration_days AS ""Длительность"",
    price AS ""Стоимость""
FROM v_tour_schedule
WHERE start_date >= CURRENT_DATE
ORDER BY start_date
LIMIT 8;");

        bookingsGrid.DataSource = CurrentUser.IsAdmin
            ? Db.Query(@"
SELECT
    booking_number AS ""Номер"",
    client_name AS ""Клиент"",
    employee_name AS ""Сотрудник"",
    tour_name AS ""Тур"",
    booking_date AS ""Дата оформления"",
    status AS ""Статус""
FROM v_booking_details
ORDER BY booking_date DESC, booking_id DESC
LIMIT 8;")
            : Db.Query(@"
SELECT
    booking_number AS ""Номер"",
    client_name AS ""Клиент"",
    tour_name AS ""Тур"",
    booking_date AS ""Дата оформления"",
    status AS ""Статус""
FROM v_booking_details
WHERE client_id = @client_id
ORDER BY booking_date DESC, booking_id DESC
LIMIT 8;", new NpgsqlParameter("client_id", CurrentUser.ClientId ?? -1));

        AppTheme.StyleGrid(upcomingGrid);
        AppTheme.StyleGrid(bookingsGrid);
        PresentationHelper.ApplyHeaders(upcomingGrid);
        PresentationHelper.ApplyHeaders(bookingsGrid);
    }

    private static string ScalarInt(string sql, params NpgsqlParameter[] parameters)
    {
        var result = Db.Scalar(sql, parameters);
        return Convert.ToInt32(result ?? 0).ToString();
    }
}
