using System;
using System.Data;
using System.Windows;
using Npgsql;

namespace ych
{
    public partial class MainWindow : Window
    {
        private readonly string _connectionString =
    "Host=edu-pg.itiscaf.ru;Port=5432;Database=dbwork;" +
    "Username=gaukov_dp;Password=4K62ebY72%h;";

        private readonly string _userRole;
        private string _currentTable = "";
        private DataTable _dataTable = new DataTable();

        public MainWindow(string userRole)
        {
            InitializeComponent();
            _userRole = userRole;
            ApplySecurity();
        }

        private void ApplySecurity()
        {
            if (_userRole == "admin")
            {
                RoleLabel.Text = "Роль: Администратор";
            }
            else if (_userRole == "teacher")
            {
                RoleLabel.Text = "Роль: Преподаватель";
                BtnDelete.IsEnabled = false;
                BtnDelete.Opacity = 0.4;
            }
            else if (_userRole == "student")
            {
                RoleLabel.Text = "Роль: Студент";
                BtnAdd.Visibility = Visibility.Collapsed;
                BtnDelete.Visibility = Visibility.Collapsed;
                BtnStudents.Visibility = Visibility.Collapsed;
                BtnTeachers.Visibility = Visibility.Collapsed;
                BtnGroups.Visibility = Visibility.Collapsed;
            }
        }

        private void LoadTable(string table, string title, string query = "")
        {
            _currentTable = table;
            TitleText.Text = title;

            bool isTable = string.IsNullOrEmpty(query);
            bool canEdit = _userRole == "admin" || _userRole == "teacher";

            ActionPanel.Visibility = (isTable && canEdit)
                ? Visibility.Visible : Visibility.Collapsed;

            string sql = isTable
                ? string.Format("SELECT * FROM {0} ORDER BY 1", table)
                : query;

            try
            {
                using (var conn = new NpgsqlConnection(_connectionString))
                {
                    conn.Open();
                    using (var adapter = new NpgsqlDataAdapter(sql, conn))
                    {
                        _dataTable = new DataTable();
                        adapter.Fill(_dataTable);
                        MainGrid.IsReadOnly = (_userRole == "student" || !isTable);
                        MainGrid.ItemsSource = _dataTable.DefaultView;
                        SetStatus(string.Format("Загружено строк: {0}", _dataTable.Rows.Count));
                    }
                }
            }
            catch (Exception ex)
            {
                ShowError(ex.Message);
            }
        }

        private void ShowStudents(object s, RoutedEventArgs e)
        {
            LoadTable("students", "Студенты");
        }

        private void ShowSubjects(object s, RoutedEventArgs e)
        {
            LoadTable("subjects", "Предметы");
        }

        private void ShowTeachers(object s, RoutedEventArgs e)
        {
            LoadTable("teachers", "Преподаватели");
        }

        private void ShowGroups(object s, RoutedEventArgs e)
        {
            LoadTable("groups", "Группы");
        }

        private void ShowGrades(object s, RoutedEventArgs e)
        {
            LoadTable("grades", "Оценки");
        }

        private void ShowFailing(object s, RoutedEventArgs e)
        {
            LoadTable("", "Неуспевающие студенты", @"
                SELECT s.last_name   AS фамилия,
                       s.first_name  AS имя,
                       gr.id         AS группа,
                       sub.title     AS предмет,
                       g.grade       AS оценка
                FROM grades g
                JOIN students s   ON g.record_book_id = s.record_book_id
                JOIN groups   gr  ON s.group_id        = gr.id
                JOIN subjects sub ON g.subject_id      = sub.id
                WHERE g.grade = 2
                ORDER BY sub.title, s.last_name");
        }

        private void ShowAvg(object s, RoutedEventArgs e)
        {
            LoadTable("", "Средний балл по студентам", @"
                SELECT s.last_name                     AS фамилия,
                       s.first_name                    AS имя,
                       ROUND(AVG(g.grade::NUMERIC), 2) AS средний_балл
                FROM grades g
                JOIN students s ON g.record_book_id = s.record_book_id
                GROUP BY s.record_book_id, s.last_name, s.first_name
                ORDER BY средний_балл DESC");
        }

        private void AddRow(object s, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(_currentTable)) return;
            _dataTable.Rows.Add(_dataTable.NewRow());
            MainGrid.ScrollIntoView(MainGrid.Items[MainGrid.Items.Count - 1]);
            SetStatus("Заполните новую строку и нажмите Сохранить");
        }

        private void SaveRow(object s, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(_currentTable)) return;

            // 1. Проверяем, есть ли пустые строки
            foreach (DataRow row in _dataTable.Rows)
            {
                // RowState.Added означает, что строка новая и еще не сохранена
                if (row.RowState == DataRowState.Added)
                {
                    bool isEmpty = true;
                    // Проходим по всем колонкам строки
                    foreach (DataColumn col in _dataTable.Columns)
                    {
                        // Если хоть одно поле не пустое и не DBNull - строка заполнена
                        if (row[col] != DBNull.Value && !string.IsNullOrEmpty(row[col].ToString()))
                        {
                            isEmpty = false;
                            break;
                        }
                    }

                    // Если строка пустая - удаляем её, чтобы не вызывать ошибку БД
                    if (isEmpty)
                    {
                        row.Delete();
                    }
                }
            }

            // Если после чистки ничего не осталось для сохранения - выходим
            if (_dataTable.GetChanges() == null)
            {
                SetStatus("Пустые строки удалены. Заполните данные.");
                return;
            }

            try
            {
                using (var conn = new NpgsqlConnection(_connectionString))
                {
                    conn.Open();
                    using (var adapter = new NpgsqlDataAdapter(
                        $"SELECT * FROM gaukov_dp.{_currentTable} WHERE 1=0", conn))
                    {
                        using (var builder = new NpgsqlCommandBuilder(adapter))
                        {
                            adapter.Update(_dataTable);
                            _dataTable.AcceptChanges();
                            SetStatus("Данные успешно сохранены");
                            LoadTable(_currentTable, TitleText.Text);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ShowError(ex.Message);
            }
        }

        private void DeleteRow(object s, RoutedEventArgs e)
        {
            if (_userRole != "admin")
            {
                ShowError("Недостаточно прав для удаления");
                return;
            }

            if (!(MainGrid.SelectedItem is DataRowView row)) return;

            var result = MessageBox.Show(
                "Удалить выбранную запись? (Все связанные оценки тоже будут удалены)",
                "Подтверждение",
                MessageBoxButton.YesNo, MessageBoxImage.Warning);

            if (result != MessageBoxResult.Yes) return;

            try
            {
                // Получаем ID студента (предполагаем, что это первая колонка или record_book_id)
                // Тебе нужно знать точное имя колонки ID в таблице students
                var studentId = row["record_book_id"]; // Или row["id"], посмотри в таблице

                using (var conn = new NpgsqlConnection(_connectionString))
                {
                    conn.Open();
                    using (var transaction = conn.BeginTransaction())
                    {
                        try
                        {
                            // 1. Сначала удаляем оценки студента
                            string deleteGradesSql = "DELETE FROM gaukov_dp.grades WHERE record_book_id = @id";
                            using (var cmd = new NpgsqlCommand(deleteGradesSql, conn, transaction))
                            {
                                cmd.Parameters.AddWithValue("id", studentId);
                                cmd.ExecuteNonQuery();
                            }

                            // 2. Теперь удаляем самого студента через DataTable
                            row.Row.Delete();

                            using (var adapter = new NpgsqlDataAdapter(
                                $"SELECT * FROM gaukov_dp.{_currentTable} WHERE 1=0", conn))
                            {
                                adapter.SelectCommand.Transaction = transaction;
                                using (var builder = new NpgsqlCommandBuilder(adapter))
                                {
                                    adapter.Update(_dataTable);
                                }
                            }

                            transaction.Commit();
                            _dataTable.AcceptChanges();
                            SetStatus("Запись и связанные данные удалены");
                        }
                        catch
                        {
                            transaction.Rollback();
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                row.Row.RejectChanges();
                ShowError(ex.Message);
            }
        }

        private void Logout_Click(object s, RoutedEventArgs e)
        {
            var login = new LoginWindow();
            login.Show();
            Close();
        }

        private void SetStatus(string msg)
        {
            StatusText.Text = msg;
        }

        private void ShowError(string msg)
        {
            StatusText.Text = string.Format("Ошибка: {0}", msg);
            MessageBox.Show(msg, "Ошибка",
                MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }
}