using VoiceCat.Interop;

namespace VoiceCat.App.Forms;

/// <summary>
/// Modeless window for a single private message conversation.
/// Created by MainForm and shown non-modally; MainForm routes incoming PMs here.
/// </summary>
public sealed class PrivateMessageForm : Form
{
    private readonly VoiceCatClient _client;
    private readonly uint _userId;
    private readonly uint _selfUserId;

    private readonly RichTextBox _rtbHistory;
    private readonly TextBox _txtCompose;
    private readonly Button _btnSend;

    public PrivateMessageForm(VoiceCatClient client, uint userId, string nickname, uint selfUserId)
    {
        _client = client;
        _userId = userId;
        _selfUserId = selfUserId;

        Text = $"Private Message — {nickname}";
        ClientSize = new Size(480, 360);
        MinimumSize = new Size(320, 240);
        StartPosition = FormStartPosition.Manual;
        KeyPreview = true;
        KeyDown += (_, e) =>
        {
            if (e.KeyCode == Keys.Escape) { e.Handled = e.SuppressKeyPress = true; Close(); }
        };

        _rtbHistory = new RichTextBox
        {
            ReadOnly = true,
            Dock = DockStyle.Fill,
            ScrollBars = RichTextBoxScrollBars.Vertical,
            BackColor = SystemColors.Window,
            AccessibleName = "Message history",
        };

        var composePanel = new TableLayoutPanel
        {
            Dock = DockStyle.Bottom,
            Height = 34,
            ColumnCount = 2,
            RowCount = 1,
            Padding = new Padding(0, 3, 0, 0),
        };
        composePanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
        composePanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 68F));
        composePanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));

        _txtCompose = new TextBox
        {
            Dock = DockStyle.Fill,
            AccessibleName = "Message text",
        };
        _btnSend = new Button
        {
            Text = "&Send",
            Dock = DockStyle.Fill,
        };

        composePanel.Controls.Add(_txtCompose, 0, 0);
        composePanel.Controls.Add(_btnSend, 1, 0);

        Controls.Add(_rtbHistory);
        Controls.Add(composePanel);

        _txtCompose.KeyDown += (_, e) =>
        {
            if (e.KeyCode == Keys.Enter) { Send(); e.Handled = e.SuppressKeyPress = true; }
        };
        _btnSend.Click += (_, _) => Send();
    }

    // Called by MainForm when a PM message arrives (or we send one and the server echoes it).
    public void AppendMessage(string time, bool isSelf, string sender, string text)
    {
        if (IsDisposed) return;
        string line = $"[{time}] {sender}: {text}\n";
        int selStart = _rtbHistory.TextLength;
        _rtbHistory.AppendText(line);
        if (isSelf)
        {
            _rtbHistory.Select(selStart, line.Length);
            _rtbHistory.SelectionColor = Color.Gray;
            _rtbHistory.Select(_rtbHistory.TextLength, 0);
            _rtbHistory.SelectionColor = _rtbHistory.ForeColor;
        }
        _rtbHistory.ScrollToCaret();
    }

    // Called by MainForm for status events (e.g., the other user disconnected).
    public void AppendActivity(string text)
    {
        if (IsDisposed) return;
        string line = $"[{DateTime.Now:HH:mm}] {text}\n";
        int selStart = _rtbHistory.TextLength;
        _rtbHistory.AppendText(line);
        _rtbHistory.Select(selStart, line.Length);
        _rtbHistory.SelectionColor = Color.Gray;
        _rtbHistory.Select(_rtbHistory.TextLength, 0);
        _rtbHistory.SelectionColor = _rtbHistory.ForeColor;
        _rtbHistory.ScrollToCaret();
    }

    private void Send()
    {
        string msg = _txtCompose.Text.Trim();
        if (string.IsNullOrEmpty(msg)) return;
        _client.SendText(VcTextScope.Private, _userId, msg);
        _txtCompose.Clear();
        // No optimistic echo: the server relays our own message back, so AppendMessage is
        // called from MainForm.HandleTextMessage when the echo arrives.
    }
}
