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

namespace WK5.Core.Models
{
    /// <summary>
    /// Stellt ein Paket aus der W4 dar.
    /// </summary>
    public class W4Paket
    {
        #region Datenbankfelder
        #region Alphanumerisch
        public string? PAKE_A_ABS_LAND { get; set; }
        public string? PAKE_A_ABS_NAME1 { get; set; }
        public string? PAKE_A_ABS_NAME2 { get; set; }
        public string? PAKE_A_ABS_ORT { get; set; }
        public string? PAKE_A_ABS_PLZ { get; set; }
        public string? PAKE_A_ABS_STR { get; set; }
        public string? PAKE_A_EMP_LAND { get; set; }
        public string? PAKE_A_EMP_NAME1 { get; set; }
        public string? PAKE_A_EMP_NAME2 { get; set; }
        public string? PAKE_A_EMP_NAME3 { get; set; }
        public string? PAKE_A_EMP_ORT { get; set; }
        public string? PAKE_A_EMP_PLZ { get; set; }
        public string? PAKE_A_EMP_STR { get; set; }
        public string? PAKE_A_KUNDNR { get; set; }
        public string? PAKE_A_NOTIZ { get; set; }
        public string? PAKE_A_NR { get; set; }
        public string PAKE_A_TYP { get; set; } = String.Empty;
        #endregion
        #region Logisch
        public bool PAKE_L_LS { get; set; }
        public bool PAKE_L_SAMSTAG { get; set; }
        public bool PAKE_L_VERSENDET { get; set; }
        #endregion
        #region Numerisch
        public int PAKE_N_BELENR { get; set; }
        public int PAKE_N_EXPRESSART { get; set; }
        public int PAKE_N_ID { get; set; }
        public int PAKE_N_LASTUSER { get; set; }
        public int PAKE_N_LFDNR { get; set; }
        public int PAKE_N_VERSENDER { get; set; }
        public decimal PAKE_N_WERT { get; set; }
        public decimal PAKE_N_GEWICHT { get; set; }
        #endregion
        #region Datum und Zeit
        public DateTime PAKE_D_VERSANDDATE { get; set; }
        public DateTime PAKE_T_DATUM { get; set; }
        public DateTime PAKE_TIMESTAMP { get; set; }
        #endregion
        #endregion

        /// <summary>
        /// Holt sich ein Paket aus der Datenbank anhand seiner Id
        /// </summary>
        /// <param name="PAKE_N_ID">Die zu suchende Id</param>
        /// <returns>Gibt ein Objekt der Klasse <see cref="Paket"/> zurück</returns>
        public static async Task<W4Paket?> GetPaketAsync(int PAKE_N_ID)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@PAKE_N_ID", PAKE_N_ID);
            var row = await fbController.SelectRowAsync("SELECT * FROM PAKETE WHERE PAKE_N_ID = @PAKE_N_ID");
            return row is null ? null : ObjectErweiterung.DataRowZuObjekt(new W4Paket(), row);
        }

        /// <summary>
        /// Holt sich ein Paket aus der Datenbank anhand seiner Tracking Nummer
        /// </summary>
        /// <param name="Tracknr">Die zu suchende Tracking Nummer</param>
        /// <returns>Gibt ein Objekt der Klasse <see cref="Paket"/> zurück</returns>
        public static async Task<W4Paket?> GetPaketByTrackingnummerAsync(string trackingnummer)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@TRACKINGNUMMER", trackingnummer);
            var row = await fbController.SelectRowAsync("SELECT * FROM PAKETE WHERE PAKE_A_NR = @TRACKINGNUMMER");

            return row is null ? null : ObjectErweiterung.DataRowZuObjekt<W4Paket>(new W4Paket(), row);
        }

        /// <summary>
        /// Fügt ein Objekt der Klasse <see cref="Paket"/> in die Datenbank ein
        /// </summary>
        /// <param name="paket">Das Paket das in die Datenbank eingefügt werden soll</param>
        /// <returns>Gibt einen <see cref="bool"/> zurück der angibt ob die Operation erfolgreich war</returns>

        public static async Task<bool> InsertPaketAsync(W4Paket paket)
        {
            using FbController2 fbController = new FbController2();

            fbController.AddParameter("@PAKE_A_NR", paket.PAKE_A_NR);
            fbController.AddParameter("@PAKE_A_KUNDNR", paket.PAKE_A_KUNDNR);
            fbController.AddParameter("@PAKE_T_DATUM", paket.PAKE_T_DATUM);
            fbController.AddParameter("@PAKE_N_BELENR", paket.PAKE_N_BELENR);
            fbController.AddParameter("@PAKE_N_LFDNR", paket.PAKE_N_LFDNR);
            fbController.AddParameter("@PAKE_A_TYP", paket.PAKE_A_TYP);
            fbController.AddParameter("@PAKE_L_LS", paket.PAKE_L_LS);
            fbController.AddParameter("@PAKE_N_VERSENDER", paket.PAKE_N_VERSENDER);
            fbController.AddParameter("@PAKE_N_WERT", paket.PAKE_N_WERT);
            fbController.AddParameter("@PAKE_N_GEWICHT", paket.PAKE_N_GEWICHT);
            fbController.AddParameter("@PAKE_L_VERSENDET", paket.PAKE_L_VERSENDET);
            fbController.AddParameter("@PAKE_N_EXPRESSART", paket.PAKE_N_EXPRESSART);
            fbController.AddParameter("@PAKE_L_SAMSTAG", paket.PAKE_L_SAMSTAG);
            fbController.AddParameter("@PAKE_A_EMP_NAME1", StringErweiterung.SafeSubstring(paket.PAKE_A_EMP_NAME1, 0, 60));
            fbController.AddParameter("@PAKE_A_EMP_NAME2", StringErweiterung.SafeSubstring(paket.PAKE_A_EMP_NAME2, 0, 60));
            fbController.AddParameter("@PAKE_A_EMP_NAME3", StringErweiterung.SafeSubstring(paket.PAKE_A_EMP_NAME3, 0, 60));
            fbController.AddParameter("@PAKE_A_EMP_STR", StringErweiterung.SafeSubstring(paket.PAKE_A_EMP_STR, 0, 40));
            fbController.AddParameter("@PAKE_A_EMP_LAND", paket.PAKE_A_EMP_LAND);
            fbController.AddParameter("@PAKE_A_EMP_PLZ", paket.PAKE_A_EMP_PLZ);
            fbController.AddParameter("@PAKE_A_EMP_ORT", paket.PAKE_A_EMP_ORT);
            fbController.AddParameter("@PAKE_A_ABS_NAME1", paket.PAKE_A_ABS_NAME1);
            fbController.AddParameter("@PAKE_A_NOTIZ", paket.PAKE_A_NOTIZ);

            string sql = @"INSERT INTO PAKETE
(
PAKE_A_NR, PAKE_A_KUNDNR, PAKE_T_DATUM, PAKE_N_BELENR,
PAKE_N_LFDNR, PAKE_A_TYP, PAKE_L_LS, PAKE_N_VERSENDER,
PAKE_N_WERT, PAKE_N_GEWICHT, PAKE_L_VERSENDET, PAKE_N_EXPRESSART,
PAKE_L_SAMSTAG, PAKE_A_EMP_NAME1, PAKE_A_EMP_NAME2, PAKE_A_EMP_NAME3,
PAKE_A_EMP_STR, PAKE_A_EMP_LAND, PAKE_A_EMP_PLZ, PAKE_A_EMP_ORT, PAKE_A_ABS_NAME1,
PAKE_A_NOTIZ
)
VALUES
(
@PAKE_A_NR, @PAKE_A_KUNDNR, @PAKE_T_DATUM, @PAKE_N_BELENR,
@PAKE_N_LFDNR, @PAKE_A_TYP, @PAKE_L_LS, @PAKE_N_VERSENDER,
@PAKE_N_WERT, @PAKE_N_GEWICHT, @PAKE_L_VERSENDET, @PAKE_N_EXPRESSART,
@PAKE_L_SAMSTAG, @PAKE_A_EMP_NAME1, @PAKE_A_EMP_NAME2, @PAKE_A_EMP_NAME3,
@PAKE_A_EMP_STR, @PAKE_A_EMP_LAND, @PAKE_A_EMP_PLZ, @PAKE_A_EMP_ORT, @PAKE_A_ABS_NAME1,
@PAKE_A_NOTIZ
)";
            try
            {

                await fbController.QueryAsync(sql);
            }
            catch (Exception ex)
            {

                return false;
            }
            return true;
        }

        /// <summary>
        /// Holt sich eine neue PAKE_N_LFDNR aus der Datenbank.
        /// <para>
        /// Der Wert repräsentiert eine fortlaufende Nummer. Beispiel: Paket 1, Paket 2, Paket 3 usw.
        /// </para>
        /// </summary>
        /// <param name="PAKE_A_TYP">Der Belegtyp zu dem die Paketnummer gehören soll</param>
        /// <param name="PAKE_N_BELENR">Die Belegnummer zu dem das Paket gehören soll</param>
        /// <returns>Gibt einen <see cref="int"/> zurück der eine neue PAKE_N_LFDNR repräsentiert</returns>
        public static async Task<int> GetNeuePaketNummerAsync(string PAKE_A_TYP, int PAKE_N_BELENR)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@PAKE_A_TYP", PAKE_A_TYP);
            fbController.AddParameter("@PAKE_N_BELENR", PAKE_N_BELENR);
            var row = await fbController.SelectRowAsync("SELECT PAKE_N_LFDNR FROM PAKETE WHERE PAKE_A_TYP = @PAKE_A_TYP AND PAKE_N_BELENR = @PAKE_N_BELENR ORDER BY PAKE_N_LFDNR ASC");

            return row is null ? 1 : (int)row["PAKE_N_LFDNR"] + 1;
        }
        public static async IAsyncEnumerable<W4Paket> GetVorgangsPakete(BelegTyp belegTyp, int belegnummer)
        {
            string sql = @"SELECT * FROM PAKETE P
WHERE 
(PAKE_A_TYP = 'AU' AND PAKE_N_BELENR = (SELECT BELE_N_NR_AU FROM BELEGE WHERE BELE_A_TYP = @PAKE_A_TYP AND BELE_N_NR = @PAKE_N_BELENR)) OR
(PAKE_A_TYP = 'LS' AND PAKE_N_BELENR = (SELECT BELE_N_NR_LS FROM BELEGE WHERE BELE_A_TYP = @PAKE_A_TYP AND BELE_N_NR = @PAKE_N_BELENR)) OR
(PAKE_A_TYP = 'RE' AND PAKE_N_BELENR = (SELECT BELE_N_NR_RE FROM BELEGE WHERE BELE_A_TYP = @PAKE_A_TYP AND BELE_N_NR = @PAKE_N_BELENR)) OR
(PAKE_A_TYP = 'GU' AND PAKE_N_BELENR = (SELECT BELE_N_NR_GU FROM BELEGE WHERE BELE_A_TYP = @PAKE_A_TYP AND BELE_N_NR = @PAKE_N_BELENR))";

            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@PAKE_A_TYP", EnumHelper.GetBelegTypString(belegTyp));
            fbController.AddParameter("@PAKE_N_BELENR", belegnummer);

            DataTable data = await fbController.SelectDataAsync(sql);
            foreach (DataRow row in data.Rows)
            {
                yield return ObjectErweiterung.DataRowZuObjekt(new W4Paket(), row);
            }
        }

    }
}
