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

namespace WK5.Core.Services
{
    public class LieferantenkontaktService : IModelService<LieferantenKontakt, int>
    {

        public async Task CreateAsync(LieferantenKontakt input, FbController2 fbController)
        {
            input.LFKO_N_LASTUSER = fbController.UserId;
            fbController.AddParameter("@LFKO_N_LFNR", input.LFKO_N_LFNR);
            fbController.AddParameter("@LFKO_N_BESTELLNR", input.LFKO_N_BESTELLNR);
            fbController.AddParameter("@LFKO_N_ART", input.LFKO_N_ART);
            fbController.AddParameter("@LFKO_D_DATE", input.LFKO_D_DATE);
            fbController.AddParameter("@LFKO_T_TIME", input.LFKO_T_TIME);
            fbController.AddParameter("@LFKO_N_LASTUSER", input.LFKO_N_LASTUSER);
            fbController.AddParameter("@LFKO_N_PARTNER", input.LFKO_N_PARTNER);
            fbController.AddParameter("@LFKO_B_LANGNOTIZ", StringErweiterung.ConvertEncoding(input.LFKO_B_LANGNOTIZ, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@LFKO_L_WIEDERV_ERL", input.LFKO_L_WIEDERV_ERL);
            fbController.AddParameter("@LFKO_D_WIEDERV_DATE", input.LFKO_D_WIEDERV_DATE);
            fbController.AddParameter("@LFKO_T_WIEDERV_TIME", input.LFKO_T_WIEDERV_TIME);
            fbController.AddParameter("@LFKO_N_WIEDERV_USER", input.LFKO_N_WIEDERV_USER);
            fbController.AddParameter("@LFKO_A_BETREFF", input.LFKO_A_BETREFF);
            fbController.AddParameter("@LFKO_A_BELEGTYP", input.LFKO_A_BELEGTYP);
            fbController.AddParameter("@LFKO_N_BELEGNUMMER", input.LFKO_N_BELEGNUMMER);

            string sql = @"INSERT INTO WK5_LIEFERANTENKONTAKTE
(
    LFKO_N_LFNR, 
    LFKO_N_BESTELLNR, 
    LFKO_N_ART, 
    LFKO_D_DATE, 
    LFKO_T_TIME, 
    LFKO_B_LANGNOTIZ, 
    LFKO_N_LASTUSER, 
    LFKO_N_PARTNER, 
    LFKO_A_BETREFF, 
    LFKO_L_WIEDERV_ERL, 
    LFKO_D_WIEDERV_DATE, 
    LFKO_T_WIEDERV_TIME, 
    LFKO_N_WIEDERV_USER,
    LFKO_A_BELEGTYP,
    LFKO_N_BELEGNUMMER
)
VALUES
(
    @LFKO_N_LFNR, 
    @LFKO_N_BESTELLNR, 
    @LFKO_N_ART, 
    @LFKO_D_DATE, 
    @LFKO_T_TIME, 
    @LFKO_B_LANGNOTIZ, 
    @LFKO_N_LASTUSER, 
    @LFKO_N_PARTNER, 
    @LFKO_A_BETREFF, 
    @LFKO_L_WIEDERV_ERL, 
    @LFKO_D_WIEDERV_DATE, 
    @LFKO_T_WIEDERV_TIME, 
    @LFKO_N_WIEDERV_USER,
    @LFKO_A_BELEGTYP,
    @LFKO_N_BELEGNUMMER
)
RETURNING LFKO_N_ID";

            object? idObj = await fbController.FetchObjectAsync(sql);

            if (idObj is null)
            {
                throw new Exception("#WK5_ADD_LIEFERANTENKONTAKT - Beim einfügen des Lieferantenkontakt konnte keine LFKO_N_ID zurückgegeben werden. Bitte der Programmierung Bescheid geben.");
            }

            if (int.TryParse(idObj?.ToString(), out int LFKO_N_ID))
            {
                input.LFKO_N_ID = LFKO_N_ID;
            }
        }

        public async Task<LieferantenKontakt?> GetAsync(int identifier, FbController2 fbController)
        {
            fbController.AddParameter("@LFKO_N_ID", identifier);
            DataRow? row = await fbController.SelectRowAsync("SELECT * FROM WK5_LIEFERANTENKONTAKTE WHERE LFKO_N_ID = @LFKO_N_ID");
            return row is null ? null : ObjectErweiterung.DataRowZuObjekt(new LieferantenKontakt(), row);
        }

        public async IAsyncEnumerable<LieferantenKontakt> GetAsync(LieferantenkontaktFilter filter, FbController2 fbController, [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            DataTable data = await fbController.SelectDataAsync(filter.ToSqlQuery(fbController));

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

        public async Task<int> GetTotalAmountAsync(LieferantenkontaktFilter filter, FbController2 fbController, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            object? wert = await fbController.FetchObjectAsync(filter.ToCountQuery(fbController));

            if(wert is null)
            {
                return 0;
            }

            if(int.TryParse(wert.ToString(), out int anzahl))
            {
                return anzahl;
            }

            return 0;
        }

        public async Task UpdateAsync(LieferantenKontakt input, FbController2 fbController)
        {
            fbController.AddParameter("@LFKO_N_LFNR", input.LFKO_N_LFNR);
            fbController.AddParameter("@LFKO_N_BESTELLNR", input.LFKO_N_BESTELLNR);
            fbController.AddParameter("@LFKO_N_ART", input.LFKO_N_ART);
            fbController.AddParameter("@LFKO_D_DATE", input.LFKO_D_DATE);
            fbController.AddParameter("@LFKO_T_TIME", input.LFKO_T_TIME);
            fbController.AddParameter("@LFKO_N_LASTUSER", input.LFKO_N_LASTUSER);
            fbController.AddParameter("@LFKO_N_ID", input.LFKO_N_ID);
            fbController.AddParameter("@LFKO_N_PARTNER", input.LFKO_N_PARTNER);
            fbController.AddParameter("@LFKO_B_LANGNOTIZ", StringErweiterung.ConvertEncoding(input.LFKO_B_LANGNOTIZ, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@LFKO_A_BETREFF", input.LFKO_A_BETREFF);
            fbController.AddParameter("@LFKO_L_WIEDERV_ERL", input.LFKO_L_WIEDERV_ERL);
            fbController.AddParameter("@LFKO_D_WIEDERV_DATE", input.LFKO_D_WIEDERV_DATE);
            fbController.AddParameter("@LFKO_T_WIEDERV_TIME", input.LFKO_T_WIEDERV_TIME);
            fbController.AddParameter("@LFKO_N_WIEDERV_USER", input.LFKO_N_WIEDERV_USER);
            fbController.AddParameter("@LFKO_WK5_N_NOTIFICATION_ID", input.LFKO_WK5_N_NOTIFICATION_ID);
            fbController.AddParameter("@LFKO_A_BELEGTYP", input.LFKO_A_BELEGTYP);
            fbController.AddParameter("@LFKO_N_BELEGNUMMER", input.LFKO_N_BELEGNUMMER);

            await fbController.QueryAsync(@"UPDATE WK5_LIEFERANTENKONTAKTE SET
LFKO_N_LFNR = @LFKO_N_LFNR, 
LFKO_N_BESTELLNR = @LFKO_N_BESTELLNR, 
LFKO_N_ART = @LFKO_N_ART, 
LFKO_D_DATE = @LFKO_D_DATE, 
LFKO_T_TIME = @LFKO_T_TIME, 
LFKO_B_LANGNOTIZ = @LFKO_B_LANGNOTIZ, 
LFKO_N_LASTUSER = @LFKO_N_LASTUSER, 
LFKO_N_PARTNER = @LFKO_N_PARTNER, 
LFKO_A_BETREFF = @LFKO_A_BETREFF,
LFKO_L_WIEDERV_ERL = @LFKO_L_WIEDERV_ERL,
LFKO_D_WIEDERV_DATE = @LFKO_D_WIEDERV_DATE,
LFKO_T_WIEDERV_TIME = @LFKO_T_WIEDERV_TIME,
LFKO_N_WIEDERV_USER = @LFKO_N_WIEDERV_USER,
LFKO_WK5_N_NOTIFICATION_ID = @LFKO_WK5_N_NOTIFICATION_ID,
LFKO_A_BELEGTYP = @LFKO_A_BELEGTYP,
LFKO_N_BELEGNUMMER = @LFKO_N_BELEGNUMMER
WHERE LFKO_N_ID = @LFKO_N_ID");
        }

        public async Task DeleteAsync(LieferantenKontakt input, FbController2 fbController)
        {
            fbController.AddParameter("@LFKO_N_ID", input.LFKO_N_ID);
            await fbController.QueryAsync("DELETE FROM WK5_LIEFERANTENKONTAKTE WHERE LFKO_N_ID = @LFKO_N_ID");
        }
    }
}
