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

namespace WK5.Core.Models
{
    public class BelegSeriennummer
    {
        private string _artikelnummer = String.Empty;

        public int BSNR_N_ID { get; set; }
        public int BSNR_N_POSID { get; set; }
        public string? BSNR_A_SN { get; set; }
        public int BSNR_N_CHARGE { get; set; }
        public int BSNR_N_MENGE { get; set; }
        public int BSNR_N_STLPOSID { get; set; }
        public DateTime BSNR_TIMESTAMP { get; set; }
        public int BSNR_N_LASTUSER { get; set; }

        public string Artikelnummer { get => _artikelnummer; set => _artikelnummer = value ?? String.Empty; }
        /// <summary>
        /// Lädt eine gechargte Seriennummer anhand der eindeutigen ID der gechargten Seriennummer
        /// </summary>
        /// <param name="BSNR_N_ID">Die ID zu der sich die Belgeseriennummer geholt werden soll</param>
        /// <returns>Gibt einen <see cref="Task"/> of <see cref="BelegSeriennummer"/> zurück</returns>
        public static async Task<BelegSeriennummer?> GetBelegSeriennummerAsync(int BSNR_N_ID)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@BSNR_N_ID", BSNR_N_ID);
            DataRow? row = await fbController.SelectRowAsync(@"SELECT BELEGSN.*,
CASE WHEN BSNR_N_STLPOSID > 0 THEN
     (SELECT BSTU_A_UNTERARTI FROM BELEGSTUECKLISTE WHERE BSTU_N_POSID = BSNR_N_STLPOSID)
ELSE
     (SELECT BPOS_A_ARTIKELNR FROM BELEGPOS WHERE BPOS_N_POSID = BSNR_N_POSID)
END AS ARTIKELNUMMER
FROM BELEGSN 
WHERE BSNR_N_ID = @BSNR_N_ID");

            return row == null ? null : ObjectErweiterung.DataRowZuObjekt(new BelegSeriennummer(), row);
        }
        /// <summary>
        /// Lädt alle gechargten Seriennummeren für einen Beleg anhand der Kombination aus <see cref="Belegposition.PosId"/> und <see cref="Belegposition.StücklistenPositionsId"/> 
        /// </summary>
        /// <param name="BSNR_N_POSID"></param>
        /// <param name="BSNR_N_STLPOSID"></param>
        /// <param name="fbController"></param>
        /// <returns></returns>
        public static async IAsyncEnumerable<BelegSeriennummer> GetBelegSeriennummernAsync(int BSNR_N_POSID, int BSNR_N_STLPOSID, FbController2 fbController)
        {
            fbController.AddParameter("@BSNR_N_POSID", BSNR_N_POSID);
            fbController.AddParameter("@BSNR_N_STLPOSID", BSNR_N_STLPOSID);

            DataTable data = await fbController.SelectDataAsync(@"SELECT BELEGSN.*, 
CASE WHEN BSNR_N_STLPOSID > 0 THEN
     (SELECT BSTU_A_UNTERARTI FROM BELEGSTUECKLISTE WHERE BSTU_N_POSID = BSNR_N_STLPOSID)
ELSE
     (SELECT BPOS_A_ARTIKELNR FROM BELEGPOS WHERE BPOS_N_POSID = BSNR_N_POSID)
END AS ARTIKELNUMMER
FROM BELEGSN 
WHERE BSNR_N_POSID = @BSNR_N_POSID AND BSNR_N_STLPOSID = @BSNR_N_STLPOSID");

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

        /// <summary>
        /// Lädt sich alle gechargten Seriennummern für einen bestimmten Beleg
        /// </summary>
        /// <param name="belegTyp">Der <see cref="BelegTyp"/> anhand dessen sich die Belegseriennummern geladen werden sollen</param>
        /// <param name="belegnummer">Die Belegnummer anhand derer sich die Belegseriennummern geladen werden sollen</param>
        /// <returns></returns>
        public static async IAsyncEnumerable<BelegSeriennummer> GetBelegSeriennummernAsync(BelegTyp belegTyp, int belegnummer, FbController2 fbController)
        {
            fbController.AddParameter("@BPOS_A_TYP", EnumHelper.GetBelegTypString(belegTyp));
            fbController.AddParameter("@BPOS_N_NR", belegnummer);

            DataTable data = await fbController.SelectDataAsync(@"SELECT BS.*,
CASE WHEN BS.BSNR_N_STLPOSID > 0 THEN
     (SELECT BSTU_A_UNTERARTI FROM BELEGSTUECKLISTE WHERE BSTU_N_POSID = BS.BSNR_N_STLPOSID)
ELSE
     BP.BPOS_A_ARTIKELNR
END AS ARTIKELNUMMER
FROM BELEGPOS BP
INNER JOIN BELEGSN BS ON BS.BSNR_N_POSID = BP.BPOS_N_POSID
WHERE BPOS_A_TYP = 'LS' AND BPOS_N_NR = @BPOS_N_NR");

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

        /// <summary>
        /// Sucht eine Belegseriennummer anhand eines BelegTyp, Belegnummer und einer Seriennummer
        /// </summary>
        /// <param name="belegTyp">Der BelegTyp zu dem die Belegseriennummer gehört</param>
        /// <param name="belegNr">Die Belegnummer zu dem die Belegseriennummer gehört</param>
        /// <param name="seriennummer">Die Seriennummer nach der die Belegseriennummer gesucht werden soll</param>
        /// <returns>Gibt einen <see cref="Task"/> of <see cref="BelegSeriennummer"/> zurück</returns>

        public static async Task<BelegSeriennummer?> FindBelegSeriennummer(BelegTyp belegTyp, int belegNr, string seriennummer)
        {
            using FbController2 fbController = new FbController2();
            string sql = "SELECT * FROM BELEGSN WHERE BSNR_N_POSID IN (SELECT BPOS_N_POSID FROM BELEGPOS WHERE BPOS_A_TYP = @BPOS_A_TYP AND BPOS_N_NR = @BPOS_N_NR) AND BSNR_A_SN = @SN";
            fbController.AddParameter("@BPOS_A_TYP", EnumHelper.GetBelegTypString(belegTyp));
            fbController.AddParameter("@BPOS_N_NR", belegNr);
            fbController.AddParameter("@SN", seriennummer);
            DataRow? row = await fbController.SelectRowAsync(sql);

            return row == null ? null : ObjectErweiterung.DataRowZuObjekt(new BelegSeriennummer(), row);
        }

        /// <summary>
        /// Aktualisiert eine BelegSeriennummer
        /// </summary>
        /// <param name="bsn">Die Werte die geschrieben werden soll</param>
        /// <param name="fbController">Der FbController2 über den geschrieben werden soll</param>
        /// <returns></returns>
        public static async Task UpdateBelegSeriennummerAsync(BelegSeriennummer bsn, FbController2 fbController)
        {
            fbController.AddParameter("@BSNR_N_ID", bsn.BSNR_N_ID);
            fbController.AddParameter("@BSNR_N_POSID", bsn.BSNR_N_POSID);
            fbController.AddParameter("@BSNR_A_SN", bsn.BSNR_A_SN);
            fbController.AddParameter("@BSNR_N_CHARGE", bsn.BSNR_N_CHARGE);
            fbController.AddParameter("@BSNR_N_MENGE", bsn.BSNR_N_MENGE);
            fbController.AddParameter("@BSNR_N_STLPOSID", bsn.BSNR_N_STLPOSID);
            fbController.AddParameter("@BSNR_TIMESTAMP", bsn.BSNR_TIMESTAMP);
            fbController.AddParameter("@BSNR_N_LASTUSER", bsn.BSNR_N_LASTUSER);
            string sql = @"UPDATE BELEGSN SET
BSNR_N_POSID = @BSNR_N_POSID,
BSNR_A_SN = @BSNR_A_SN,
BSNR_N_CHARGE = @BSNR_N_CHARGE,
BSNR_N_MENGE = @BSNR_N_MENGE,
BSNR_N_STLPOSID = @BSNR_N_STLPOSID,
BSNR_TIMESTAMP = @BSNR_TIMESTAMP,
BSNR_N_LASTUSER = @BSNR_N_LASTUSER
WHERE BSNR_N_ID = @BSNR_N_ID";

            await fbController.QueryAsync(sql);
        }


    }
}
