using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using WK5.Core.Models;
using System.DirectoryServices.AccountManagement;
using WK5.Core;
using KarleyLibrary.Erweiterungen;
using System.Data;
using System.Timers;
using BlazorDownloadFile;
using Microsoft.Web.WebView2.Core;
using System.IO;
using FluentValidation;
using System.Reflection;

namespace WK5.Desktop
{
    public partial class NotificationForm : Form
    {
        public NotifyIcon trayIcon { get; set; }
        public ToolStripButton ExitButton { get; set; } = new ToolStripButton("Beenden");
        public ToolStripButton PauseButton { get; set; } = new ToolStripButton("Timer pausieren");
        public bool Pausiert { get; set; }
        public System.Timers.Timer FetchTimer { get; set; }
        public UserPrincipal? CurrentUser { get; set; }

        public NotificationForm()
        {
            ControlBox = false;
            Icon = Properties.Resources.favicon;
            DataService.MainForm = this;
            var serviceCollection = new ServiceCollection();
            serviceCollection.AddBlazorWebView();
            serviceCollection.AddBlazorDownloadFile();
            serviceCollection.AddValidatorsFromAssembly(Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WK5.Core.dll")));

            CurrentUser = UserPrincipal.Current;


            if (CurrentUser is null)
            {
                MessageBox.Show(
                    caption: "Kein Benutzer gefunden",
                    text: "Es konnte kein Domänenbenutzer gefunden werden",
                    icon: MessageBoxIcon.Exclamation,
                    buttons: MessageBoxButtons.OK
                    );
                Application.Exit();
            }

            DataService.Mitarbeiter = DataService.ToAppMitarbeiter(CurrentUser);

            ExitButton.Click += ExitButton_Click;
            PauseButton.Click += PauseButton_Click;

            PauseButton.ToolTipText = "Pausiert die Prüfung im Hintergrund. Ihr erhaltet solange keine Popups mehr.";
            ExitButton.ToolTipText = "Beendet das Programm";

            ContextMenuStrip cms = new ContextMenuStrip();
            cms.Items.Add(ExitButton);
            cms.Items.Add(PauseButton);
            trayIcon = new NotifyIcon()
            {
                Icon = Properties.Resources.favicon,
                ContextMenuStrip = cms,
                Visible = true
            };
            cms.PerformLayout();

            SetTimer();
            FetchTimer.Start();

            InitializeComponent();

            InitializeWebView();
            WK5WebView.HostPage = @"wwwroot\index.html";
            WK5WebView.Services = serviceCollection.BuildServiceProvider();
            WK5WebView.RootComponents.Add<Main>("#app");


            HideForm();
        }

        private void InitializeWebView()
        {
            string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            string cacheFolder = Path.Combine(localAppData, "WindowsFormsWebView2");
            Task<CoreWebView2Environment> task = CoreWebView2Environment.CreateAsync(null, cacheFolder, null);

            TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();

            task.ContinueWith(t =>
            {
                CoreWebView2Environment environment = task.Result;
                WK5WebView.WebView.EnsureCoreWebView2Async(environment);
            }, ui).GetAwaiter().GetResult();
        }
        private void PauseButton_Click(object sender, EventArgs e)
        {
            Pausiert = !Pausiert;
            FetchTimer.Enabled = !Pausiert;

            if (!Pausiert)
            {
                PauseButton.Text = "Timer pausieren";
            }
            else
            {
                PauseButton.Text = "Timer fortsetzen";
            }
        }

        private void ExitButton_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void SetTimer()
        {
            FetchTimer = new System.Timers.Timer(30000);
            FetchTimer.Elapsed += async (o, e) => await FetchTimer_Elapsed(o, e);
            FetchTimer.AutoReset = true;
            FetchTimer.Enabled = true;
        }

        private async Task CheckKundenkontakte()
        {
            FetchTimer.Enabled = false;
            using FbController2 fbController = new FbController2();

            fbController.AddParameter("@USER", CurrentUser.EmployeeId);
            string sql = "SELECT * FROM KUNDENKONTAKTE WHERE (KUKO_D_WIEDERV_DATE+KUKO_T_WIEDERV_TIME) <= CURRENT_TIMESTAMP AND KUKO_L_WIEDERV_ERL = 'N' AND KUKO_D_WIEDERV_DATE > '30.12.1899' AND KUKO_N_WIEDERV_USER = @USER";

            DataTable data = await fbController.SelectDataAsync(sql);

            foreach (DataRow row in data.Rows)
            {
                Kundenkontakt kuko = ObjectErweiterung.DataRowZuObjekt(new Kundenkontakt(), row);
                Kunde? kunde = await Kunde.GetKundeAsync(kuko.KUKO_A_KUNDNR);
                DataService.Kontakt = kuko;
                DataService.Mode = DisplayMode.Kunde;
                DataService.Busy = true;
                this.Invoke(new MethodInvoker(() =>
                {
                    this.ShowForm();
                    this.TopMost = true;
                    WK5WebView.WebView.Reload();
                    if (kunde is not null)
                    {
                        this.Text = $"Wiedervorlage - {kunde.KUND_A_NAME1} {kunde.KUND_A_NAME2} ({kunde.KUND_A_NR})";
                    }
                    else
                    {
                        this.Text = $"Wiedervorlage - {kuko.KUKO_A_KUNDNR}";
                    }
                }));

                await Task.Delay(1000);
                this.Invoke(new MethodInvoker(() =>
                {
                    this.TopMost = false;
                }));

                while (DataService.Busy)
                {
                    await Task.Delay(100);
                }
                this.Invoke(new MethodInvoker(() =>
                {
                    this.HideForm();
                }));
            }
            FetchTimer.Enabled = !Pausiert;
        }

        private async Task CheckLieferantenkontakte()
        {
            FetchTimer.Enabled = false;
            using FbController2 fbController = new FbController2();

            fbController.AddParameter("@USER", CurrentUser.EmployeeId);
            string sql = "SELECT * FROM WK5_LIEFERANTENKONTAKTE WHERE (LFKO_D_WIEDERV_DATE+LFKO_T_WIEDERV_TIME) <= CURRENT_TIMESTAMP AND LFKO_L_WIEDERV_ERL = 'N' AND LFKO_D_WIEDERV_DATE > '30.12.1899' AND LFKO_N_WIEDERV_USER = @USER";

            DataTable data = await fbController.SelectDataAsync(sql);

            foreach (DataRow row in data.Rows)
            {
                LieferantenKontakt lfko = ObjectErweiterung.DataRowZuObjekt(new LieferantenKontakt(), row);
                Lieferant? lief = await Lieferant.GetLieferantAsync(lfko.LFKO_N_LFNR);
                DataService.LiefKontakt = lfko;
                DataService.Mode = DisplayMode.Lieferant;
                DataService.Busy = true;

                this.Invoke(new MethodInvoker(() =>
                {
                    this.ShowForm();
                    this.TopMost = true;
                    WK5WebView.WebView.Reload();
                    if (lief is not null)
                    {
                        this.Text = $"Wiedervorlage - {lief.LIEF_A_NAME1} {lief.LIEF_A_NAME2} ({lief.LIEF_N_NR})";
                    }
                    else
                    {
                        this.Text = $"Wiedervorlage - {lfko.LFKO_N_LFNR}";
                    }
                }));

                await Task.Delay(1000);
                this.Invoke(new MethodInvoker(() =>
                {
                    this.TopMost = false;
                }));

                while (DataService.Busy)
                {
                    await Task.Delay(100);
                }
                this.Invoke(new MethodInvoker(() =>
                {
                    this.HideForm();
                }));
            }
            FetchTimer.Enabled = !Pausiert;
        }

        private async Task FetchTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            await CheckKundenkontakte();
            await CheckLieferantenkontakte();
        }

        private void NotificationForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing || e.CloseReason == CloseReason.TaskManagerClosing)
            {
                e.Cancel = true;
            }
            else
            {
                Environment.Exit(0);
            }
        }

        public void ShowForm()
        {
            Opacity = 100;
            ShowInTaskbar = true;
        }

        public void HideForm()
        {
            Opacity = 0;
            ShowInTaskbar = false;
        }
    }
}
