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

namespace ZhkhApp
{
    public partial class EditForm : Form
    {
        private string tableName;
        private int? editId;

        public EditForm(string table, int? id)
        {
            tableName = table;
            editId = id;
            InitializeComponent();
            CreateDynamicFields();
            LoadComboBoxes();

            if (editId.HasValue)
            {
                this.Text = $"Редактирование: {GetRussianName()}";
                LoadDataForEdit();
            }
            else
            {
                this.Text = $"Добавление: {GetRussianName()}";
            }
        }

        private string GetRussianName()
        {
            switch (tableName)
            {
                case "apartments": return "Квартира";
                case "persons": return "Человек";
                case "receipts": return "Квитанция";
                case "users": return "Пользователь";
                case "payments": return "Платёж";
                default: return tableName;
            }
        }

        private string GetPrimaryKeyName(string table)
        {
            switch (table)
            {
                case "apartments": return "apartment_id";
                case "persons": return "person_id";
                case "receipts": return "receipt_id";
                case "payments": return "payment_id";
                case "users": return "user_id";
                default: return table + "_id";
            }
        }

        private void CreateDynamicFields()
        {
            int y = 30;

            if (tableName == "apartments")
            {
                AddField("Номер квартиры:", ref y, out txtNumber);
                AddField("Площадь (кв.м):", ref y, out txtArea);
                AddField("Кол-во проживающих:", ref y, out txtResidentCount);
                AddCombo("Адрес:", ref y, out cbAddress);
            }
            else if (tableName == "persons")
            {
                AddField("Фамилия:", ref y, out txtLastName);
                AddField("Имя:", ref y, out txtFirstName);
                AddField("Отчество:", ref y, out txtMiddleName);
            }
            else if (tableName == "receipts")
            {
                AddCombo("Квартира:", ref y, out cbApartment);
                AddField("Месяц (1-12):", ref y, out txtMonth);
                AddField("Год:", ref y, out txtYear);
                AddField("Пени (руб):", ref y, out txtPenalty);
                AddField("Сумма (руб):", ref y, out txtTotalSum);
                AddCombo("Выписано на:", ref y, out cbPerson);
            }
            else if (tableName == "users")
            {
                AddField("Логин:", ref y, out txtUsername);
                AddField("Пароль:", ref y, out txtPassword);
                AddCombo("Роль:", ref y, out cbRole);
                AddCombo("Связать с человеком:", ref y, out cbPerson);
            }
            else if (tableName == "payments")
            {
                AddCombo("Квитанция:", ref y, out cbReceipt);
                AddField("Сумма оплаты:", ref y, out txtAmount);
                AddCombo("Способ оплаты:", ref y, out cbPaymentMethod);
            }
        }

        private void AddField(string labelText, ref int y, out TextBox tb)
        {
            Label lbl = new Label()
            {
                Text = labelText,
                Location = new System.Drawing.Point(20, y),
                Size = new System.Drawing.Size(150, 25)
            };
            tb = new TextBox()
            {
                Location = new System.Drawing.Point(180, y),
                Size = new System.Drawing.Size(200, 25)
            };
            this.Controls.Add(lbl);
            this.Controls.Add(tb);
            y += 40;
        }

        private void AddCombo(string labelText, ref int y, out ComboBox cb)
        {
            Label lbl = new Label()
            {
                Text = labelText,
                Location = new System.Drawing.Point(20, y),
                Size = new System.Drawing.Size(150, 25)
            };
            cb = new ComboBox()
            {
                Location = new System.Drawing.Point(180, y),
                Size = new System.Drawing.Size(200, 28),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            this.Controls.Add(lbl);
            this.Controls.Add(cb);
            y += 40;
        }

        private void LoadComboBoxes()
        {
            try
            {
                if (cbAddress != null)
                {
                    using (var conn = new NpgsqlConnection(MainForm.ConnectionString))
                    {
                        conn.Open();
                        string query = "SELECT address_id, street_name || ', д.' || house_number as addr FROM addresses JOIN streets ON addresses.street_id = streets.street_id";
                        var da = new NpgsqlDataAdapter(query, conn);
                        DataTable dt = new DataTable();
                        da.Fill(dt);
                        cbAddress.DisplayMember = "addr";
                        cbAddress.ValueMember = "address_id";
                        cbAddress.DataSource = dt;
                    }
                }
                if (cbApartment != null)
                {
                    using (var conn = new NpgsqlConnection(MainForm.ConnectionString))
                    {
                        conn.Open();
                        var da = new NpgsqlDataAdapter("SELECT apartment_id, apt_number FROM apartments", conn);
                        DataTable dt = new DataTable();
                        da.Fill(dt);
                        cbApartment.DisplayMember = "apt_number";
                        cbApartment.ValueMember = "apartment_id";
                        cbApartment.DataSource = dt;
                    }
                }
                if (cbPerson != null)
                {
                    using (var conn = new NpgsqlConnection(MainForm.ConnectionString))
                    {
                        conn.Open();
                        var da = new NpgsqlDataAdapter("SELECT person_id, last_name || ' ' || first_name as name FROM persons", conn);
                        DataTable dt = new DataTable();
                        da.Fill(dt);
                        cbPerson.DisplayMember = "name";
                        cbPerson.ValueMember = "person_id";
                        cbPerson.DataSource = dt;
                    }
                }
                if (cbRole != null)
                {
                    using (var conn = new NpgsqlConnection(MainForm.ConnectionString))
                    {
                        conn.Open();
                        var da = new NpgsqlDataAdapter("SELECT role_id, role_name FROM roles", conn);
                        DataTable dt = new DataTable();
                        da.Fill(dt);
                        cbRole.DisplayMember = "role_name";
                        cbRole.ValueMember = "role_id";
                        cbRole.DataSource = dt;
                    }
                }
                if (cbReceipt != null)
                {
                    using (var conn = new NpgsqlConnection(MainForm.ConnectionString))
                    {
                        conn.Open();
                        string query = @"
                            SELECT r.receipt_id, 
                                   '№' || r.receipt_id || ' (кв.' || a.apt_number || ')' as receipt_info
                            FROM receipts r
                            JOIN apartments a ON r.apartment_id = a.apartment_id
                            ORDER BY r.receipt_id";
                        var da = new NpgsqlDataAdapter(query, conn);
                        DataTable dt = new DataTable();
                        da.Fill(dt);
                        cbReceipt.DisplayMember = "receipt_info";
                        cbReceipt.ValueMember = "receipt_id";
                        cbReceipt.DataSource = dt;
                    }
                }
                if (cbPaymentMethod != null)
                {
                    cbPaymentMethod.Items.Clear();
                    cbPaymentMethod.Items.AddRange(new[] { "Банковская карта", "Наличные (в кассе)", "Онлайн-кошелёк" });
                    cbPaymentMethod.DropDownStyle = ComboBoxStyle.DropDownList;
                    cbPaymentMethod.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Ошибка загрузки справочников: {ex.Message}");
            }
        }

        private void LoadDataForEdit()
        {
            try
            {
                string pkName = GetPrimaryKeyName(tableName);
                using (var conn = new NpgsqlConnection(MainForm.ConnectionString))
                {
                    conn.Open();
                    using (var cmd = new NpgsqlCommand($"SELECT * FROM {tableName} WHERE {pkName} = @id", conn))
                    {
                        cmd.Parameters.AddWithValue("@id", editId.Value);
                        using (var reader = cmd.ExecuteReader())
                        {
                            if (reader.Read())
                            {
                                if (tableName == "apartments")
                                {
                                    txtNumber.Text = reader["apt_number"].ToString();
                                    txtArea.Text = reader["area"].ToString();
                                    txtResidentCount.Text = reader["resident_count"].ToString();
                                    cbAddress.SelectedValue = reader["address_id"];
                                }
                                else if (tableName == "persons")
                                {
                                    txtLastName.Text = reader["last_name"].ToString();
                                    txtFirstName.Text = reader["first_name"].ToString();
                                    txtMiddleName.Text = reader["middle_name"].ToString();
                                }
                                else if (tableName == "receipts")
                                {
                                    cbApartment.SelectedValue = reader["apartment_id"];
                                    txtMonth.Text = reader["period_month"].ToString();
                                    txtYear.Text = reader["period_year"].ToString();
                                    txtPenalty.Text = reader["penalty"].ToString();
                                    txtTotalSum.Text = reader["total_sum"].ToString();
                                    cbPerson.SelectedValue = reader["issued_to_person_id"];
                                }
                                else if (tableName == "users")
                                {
                                    txtUsername.Text = reader["username"].ToString();
                                    txtPassword.Text = "";
                                    cbRole.SelectedValue = reader["role_id"];
                                    cbPerson.SelectedValue = reader["person_id"] != DBNull.Value ? reader["person_id"] : null;
                                }
                                else if (tableName == "payments")
                                {
                                    cbReceipt.SelectedValue = reader["receipt_id"];
                                    txtAmount.Text = reader["amount"].ToString();
                                    cbPaymentMethod.SelectedItem = reader["payment_method"].ToString();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Ошибка загрузки данных: {ex.Message}");
            }
        }

        private void BtnSave_Click(object sender, EventArgs e)
        {
            try
            {
                using (var conn = new NpgsqlConnection(MainForm.ConnectionString))
                {
                    conn.Open();

                    var cmd = new NpgsqlCommand();
                    cmd.Connection = conn;

                    if (tableName == "apartments")
                    {
                        if (editId.HasValue)
                        {
                            cmd.CommandText = "UPDATE apartments SET apt_number=@n, area=@a, resident_count=@c, address_id=@ad WHERE apartment_id=@id";
                            cmd.Parameters.AddWithValue("@id", editId.Value);
                        }
                        else
                        {
                            cmd.CommandText = "INSERT INTO apartments (apt_number, area, resident_count, address_id) VALUES (@n, @a, @c, @ad)";
                        }
                        cmd.Parameters.AddWithValue("@n", txtNumber.Text);
                        cmd.Parameters.AddWithValue("@a", decimal.Parse(txtArea.Text));
                        cmd.Parameters.AddWithValue("@c", int.Parse(txtResidentCount.Text));
                        cmd.Parameters.AddWithValue("@ad", cbAddress.SelectedValue);
                    }
                    else if (tableName == "persons")
                    {
                        if (editId.HasValue)
                        {
                            cmd.CommandText = "UPDATE persons SET last_name=@l, first_name=@f, middle_name=@m WHERE person_id=@id";
                            cmd.Parameters.AddWithValue("@id", editId.Value);
                        }
                        else
                        {
                            cmd.CommandText = "INSERT INTO persons (last_name, first_name, middle_name) VALUES (@l, @f, @m)";
                        }
                        cmd.Parameters.AddWithValue("@l", txtLastName.Text);
                        cmd.Parameters.AddWithValue("@f", txtFirstName.Text);
                        cmd.Parameters.AddWithValue("@m", txtMiddleName.Text);
                    }
                    else if (tableName == "receipts")
                    {
                        if (editId.HasValue)
                        {
                            cmd.CommandText = "UPDATE receipts SET apartment_id=@ap, period_month=@m, period_year=@y, penalty=@p, total_sum=@t, issued_to_person_id=@i WHERE receipt_id=@id";
                            cmd.Parameters.AddWithValue("@id", editId.Value);
                        }
                        else
                        {
                            cmd.CommandText = "INSERT INTO receipts (apartment_id, period_month, period_year, penalty, total_sum, issued_to_person_id) VALUES (@ap, @m, @y, @p, @t, @i)";
                        }
                        cmd.Parameters.AddWithValue("@ap", cbApartment.SelectedValue);
                        cmd.Parameters.AddWithValue("@m", int.Parse(txtMonth.Text));
                        cmd.Parameters.AddWithValue("@y", int.Parse(txtYear.Text));
                        cmd.Parameters.AddWithValue("@p", decimal.Parse(txtPenalty.Text == "" ? "0" : txtPenalty.Text));
                        cmd.Parameters.AddWithValue("@t", decimal.Parse(txtTotalSum.Text));
                        cmd.Parameters.AddWithValue("@i", cbPerson.SelectedValue);
                    }
                    else if (tableName == "payments")
                    {
                        if (editId.HasValue)
                        {
                            cmd.CommandText = "UPDATE payments SET receipt_id=@rid, amount=@amt, payment_method=@pm WHERE payment_id=@id";
                            cmd.Parameters.AddWithValue("@id", editId.Value);
                        }
                        else
                        {
                            cmd.CommandText = "INSERT INTO payments (receipt_id, amount, payment_method) VALUES (@rid, @amt, @pm)";
                        }
                        cmd.Parameters.AddWithValue("@rid", cbReceipt.SelectedValue);
                        cmd.Parameters.AddWithValue("@amt", decimal.Parse(txtAmount.Text));
                        cmd.Parameters.AddWithValue("@pm", cbPaymentMethod.SelectedItem.ToString());
                    }
                    else if (tableName == "users")
                    {
                        if (editId.HasValue)
                        {
                            if (string.IsNullOrEmpty(txtPassword.Text))
                            {
                                cmd.CommandText = "UPDATE users SET username=@u, role_id=@r, person_id=@per WHERE user_id=@id";
                            }
                            else
                            {
                                cmd.CommandText = "UPDATE users SET username=@u, password_hash=MD5(@p), role_id=@r, person_id=@per WHERE user_id=@id";
                                cmd.Parameters.AddWithValue("@p", txtPassword.Text);
                            }
                            cmd.Parameters.AddWithValue("@id", editId.Value);
                        }
                        else
                        {
                            cmd.CommandText = "INSERT INTO users (username, password_hash, role_id, person_id) VALUES (@u, MD5(@p), @r, @per)";
                            cmd.Parameters.AddWithValue("@p", txtPassword.Text);
                        }
                        cmd.Parameters.AddWithValue("@u", txtUsername.Text);
                        cmd.Parameters.AddWithValue("@r", cbRole.SelectedValue);
                        cmd.Parameters.AddWithValue("@per", cbPerson.SelectedValue == null ? DBNull.Value : cbPerson.SelectedValue);
                    }

                    cmd.ExecuteNonQuery();
                }
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Ошибка сохранения: {ex.Message}");
            }
        }

        private void BtnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}