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
{
    /// <summary>
    /// Stellt Funktionen zur Verwaltungen von <see cref="Kundenkontakt"/>en zur Verfügung
    /// </summary>
    public class KundenkontaktService : IModelService<Kundenkontakt, int>
    {
        public async Task CreateAsync(Kundenkontakt input, FbController2 fbController)
        {
            input.KUKO_N_LASTUSER = fbController.UserId;
            fbController.AddParameter("@KUKO_A_KUNDNR", input.KUKO_A_KUNDNR);
            fbController.AddParameter("@KUKO_D_DATE", input.KUKO_D_DATE);
            fbController.AddParameter("@KUKO_T_TIME", input.KUKO_T_TIME);
            fbController.AddParameter("@KUKO_N_ART", input.KUKO_N_ART);
            fbController.AddParameter("@KUKO_L_WIEDERV_ERL", input.KUKO_L_WIEDERV_ERL);
            fbController.AddParameter("@KUKO_D_WIEDERV_DATE", input.KUKO_D_WIEDERV_DATE);
            fbController.AddParameter("@KUKO_T_WIEDERV_TIME", input.KUKO_T_WIEDERV_TIME);
            fbController.AddParameter("@KUKO_N_WIEDERV_USER", input.KUKO_N_WIEDERV_USER);
            fbController.AddParameter("@KUKO_A_PARTNER", input.KUKO_A_PARTNER);
            fbController.AddParameter("@KUKO_N_LASTUSER", input.KUKO_N_LASTUSER);
            fbController.AddParameter("@KUKO_WK5_B_LANGNOTIZ", input.KUKO_WK5_B_LANGNOTIZ);
            fbController.AddParameter("@KUKO_WK5_A_BETREFF", input.KUKO_WK5_A_BETREFF);
            fbController.AddParameter("@KUKO_N_BELEGNR_AU", input.KUKO_N_BELEGNR_AU);
            fbController.AddParameter("@KUKO_N_BELEGNR_AN", input.KUKO_N_BELEGNR_AN);
            fbController.AddParameter("@KUKO_N_BELEGNR", input.KUKO_N_BELEGNR);
            fbController.AddParameter("@KUKO_A_BELEGTYP", input.KUKO_A_BELEGTYP);

            object? idObj = await fbController.FetchObjectAsync(@"INSERT INTO KUNDENKONTAKTE
(
KUKO_N_ID, 
KUKO_A_KUNDNR, 
KUKO_D_DATE, 
KUKO_T_TIME, 
KUKO_N_ART, 
KUKO_D_WIEDERV_DATE,
KUKO_T_WIEDERV_TIME, 
KUKO_N_WIEDERV_USER, 
KUKO_A_PARTNER, 
KUKO_TIMESTAMP,
KUKO_N_LASTUSER, 
KUKO_WK5_B_LANGNOTIZ, 
KUKO_L_WIEDERV_ERL, 
KUKO_WK5_A_BETREFF,
KUKO_N_BELEGNR_AU,
KUKO_N_BELEGNR_AN,
KUKO_N_BELEGNR,
KUKO_A_BELEGTYP
)
VALUES
(
(SELECT NEXT VALUE FOR GEN_KUKO_N_ID FROM RDB$DATABASE), 
@KUKO_A_KUNDNR, 
@KUKO_D_DATE, 
@KUKO_T_TIME, 
@KUKO_N_ART, 
@KUKO_D_WIEDERV_DATE,
@KUKO_T_WIEDERV_TIME, 
@KUKO_N_WIEDERV_USER, 
@KUKO_A_PARTNER, 
CURRENT_TIMESTAMP,
@KUKO_N_LASTUSER, 
@KUKO_WK5_B_LANGNOTIZ, 
@KUKO_L_WIEDERV_ERL, 
@KUKO_WK5_A_BETREFF,
@KUKO_N_BELEGNR_AU,
@KUKO_N_BELEGNR_AN,
@KUKO_N_BELEGNR,
@KUKO_A_BELEGTYP
)
            RETURNING KUKO_N_ID");

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

            if (int.TryParse(idObj?.ToString(), out int KUKO_N_ID))
            {
                input.KUKO_N_ID = KUKO_N_ID;
            }
        }
        public async Task UpdateAsync(Kundenkontakt input, FbController2 fbController)
        {
            fbController.AddParameter("@KUKO_A_KUNDNR", input.KUKO_A_KUNDNR);
            fbController.AddParameter("@KUKO_D_DATE", input.KUKO_D_DATE);
            fbController.AddParameter("@KUKO_T_TIME", input.KUKO_T_TIME);
            fbController.AddParameter("@KUKO_N_ART", input.KUKO_N_ART);
            fbController.AddParameter("@KUKO_D_WIEDERV_DATE", input.KUKO_D_WIEDERV_DATE);
            fbController.AddParameter("@KUKO_T_WIEDERV_TIME", input.KUKO_T_WIEDERV_TIME);
            fbController.AddParameter("@KUKO_N_WIEDERV_USER", input.KUKO_N_WIEDERV_USER);
            fbController.AddParameter("@KUKO_A_PARTNER", input.KUKO_A_PARTNER);
            fbController.AddParameter("@KUKO_WK5_B_LANGNOTIZ", StringErweiterung.ConvertEncoding(input.KUKO_WK5_B_LANGNOTIZ, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@KUKO_N_ID", input.KUKO_N_ID);
            fbController.AddParameter("@KUKO_L_WIEDERV_ERL", input.KUKO_L_WIEDERV_ERL);
            fbController.AddParameter("@KUKO_WK5_A_BETREFF", input.KUKO_WK5_A_BETREFF);
            fbController.AddParameter("@KUKO_WK5_N_NOTIFICATION_ID", input.KUKO_WK5_N_NOTIFICATION_ID);
            fbController.AddParameter("@KUKO_N_LASTUSER", fbController.UserId);
            fbController.AddParameter("@KUKO_N_BELEGNR", input.KUKO_N_BELEGNR);
            fbController.AddParameter("@KUKO_A_BELEGTYP", input.KUKO_A_BELEGTYP);


            await fbController.QueryAsync(@"UPDATE KUNDENKONTAKTE SET
KUKO_A_KUNDNR = @KUKO_A_KUNDNR,
KUKO_D_DATE = @KUKO_D_DATE, 
KUKO_T_TIME = @KUKO_T_TIME, 
KUKO_N_ART = @KUKO_N_ART, 
KUKO_D_WIEDERV_DATE = @KUKO_D_WIEDERV_DATE, 
KUKO_T_WIEDERV_TIME = @KUKO_T_WIEDERV_TIME, 
KUKO_N_WIEDERV_USER = @KUKO_N_WIEDERV_USER, 
KUKO_A_PARTNER = @KUKO_A_PARTNER, 
KUKO_TIMESTAMP = CURRENT_TIMESTAMP, 
KUKO_WK5_B_LANGNOTIZ = @KUKO_WK5_B_LANGNOTIZ,
KUKO_WK5_A_BETREFF = @KUKO_WK5_A_BETREFF,
KUKO_L_WIEDERV_ERL = @KUKO_L_WIEDERV_ERL,
KUKO_WK5_N_NOTIFICATION_ID = @KUKO_WK5_N_NOTIFICATION_ID,
KUKO_N_LASTUSER = @KUKO_N_LASTUSER,
KUKO_N_BELEGNR = @KUKO_N_BELEGNR,
KUKO_A_BELEGTYP = @KUKO_A_BELEGTYP
WHERE KUKO_N_ID = @KUKO_N_ID");
        }
        public async Task<Kundenkontakt?> GetAsync(int identifier, FbController2 fbController)
        {
            fbController.AddParameter("@KUKO_N_ID", identifier);
            DataRow? row = await fbController.SelectRowAsync("SELECT * FROM KUNDENKONTAKTE WHERE KUKO_N_ID = @KUKO_N_ID");
            return row is null ? null : ObjectErweiterung.DataRowZuObjekt(new Kundenkontakt(), row);
        }
        /// <summary>
        /// Liefert für einen <see cref="KundenkontaktFilter"/> alle Kundenkontakte zurück.
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="fbController"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async IAsyncEnumerable<Kundenkontakt> GetAsync(KundenkontaktFilter 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 Kundenkontakt(), row);
            }
        }
        /// <summary>
        /// Liefert die Anzahl aller Ergebnisse für <see cref="GetAsync(KundenkontaktFilter, FbController2, CancellationToken)"/> zurück.
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="fbController"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<int> GetTotalAmountAsync(KundenkontaktFilter 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;
        }
        /// <summary>
        /// Löscht einen Kundenkontakt
        /// </summary>
        /// <param name="input"></param>
        /// <param name="fbController"></param>
        /// <returns></returns>
        public async Task DeleteAsync(Kundenkontakt input, FbController2 fbController)
        {
            fbController.AddParameter("@KUKO_N_ID", input.KUKO_N_ID);
            await fbController.QueryAsync("DELETE FROM KUNDENKONTAKTE WHERE KUKO_N_ID = @KUKO_N_ID");
        }
    }
}
