using OnAir.Properties;

namespace OnAir
{
    public partial class Form1 : Form
    {
        private NotifyIcon? trayIcon;

        private WebCamWatcher? _watcher;
        private bool _isOnAir;

        HttpClient httpClient;

        public Form1()
        {
            InitializeComponent();
            httpClient = new HttpClient();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            TopMost = Properties.Settings.Default.AlwaysOnTop;
            Location = Properties.Settings.Default.WindowPosition;
            Size = Properties.Settings.Default.WindowSize;

            // Initialize Tray Icon
            var defaultItem = new ToolStripMenuItem("Anzeigen", null, OnShowForm);
            defaultItem.Font = new Font(defaultItem.Font, FontStyle.Bold);
            trayIcon = new NotifyIcon()
            {
                Icon = Resources.CamOff,
                ContextMenuStrip = new ContextMenuStrip()
                {
                    Items = {
                        defaultItem,
                        new ToolStripMenuItem("Einstellungen ...", null, OnSettings),
                        new ToolStripMenuItem("Beenden", null, OnExit),
                    }
                },
                Visible = true,
                Text = "OnAir"
            };
            trayIcon.DoubleClick += OnShowForm;

            SetOnAir(IsCamInUse());
            _watcher = new WebCamWatcher();
            _watcher.Watch(OnCamUsageChanged);
        }

        private bool IsCamInUse()
        {
            return WebCamWatcher.GetAppsUsingCam().Count() > 0;
        }

        async void SwitchLamp(bool OnOff)
        {
            lblStatus.Text = $"Die Lampe wird {(OnOff ? "ein" : "aus")}geschaltet ...";
            string url = OnOff ? Properties.Settings.Default.LampOnUrl : Properties.Settings.Default.LampOffUrl;
            if (!string.IsNullOrEmpty(url))
            {
                try
                {
                    var response = await httpClient.GetAsync(url);
                    response.EnsureSuccessStatusCode();
                    string responseBody = await response.Content.ReadAsStringAsync();
                    var wb = new WebBrowser();
                    wb.Navigate("about:blank");
                    wb.Document?.Write(responseBody);
                    string? state = wb.Document?.GetElementById("lampstate")?.InnerText;
                    if (!string.IsNullOrEmpty(state))
                    {
                        lblStatus.Text = $"Die Lampe ist {state}.";
                    }
                    else
                    {
                        lblStatus.Text = $"Der Status der Lampe ist unbekannt.";
                    }
                    wb.Dispose();
                }
                catch (HttpRequestException e)
                {
                    lblStatus.Text = e.Message;
                }
            }
            else
            {
                lblStatus.Text = "Lampen-URL wurde nicht konfiguriert.";
            }
        }

        private void SetOnAir(bool inUse)
        {
            if (inUse)
            {
                lblOnAir.BackColor = Color.Red;
                if (trayIcon != null)
                {
                    trayIcon.Icon = Resources.CamOn;
                }
            }
            else
            {
                lblOnAir.BackColor = Color.Gray;
                if (trayIcon != null)
                {
                    trayIcon.Icon = Resources.CamOff;
                }
            }
            SwitchLamp(inUse);
            _isOnAir = inUse;
        }

        private void OnCamUsageChanged()
        {
            bool inUse = IsCamInUse();
            if (inUse != _isOnAir)
            {
                if (this.InvokeRequired)
                {
                    // SetOnAir has to run on the UI thread because SwitchLamp() uses a WebBrowser control.
                    this.Invoke(SetOnAir, [inUse]);
                }
                else
                {
                    SetOnAir(inUse);
                }
            }
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            WindowState = (FormWindowState)Properties.Settings.Default.WindowState;
            if (Properties.Settings.Default.MinimizeToTray && (WindowState == FormWindowState.Minimized))
            {
                this.Visible = false;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            _watcher?.EndWatch();
            if (trayIcon != null)
            {
                trayIcon.Visible = false;
            }
            if (WindowState == FormWindowState.Normal)
            {
                Properties.Settings.Default.WindowPosition = Location;
                Properties.Settings.Default.WindowSize = Size;
            }
            Properties.Settings.Default.WindowState = (int)WindowState;
            Properties.Settings.Default.Save();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.MinimizeToTray && (WindowState == FormWindowState.Minimized))
            {
                this.Visible = false;
            }
        }

        private void OnShowForm(object? sender, EventArgs e)
        {
            if (!this.Visible)
            {
                this.Show();
            }
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.WindowState = FormWindowState.Normal;
            }
            this.Activate();
        }

        private void OnExit(object? sender, EventArgs e)
        {
            Application.Exit();
        }

        private void OnSettings(object? sender, EventArgs e)
        {
            var form = new SettingsForm()
            {
                LampStateUrl = Properties.Settings.Default.LampStateUrl,
                LampOnUrl = Properties.Settings.Default.LampOnUrl,
                LampOffUrl = Properties.Settings.Default.LampOffUrl,
                AlwaysOnTop = TopMost,
                MinimizeToTray = Properties.Settings.Default.MinimizeToTray
            };
            form.TopMost = TopMost;
            if (form.ShowDialog(this) == DialogResult.OK)
            {
                Properties.Settings.Default.LampStateUrl = form.LampStateUrl;
                Properties.Settings.Default.LampOnUrl = form.LampOnUrl;
                Properties.Settings.Default.LampOffUrl = form.LampOffUrl;
                Properties.Settings.Default.AlwaysOnTop = form.AlwaysOnTop;
                Properties.Settings.Default.MinimizeToTray = form.MinimizeToTray;
                Properties.Settings.Default.Save();

                TopMost = Properties.Settings.Default.AlwaysOnTop;
                if (WindowState == FormWindowState.Minimized)
                {
                    if (Properties.Settings.Default.MinimizeToTray)
                    {
                        this.Visible = false;
                    }
                    else
                    {
                        this.Show();
                    }
                }
            }
        }

        private void toolStripDropDownButton1_Click(object sender, EventArgs e)
        {
            SetOnAir(!_isOnAir);
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            (new AboutForm()).ShowDialog(this);
        }
    }
}
