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

namespace WK5.Core.Models
{
    /// <summary>
    /// Repräsentiert die Tabelle CHARGEN aus der Datenbank
    /// </summary>
    public class Charge : ICloneable
    {
        private string _aktuellerLagerplatz = string.Empty;
        private string _bezeichnung1 = string.Empty;
        private string _bezeichnung2 = string.Empty;
        #region Datenbankfelder
        public string CHAR_A_ARTINR { get; set; } = String.Empty;
        public string? CHAR_A_GRUND { get; set; }
        public string? CHAR_A_HERSTELLER { get; set; }
        public string? CHAR_A_HILFSMITTEL { get; set; }
        public string? CHAR_A_LAGERPLATZ { get; set; }
        public string? CHAR_A_NOTIZ { get; set; }
        public string? CHAR_B_NOTIZEN { get; set; }
        public DateTime CHAR_D_MHD { get; set; }
        public bool CHAR_L_GESPERRT { get; set; }
        public bool CHAR_L_GEBRAUCHT { get; set; }
        public bool CHAR_L_STEUERFREI { get; set; }
        public int CHAR_N_AB_NR { get; set; }
        public int CHAR_N_BESTNR { get; set; }
        public int CHAR_N_BESTPOS { get; set; }
        public int CHAR_N_FA { get; set; }
        public int CHAR_N_KONTROLLNR { get; set; }
        public int CHAR_N_LASTUSER { get; set; }
        public int CHAR_N_NR { get; set; }
        public int CHAR_N_PROJEKT_NR { get; set; }
        public int CHAR_N_STAPELNR { get; set; }
        public int CHAR_N_STEUERSATZ { get; set; }
        public decimal CHAR_N_EKPREIS { get; set; }
        public decimal CHAR_N_EKPREIS_ORG { get; set; }
        public decimal CHAR_N_MENGE { get; set; }
        public decimal CHAR_N_MENGENFAKTOR { get; set; }
        public decimal CHAR_N_BESTMENGE { get; set; }
        public decimal CHAR_N_MENGEOFFEN { get; set; }
        public decimal CHAR_N_RABATT { get; set; }
        public decimal CHAR_N_RABATT2 { get; set; }
        public decimal CHAR_N_TRANSPORTK { get; set; }
        public DateTime CHAR_TIMESTAMP { get; set; }
        public string LIEF_A_NAME1 { get; set; } = String.Empty;
        public DateTime ZUGA_D_DATUM { get; set; }
        public int ARTI_N_ERLOESKONTO { get; set; }

        [CompareField("ARTI_A_BEZ1")]
        public string Bezeichnung1 { get => _bezeichnung1; set => _bezeichnung1 = value ?? string.Empty; }
        [CompareField("ARTI_A_BEZ2")]
        public string Bezeichnung2 { get => _bezeichnung2; set => _bezeichnung2 = value ?? string.Empty; }
        [CompareField("ARTI_A_LAGER")]
        public string AktuellerLagerplatz { get => _aktuellerLagerplatz; set => _aktuellerLagerplatz = value ?? string.Empty; }
        #endregion

        public string GetBezeichnung() => Regex.Replace($"{Bezeichnung1} {Bezeichnung2}", "  +/g", " ").Trim();

        /// <summary>
        /// Lädt eine Charge aus der Datenbank mit der entsprechenden Chargennummer
        /// </summary>
        /// <param name="CHAR_N_NR">Die Chargennummer die geladen werden soll</param>
        /// <returns>Gibt ein Objekt der Klasse <see cref="Charge"/> zurück das die Werte aus der Datenbank enthält</returns>
        public static async Task<Charge?> GetChargeAsync(int CHAR_N_NR, FbController2 fbController)
        {
            fbController.AddParameter("@CHARNR", CHAR_N_NR);
            var row = await fbController.SelectRowAsync(@"
SELECT C.*, ARTI_N_ERLOESKONTO, ARTI_A_LAGER, ARTI_A_BEZ1, ARTI_A_BEZ2
FROM CHARGEN C
LEFT JOIN ARTIKEL A ON A.ARTI_A_NR = C.CHAR_A_ARTINR
WHERE CHAR_N_NR = @CHARNR");



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

        public static async IAsyncEnumerable<Charge> GetChargenAsync(int ZUGA_N_NR, FbController2 fbController)
        {
            fbController.AddParameter("@CHAR_N_STAPELNR", ZUGA_N_NR);
            var data = await fbController.SelectDataAsync(@"
SELECT C.*, ARTI_N_ERLOESKONTO, ARTI_A_LAGER, ARTI_A_BEZ1, ARTI_A_BEZ2
FROM CHARGEN C
LEFT JOIN ARTIKEL A ON A.ARTI_A_NR = C.CHAR_A_ARTINR
WHERE CHAR_N_STAPELNR = @CHAR_N_STAPELNR");
            foreach (DataRow row in data.Rows)
            {
                yield return ObjectErweiterung.DataRowZuObjekt(new Charge(), row);
            }
        }

        public static async IAsyncEnumerable<Charge> GetChargenAsync(string CHAR_A_ARTINR, FbController2 fbController)
        {
            fbController.AddParameter("@CHAR_A_ARTINR", CHAR_A_ARTINR);
            DataTable data = await fbController.SelectDataAsync(@"
SELECT C.*, ARTI_N_ERLOESKONTO, ARTI_A_LAGER, ARTI_A_BEZ1, ARTI_A_BEZ2
FROM CHARGEN C
LEFT JOIN ARTIKEL A ON A.ARTI_A_NR = C.CHAR_A_ARTINR
WHERE CHAR_A_ARTINR = @CHAR_A_ARTINR");

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

        }

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
}
