using VoiceCat.App.Notifications;

namespace VoiceCat.App.Forms;

/// <summary>
/// Edits and persists <see cref="FeedbackSettings"/> (event sounds + spoken announcements).
/// On OK the supplied <see cref="EventFeedback"/> is updated live and the settings saved.
/// </summary>
public sealed class NotificationSettingsForm : Form
{
    private readonly EventFeedback _feedback;

    private readonly CheckBox _chkSounds;
    private readonly CheckBox _chkSpeech;
    private readonly TrackBar _trkVolume;
    private readonly CheckBox _chkSelfTalk;
    private readonly CheckBox _chkPtt;

    public NotificationSettingsForm(EventFeedback feedback)
    {
        _feedback = feedback;
        var s = feedback.Settings;

        Text = "Notification settings";
        FormBorderStyle = FormBorderStyle.FixedDialog;
        MaximizeBox = false;
        MinimizeBox = false;
        StartPosition = FormStartPosition.CenterParent;
        AutoScaleMode = AutoScaleMode.Font;
        ClientSize = new Size(360, 300);

        _chkSounds = new CheckBox
        {
            Text = "Play event &sounds",
            Location = new Point(12, 12),
            AutoSize = true,
            Checked = s.Sounds,
        };

        var lblVolume = new Label
        {
            Text = "Sound &volume:",
            Location = new Point(12, 42),
            AutoSize = true,
        };
        _trkVolume = new TrackBar
        {
            Location = new Point(12, 64),
            Size = new Size(330, 45),
            Minimum = 0,
            Maximum = 100,
            TickFrequency = 10,
            Value = (int)Math.Round(Math.Clamp(s.Volume, 0f, 1f) * 100),
        };
        _trkVolume.AccessibleName = "Sound volume";

        _chkSpeech = new CheckBox
        {
            Text = "&Speak events (text-to-speech)",
            Location = new Point(12, 118),
            AutoSize = true,
            Checked = s.Speech,
        };
        var lblSpeechHint = new Label
        {
            Text = feedback.SpeechAvailable
                ? "Announces joins/leaves and reads message text aloud."
                : "No speech engine available on this machine.",
            Location = new Point(30, 142),
            AutoSize = true,
            ForeColor = SystemColors.GrayText,
        };

        var lblOptional = new Label
        {
            Text = "Optional sounds:",
            Location = new Point(12, 174),
            AutoSize = true,
        };
        _chkSelfTalk = new CheckBox
        {
            Text = "Your own voice-&activity start/stop",
            Location = new Point(12, 198),
            AutoSize = true,
            Checked = s.SelfTalkSounds,
        };
        _chkPtt = new CheckBox
        {
            Text = "&Push-to-talk cue",
            Location = new Point(12, 224),
            AutoSize = true,
            Checked = s.PttSound,
        };

        var btnOk = new Button
        {
            Text = "&OK",
            DialogResult = DialogResult.OK,
            Location = new Point(192, 262),
            Size = new Size(75, 27),
        };
        var btnCancel = new Button
        {
            Text = "&Cancel",
            DialogResult = DialogResult.Cancel,
            Location = new Point(273, 262),
            Size = new Size(75, 27),
        };

        AcceptButton = btnOk;
        CancelButton = btnCancel;
        Controls.AddRange([_chkSounds, lblVolume, _trkVolume, _chkSpeech, lblSpeechHint,
                           lblOptional, _chkSelfTalk, _chkPtt, btnOk, btnCancel]);

        btnOk.Click += (_, _) => Apply();
    }

    private void Apply()
    {
        var s = _feedback.Settings;
        s.Sounds = _chkSounds.Checked;
        s.Speech = _chkSpeech.Checked;
        s.Volume = _trkVolume.Value / 100f;
        s.SelfTalkSounds = _chkSelfTalk.Checked;
        s.PttSound = _chkPtt.Checked;
        s.Save();
    }
}
