using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WK5.Core.Models;

namespace WK5.Core.Services
{
    public class NotificationService : IDisposable
    {
        public event EventHandler? NotificationsChanged;
        public List<Notification> Notifications = new List<Notification>();
        public Timer? CheckTimer { get; set; }

        public IEnumerable<Notification> GetUserNotification(AppMitarbeiter mitarbeiter)
        {            
            return Notifications.Where(x => (x.NOTI_N_TARGET == NotificationType.Group && mitarbeiter.WK5Gruppen.Select(y => y.GRUP_N_ID).ToList().Contains(x.NOTI_N_TARGET_ID)) || (x.NOTI_N_TARGET == NotificationType.User && x.NOTI_N_TARGET_ID == mitarbeiter.PersonalNummer));
        }

        public async Task AddNotification(Notification notification)
        {
            using FbController2 fbController = new FbController2();
            var tmp = await notification.CreateAsync(fbController);

            Notifications.Add(tmp);
            NotificationsChanged?.Invoke(this, EventArgs.Empty);
        }

        public async Task RemoveNotification(int notification_id)
        {
            using FbController2 fbController = new FbController2();
            Notification? tmp = await Notification.GetNotificationsAsync(notification_id);
            if (tmp is not null)
            {
                await tmp.DeleteAsync(fbController);
            }

            Notifications.RemoveAll(x => x.NOTI_N_ID == notification_id);
            NotificationsChanged?.Invoke(this, EventArgs.Empty);
        }

        public async Task RemoveNotification(Notification notification)
        {
            using FbController2 fbController = new FbController2();
            await notification.DeleteAsync(fbController);

            Notifications.RemoveAll(x => x.NOTI_N_ID == notification.NOTI_N_ID);
            NotificationsChanged?.Invoke(this, EventArgs.Empty);
        }

        public async Task Initialize()
        {
            Notifications = await Notification.GetAllNotificationsAsync().ToListAsync();
            NotificationsChanged?.Invoke(this, EventArgs.Empty);
        }

        public async Task RunTimer()
        {
            CheckTimer = new Timer(async (e) =>
            {
                try
                {
                    await Check();
                }
                catch (Exception ex)
                {

                }
            },null,0, await GlobalConfig.GetConfigNumber(GlobalConfig.NOTIFICATION_CHECK_INTERVAL_CONFIG_NAME, 30000));
        }

        public async Task Check()
        {
            await Initialize();
            await CheckKundenkontakte();
            await CheckLieferantenkontakte();            
        }

        private async Task CheckKundenkontakte()
        {
            using FbController2 fbController = new FbController2();
            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 > 0
AND (SELECT COUNT(*) FROM WK5_NOTIFICATIONS WHERE NOTI_A_REFERENCE_TYP = 'KUKO' AND NOTI_A_REFERENCE_NR = CAST(KUKO_N_ID AS VARCHAR(30))) <= 0";
            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);
                Notification noti = new Notification()
                {
                    NOTI_A_ICON = "far fa-comment-dots",
                    NOTI_A_LINK = $"/Kunden/Kontakt/{kuko.KUKO_N_ID}",
                    NOTI_B_TEXT = kuko.KUKO_A_NOTIZ.RemoveHTML().SafeSubstring(0, 65) + "...",
                    NOTI_A_TITEL = $"Wiedervorlage ({(kunde is not null ? kunde.KUND_A_NAME1 : $"Kunde: {kuko.KUKO_A_KUNDNR}")})",
                    NOTI_D_DATE = DateTime.Now,
                    NOTI_N_TARGET_ID = kuko.KUKO_N_WIEDERV_USER,
                    NOTI_N_ALERTTYP = Basis.AlertType.Info,
                    NOTI_N_TARGET = NotificationType.User,
                    NOTI_A_REFERENCE_NR = kuko.KUKO_N_ID.ToString(),
                    NOTI_A_REFERENCE_TYP = NotificationReferenceTyp.Kundenkontakt
                };

                await AddNotification(noti);
            }

        }

        private async Task CheckLieferantenkontakte()
        {
            using FbController2 fbController = new FbController2();
            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 > 0
AND (SELECT COUNT(*) FROM WK5_NOTIFICATIONS WHERE NOTI_A_REFERENCE_TYP = 'KUKO' AND NOTI_A_REFERENCE_NR = CAST(KUKO_N_ID AS VARCHAR(30))) <= 0";
            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);
                Notification noti = new Notification()
                {
                    NOTI_A_ICON = "far fa-comment-dots",
                    NOTI_A_LINK = $"/Lieferanten/Kontakt/{lfko.LFKO_N_ID}",
                    NOTI_B_TEXT = lfko.LFKO_A_NOTIZ?.RemoveHTML().SafeSubstring(0, 65) + "..." ?? String.Empty,
                    NOTI_A_TITEL = $"Wiedervorlage ({(lief is not null ? lief.LIEF_A_NAME1 : $"Lieferant: {lief.LIEF_N_NR}")})",
                    NOTI_D_DATE = DateTime.Now,                    
                    NOTI_N_TARGET_ID = lfko.LFKO_N_WIEDERV_USER,
                    NOTI_N_ALERTTYP = Basis.AlertType.Info,
                    NOTI_N_TARGET = NotificationType.User,
                    NOTI_A_REFERENCE_NR = lfko.LFKO_N_ID.ToString(),
                    NOTI_A_REFERENCE_TYP = NotificationReferenceTyp.Lieferantenkontakt

                };                

                await AddNotification(noti);
            }

        }

        public void Dispose()
        {
            CheckTimer.Dispose();
        }


        //public async Task Run()
        //{
        //    await CheckWiedervorlageNotifications();
        //    await CheckLieferantenWiedervorlageNotifications();   
        //}

        //public async Task CheckWiedervorlageNotifications()
        //{
        //    try
        //    {
        //        using FbController2 fbController = new FbController2();

        //        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 COALESCE(KUKO_WK5_N_NOTIFICATION_ID,0) <= 0 AND KUKO_N_WIEDERV_USER > 0";

        //        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);
        //            Notification tmp = new Notification()
        //            {
        //                NOTI_A_ICON = "far fa-comment-dots",
        //                NOTI_A_LINK = $"/Kunden/Kundenkontakte/{kuko.KUKO_N_ID}",
        //                NOTI_B_TEXT = kuko.KUKO_A_NOTIZ.SafeSubstring(0, 20) + "...",
        //                NOTI_A_TITEL = $"Wiedervorlage ({(kunde is not null ? kunde.KUND_A_NAME1 : $"Kunde: {kuko.KUKO_A_KUNDNR}")})",
        //                NOTI_D_DATE = DateTime.Now,
        //                NOTI_L_GELESEN = false,
        //                NOTI_N_TARGET_ID = kuko.KUKO_N_WIEDERV_USER,
        //                NOTI_N_TYP = Basis.AlertType.Info,
        //                NOTI_N_TARGET = NotificationType.User

        //            };

        //            tmp = await tmp.CreateAsync(fbController);

        //            kuko.KUKO_WK5_N_NOTIFICATION_ID = tmp.NOTI_N_ID;
        //            await kuko.UpdateAsync();
        //        }

        //    }
        //    catch (Exception ex)
        //    {

        //    }
        //}

        //public async Task CheckLieferantenWiedervorlageNotifications()
        //{
        //    try
        //    {
        //        using FbController2 fbController = new FbController2();

        //        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 COALESCE(LFKO_WK5_N_NOTIFICATION_ID,0) <= 0 AND LFKO_N_WIEDERV_USER > 0";

        //        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);
        //            Notification tmp = new Notification()
        //            {
        //                NOTI_A_ICON = "far fa-comment-dots",
        //                NOTI_A_LINK = $"/Lieferanten/Lieferantenkontakte/{lfko.LFKO_N_ID}",
        //                NOTI_B_TEXT = lfko.LFKO_A_NOTIZ.SafeSubstring(0, 20) + "...",
        //                NOTI_A_TITEL = $"Wiedervorlage ({(lief is not null ? lief.LIEF_A_NAME1 : $"Lieferant: {lief.LIEF_N_NR}")})",
        //                NOTI_D_DATE = DateTime.Now,
        //                NOTI_L_GELESEN = false,
        //                NOTI_N_TARGET_ID = lfko.LFKO_N_WIEDERV_USER,
        //                NOTI_N_TYP = Basis.AlertType.Info,
        //                NOTI_N_TARGET = NotificationType.User

        //            };

        //            tmp = await tmp.CreateAsync(fbController);

        //            lfko.LFKO_WK5_N_NOTIFICATION_ID = tmp.NOTI_N_ID;
        //            await lfko.UpdateLieferantenKontaktAsync(fbController);
        //        }

        //    }
        //    catch (Exception ex)
        //    {

        //    }
        //}
    }
}
