using Sunfish.Auth;
using Sunfish.Config;
using Sunfish.Net;

namespace Sunfish.WinForms;

/// <summary>
/// Panel de administracion web: activarlo, contrasena (usuario "admin") y desde donde se permite.
/// Compacto y vertical, etiqueta encima de cada campo, como el dialogo de share.
/// </summary>
internal sealed class AdminDialog : Form
{
    private const int FieldWidth = 230;
    private readonly AdminSettings _admin;
    private readonly CheckBox _enabled = new() { AutoSize = true, Margin = new Padding(3, 3, 3, 6) };
    private readonly TextBox _password = new() { Width = FieldWidth, UseSystemPasswordChar = true };
    private readonly TextBox _repeat = new() { Width = FieldWidth, UseSystemPasswordChar = true };
    private readonly TextBox _allow = new() { Width = FieldWidth };

    public AdminDialog(AdminSettings admin, int httpPort)
    {
        _admin = admin;
        SuspendLayout();
        AutoScaleDimensions = new SizeF(96F, 96F);
        AutoScaleMode = AutoScaleMode.Dpi;
        Text = Strings.AdminPanel;
        FormBorderStyle = FormBorderStyle.FixedDialog;
        MaximizeBox = MinimizeBox = false;
        ShowInTaskbar = false;
        StartPosition = FormStartPosition.CenterParent;
        AutoSize = true;
        AutoSizeMode = AutoSizeMode.GrowAndShrink;
        Padding = new Padding(8, 6, 8, 8);

        _enabled.Text = Texts.AdminEnable;
        _enabled.Checked = admin.Enabled;
        _allow.Text = string.Join(", ", admin.AllowFrom);

        var main = new FlowLayoutPanel
        {
            FlowDirection = FlowDirection.TopDown, AutoSize = true, WrapContents = false,
            Location = new Point(Padding.Left, Padding.Top), Margin = new Padding(0),
        };
        main.Controls.Add(_enabled);
        main.Controls.Add(Caption(admin.PasswordHash.Length > 0 ? Texts.AdminPasswordKeep : Strings.FieldPassword));
        main.Controls.Add(_password);
        main.Controls.Add(Caption(Strings.AdminRepeat));
        main.Controls.Add(_repeat);
        main.Controls.Add(Caption(Strings.AdminAllowFrom));
        main.Controls.Add(_allow);
        main.Controls.Add(new Label
        {
            Text = Texts.AdminHelp($"http://<IP>:{httpPort}/$sunfish/admin/"), AutoSize = true,
            MaximumSize = new Size(FieldWidth, 0), ForeColor = SystemColors.GrayText, Margin = new Padding(3, 6, 3, 3),
        });

        var ok = new Button { Text = Texts.Ok, Size = new Size(80, 25), UseVisualStyleBackColor = true, Margin = new Padding(3, 0, 3, 0) };
        ok.Click += (_, _) => Accept();
        var cancel = new Button { Text = Texts.Cancel, Size = new Size(80, 25), DialogResult = DialogResult.Cancel, UseVisualStyleBackColor = true, Margin = new Padding(3, 0, 3, 0) };
        var buttons = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, Width = FieldWidth + 6, Height = 25, Margin = new Padding(0, 10, 0, 0) };
        buttons.Controls.AddRange([cancel, ok]);
        main.Controls.Add(buttons);
        AcceptButton = ok;
        CancelButton = cancel;
        Controls.Add(main);
        ResumeLayout(false);
        PerformLayout();
    }

    private static Label Caption(string text) => new() { Text = text + ":", AutoSize = true, Margin = new Padding(3, 6, 3, 1) };

    private void Accept()
    {
        var rules = _allow.Text.Split([',', ' ', ';'], StringSplitOptions.RemoveEmptyEntries).ToList();
        var bad = rules.FirstOrDefault(r => !AddressRules.IsValid(r));
        if (rules.Count == 0 || bad is not null)
        {
            MessageBox.Show(this, Strings.AdminBadAllow(bad ?? ""), Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }
        if (_password.Text != _repeat.Text)
        {
            MessageBox.Show(this, Strings.AdminPasswordMismatch, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }
        if (_enabled.Checked && _password.Text.Length == 0 && _admin.PasswordHash.Length == 0)
        {
            MessageBox.Show(this, Strings.ErrorPasswordEmpty, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }
        _admin.Enabled = _enabled.Checked;
        _admin.AllowFrom = rules;
        if (_password.Text.Length > 0)
            _admin.PasswordHash = Passwords.Hash(_password.Text);
        DialogResult = DialogResult.OK;
    }
}
