using KarleyLibrary.Attributes;
using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;

namespace WK5.Core.Models
{
    public class Seriennummer
    {
        [CompareField("SNNR_A_SN")]
        public string Nummer { get; set; } = String.Empty;
        [CompareField("SNNR_A_KUNDE")]
        public string Kunde { get; set; } = String.Empty;
        [CompareField("SNNR_N_CHARGE")]
        public int Charge { get; set; }
        [CompareField("CHAR_A_ARTINR")]
        public string Artikelnummer { get; set; } = String.Empty;
        [CompareField("ZUGA_D_DATUM")]
        public DateTime Zugang { get; set; }
        [CompareField("SNNR_L_AUSGELIEFERT")]
        public bool Ausgeliefert { get; set; }
        [CompareField("SNNR_N_MENGE")]
        public int Menge { get; set; }

        [CompareField("LIEF_A_NAME1")]
        public string Lieferant { get; set; } = String.Empty;

        /// <summary>
        /// Holt sich eine Seriennummer aus der Datenbank die die gegebene Seriennummer hat und zu der übergebenen Charge gehört
        /// </summary>
        /// <param name="snr">Die Seriennummer von der wir die holen sollen</param>
        /// <param name="charge">Die Charge in der die Seriennummer auftritt</param>
        /// <returns>Gibt einen <see cref="Task"/> of <see cref="Seriennummer"/> zurück</returns>
        public static async Task<Seriennummer?> GetSeriennummerAsync(string snr, int charge)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@SNNR_A_SN", snr);
            fbController.AddParameter("@SNNR_N_CHARGE", charge);
            DataRow? row = await fbController.SelectRowAsync("SELECT * FROM VIEW_SN WHERE SNNR_A_SN = @SNNR_A_SN AND SNNR_N_CHARGE = @SNNR_N_CHARGE");

            return row is null ? null : ObjectErweiterung.DataRowZuObjekt(new Seriennummer(), row);
        }

        public static async IAsyncEnumerable<Seriennummer> GetSeriennummernAsync(int SNNR_N_CHARGE, FbController2 fbController)
        {
            fbController.AddParameter("@SNNR_N_CHARGE", SNNR_N_CHARGE);
            var data = await fbController.SelectDataAsync("SELECT * FROM SN WHERE SNNR_N_CHARGE = @SNNR_N_CHARGE");

            foreach (DataRow row in data.Rows)
            {
                yield return ObjectErweiterung.DataRowZuObjekt(new Seriennummer(), row);
            }
        }

        /// <summary>
        /// Updatet eine Seriennummer mit neuen Werten
        /// </summary>
        /// <param name="sn">Die akutalisierten Werte der Seriennummer</param>
        /// <param name="fbController">Der FbController2 über den die SQL ausgeführt werden soll</param>
        /// <returns></returns>
        public static async Task UpdateSeriennummerAsync(Seriennummer sn, FbController2 fbController)
        {
            fbController.AddParameter("@SNNR_N_MENGE", sn.Menge);
            fbController.AddParameter("@SNNR_L_AUSGELIEFERT", sn.Ausgeliefert.ToFirebirdBool());
            fbController.AddParameter("@SNNR_A_SN", sn.Nummer);
            fbController.AddParameter("@SNNR_N_CHARGE", sn.Charge);

            string sql = @"UPDATE SN SET SNNR_N_MENGE = @SNNR_N_MENGE, SNNR_L_AUSGELIEFERT = @SNNR_L_AUSGELIEFERT WHERE SNNR_A_SN = @SNNR_A_SN AND SNNR_N_CHARGE = @SNNR_N_CHARGE";
            await fbController.QueryAsync(sql);

        }

        /// <summary>
        /// Sucht offene Seriennummern anhand Ihrer SNNR_A_SN
        /// </summary>
        /// <param name="sn">Die Serienummer nach der gesucht werden soll</param>
        /// <returns>Gibt ein <see cref="IAsyncEnumerable{T}"/> of <see cref="Seriennummer"/> zurück</returns>
        public static async IAsyncEnumerable<Seriennummer> FindeOffeneSeriennummernAsync(string sn)
        {
            using FbController2 fbController = new FbController2();
            string sql = @"SELECT * FROM SN WHERE SNNR_A_SN = @SN AND SNNR_L_AUSGELIEFERT = 'N' AND SNNR_N_MENGE > 0";
            fbController.AddParameter("@SN", sn);
            DataTable data = await fbController.SelectDataAsync(sql);

            foreach (DataRow row in data.Rows)
            {
                if (row is not null)
                {
                    yield return ObjectErweiterung.DataRowZuObjekt(new Seriennummer(), row);
                }
            }
        }

        /// <summary>
        /// Sucht offene Seriennummern anhand der artikel Nummer Ihrer Charge
        /// </summary>
        /// <param name="ARTI_A_NR">Die Artiklenummer nach der gesucht werden soll</param>
        /// <returns>Gibt ein <see cref="IAsyncEnumerable{T}"/> of <see cref="Seriennummer"/> zurück</returns>
        public static async IAsyncEnumerable<Seriennummer> FindeOffeneSeriennummernByArtikelAsync(string ARTI_A_NR)
        {
            using FbController2 fbController = new FbController2();
            string sql = "SELECT * FROM VIEW_SN WHERE SNNR_L_AUSGELIEFERT = 'N' AND SNNR_N_MENGE > 0 AND CHAR_A_ARTINR = @ARTI_A_NR ORDER BY ZUGA_D_DATUM DESC";
            fbController.AddParameter("@ARTI_A_NR", ARTI_A_NR);
            DataTable data = await fbController.SelectDataAsync(sql);

            foreach (DataRow row in data.Rows)
            {
                if (row is not null)
                {
                    yield return ObjectErweiterung.DataRowZuObjekt(new Seriennummer(), row);
                }
            }
        }

    }
}
