using System;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Decal.DenAgent
{
    /// <summary>
    /// Options/settings dialog for Decal configuration.
    /// Manages registry settings under HKLM\SOFTWARE\Decal.
    /// Replaces the MFC cOptionsDlg class.
    /// </summary>
    internal sealed class OptionsForm : Form
    {
        private readonly NumericUpDown _nudBarAlpha;
        private readonly NumericUpDown _nudViewAlpha;
        private readonly ComboBox _cbDockPos;
        private readonly CheckBox _chkTimestamp;
        private readonly TextBox _txtTimestampFormat;
        private readonly CheckBox _chkWindowed;
        private readonly CheckBox _chkDualLog;
        private readonly CheckBox _chkNoMovies;
        private readonly CheckBox _chkNoSplash;

        public OptionsForm()
        {
            Text = "Decal Options";
            Size = new System.Drawing.Size(380, 340);
            FormBorderStyle = FormBorderStyle.FixedDialog;
            MaximizeBox = false;
            MinimizeBox = false;
            StartPosition = FormStartPosition.CenterParent;

            int y = 15;

            // View Options group
            var grpView = new GroupBox
            {
                Text = "View Options",
                Location = new System.Drawing.Point(10, y),
                Size = new System.Drawing.Size(350, 90)
            };
            Controls.Add(grpView);

            grpView.Controls.Add(new Label { Text = "Bar Alpha:", Location = new System.Drawing.Point(10, 25), AutoSize = true });
            _nudBarAlpha = new NumericUpDown
            {
                Location = new System.Drawing.Point(100, 22),
                Size = new System.Drawing.Size(60, 23),
                Minimum = 0, Maximum = 255, Value = 255
            };
            grpView.Controls.Add(_nudBarAlpha);

            grpView.Controls.Add(new Label { Text = "View Alpha:", Location = new System.Drawing.Point(180, 25), AutoSize = true });
            _nudViewAlpha = new NumericUpDown
            {
                Location = new System.Drawing.Point(270, 22),
                Size = new System.Drawing.Size(60, 23),
                Minimum = 0, Maximum = 255, Value = 255
            };
            grpView.Controls.Add(_nudViewAlpha);

            grpView.Controls.Add(new Label { Text = "Dock Position:", Location = new System.Drawing.Point(10, 58), AutoSize = true });
            _cbDockPos = new ComboBox
            {
                Location = new System.Drawing.Point(100, 55),
                Size = new System.Drawing.Size(100, 23),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            _cbDockPos.Items.AddRange(new object[] { "Top", "Left", "Right" });
            _cbDockPos.SelectedIndex = 0;
            grpView.Controls.Add(_cbDockPos);

            y += 100;

            // Timestamp group
            var grpTS = new GroupBox
            {
                Text = "Time Stamping",
                Location = new System.Drawing.Point(10, y),
                Size = new System.Drawing.Size(350, 55)
            };
            Controls.Add(grpTS);

            _chkTimestamp = new CheckBox
            {
                Text = "Enable Timestamps",
                Location = new System.Drawing.Point(10, 22),
                AutoSize = true
            };
            _chkTimestamp.CheckedChanged += (s, e) => _txtTimestampFormat.Enabled = _chkTimestamp.Checked;
            grpTS.Controls.Add(_chkTimestamp);

            grpTS.Controls.Add(new Label { Text = "Format:", Location = new System.Drawing.Point(170, 24), AutoSize = true });
            _txtTimestampFormat = new TextBox
            {
                Location = new System.Drawing.Point(220, 21),
                Size = new System.Drawing.Size(110, 23),
                Text = "[%H:%M]",
                Enabled = false
            };
            grpTS.Controls.Add(_txtTimestampFormat);

            y += 65;

            // Client Patches group
            var grpPatches = new GroupBox
            {
                Text = "Client Patches",
                Location = new System.Drawing.Point(10, y),
                Size = new System.Drawing.Size(350, 90)
            };
            Controls.Add(grpPatches);

            _chkWindowed = new CheckBox
            {
                Text = "Allow Windowed Mode",
                Location = new System.Drawing.Point(10, 20),
                AutoSize = true
            };
            grpPatches.Controls.Add(_chkWindowed);

            _chkDualLog = new CheckBox
            {
                Text = "Allow Dual Logging",
                Location = new System.Drawing.Point(10, 42),
                AutoSize = true
            };
            grpPatches.Controls.Add(_chkDualLog);

            _chkNoMovies = new CheckBox
            {
                Text = "Disable Movies",
                Location = new System.Drawing.Point(190, 20),
                AutoSize = true
            };
            grpPatches.Controls.Add(_chkNoMovies);

            _chkNoSplash = new CheckBox
            {
                Text = "Disable Splash Screen",
                Location = new System.Drawing.Point(190, 42),
                AutoSize = true
            };
            grpPatches.Controls.Add(_chkNoSplash);

            y += 100;

            // OK / Cancel buttons
            var btnOK = new Button
            {
                Text = "OK",
                DialogResult = DialogResult.OK,
                Location = new System.Drawing.Point(200, y),
                Size = new System.Drawing.Size(75, 25)
            };
            btnOK.Click += OnOK;
            Controls.Add(btnOK);

            var btnCancel = new Button
            {
                Text = "Cancel",
                DialogResult = DialogResult.Cancel,
                Location = new System.Drawing.Point(285, y),
                Size = new System.Drawing.Size(75, 25)
            };
            Controls.Add(btnCancel);

            AcceptButton = btnOK;
            CancelButton = btnCancel;

            LoadSettings();
        }

        private void LoadSettings()
        {
            try
            {
                using var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Decal");
                if (key == null) return;

                _nudBarAlpha.Value = Math.Min(255, Math.Max(0, (int)(key.GetValue("BarAlpha") ?? 255)));
                _nudViewAlpha.Value = Math.Min(255, Math.Max(0, (int)(key.GetValue("ViewAlpha") ?? 255)));

                int dockPos = (int)(key.GetValue("BarDock") ?? 0);
                if (dockPos >= 0 && dockPos < _cbDockPos.Items.Count)
                    _cbDockPos.SelectedIndex = dockPos;

                _chkTimestamp.Checked = ((int)(key.GetValue("Timestamp") ?? 0)) != 0;
                _txtTimestampFormat.Text = key.GetValue("TimestampFormat") as string ?? "[%H:%M]";
                _txtTimestampFormat.Enabled = _chkTimestamp.Checked;

                _chkWindowed.Checked = ((int)(key.GetValue("AllowWindowed") ?? 0)) != 0;
                _chkDualLog.Checked = ((int)(key.GetValue("AllowDualLog") ?? 0)) != 0;
                _chkNoMovies.Checked = ((int)(key.GetValue("NoMovies") ?? 0)) != 0;
                _chkNoSplash.Checked = ((int)(key.GetValue("NoSplash") ?? 0)) != 0;
            }
            catch { /* Default values are fine */ }
        }

        private void OnOK(object sender, EventArgs e)
        {
            try
            {
                using var key = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Decal");
                if (key == null) return;

                key.SetValue("BarAlpha", (int)_nudBarAlpha.Value, RegistryValueKind.DWord);
                key.SetValue("ViewAlpha", (int)_nudViewAlpha.Value, RegistryValueKind.DWord);
                key.SetValue("BarDock", _cbDockPos.SelectedIndex, RegistryValueKind.DWord);

                key.SetValue("Timestamp", _chkTimestamp.Checked ? 1 : 0, RegistryValueKind.DWord);
                key.SetValue("TimestampFormat", _txtTimestampFormat.Text);

                key.SetValue("AllowWindowed", _chkWindowed.Checked ? 1 : 0, RegistryValueKind.DWord);
                key.SetValue("AllowDualLog", _chkDualLog.Checked ? 1 : 0, RegistryValueKind.DWord);
                key.SetValue("NoMovies", _chkNoMovies.Checked ? 1 : 0, RegistryValueKind.DWord);
                key.SetValue("NoSplash", _chkNoSplash.Checked ? 1 : 0, RegistryValueKind.DWord);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Failed to save settings: {ex.Message}\n\nYou may need to run as Administrator.",
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
