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.Models;

namespace WK5.Core.Services
{
    /// <summary>
    /// Stellt Funktionen zum einlagern von Artikeln zur Verfügung.
    /// </summary>
    public class WareEinlagernService
    {
        /// <summary>
        /// Ruft für ein bestimmtes Datum alle Artikel ab, die noch eingelagert werden müssen.
        /// </summary>
        /// <param name="datum"></param>
        /// <param name="fbController"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async IAsyncEnumerable<WareEinlagernArtikel> GetArtikelAsync(DateTime datum, FbController2 fbController, [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            fbController.AddParameter("@ZUGA_D_DATUM", datum);
            DataTable data = await fbController.SelectDataAsync(@"SELECT 
CHAR_A_ARTINR, 
SUM(CHAR_N_MENGEOFFEN) AS MENGE,
(SELECT ARTI_A_LAGER FROM ARTIKEL WHERE ARTI_A_NR = C.CHAR_A_ARTINR),
(SELECT ARTI_A_BEZ1 FROM ARTIKEL WHERE ARTI_A_NR = C.CHAR_A_ARTINR),
(SELECT ARTI_A_BEZ2 FROM ARTIKEL WHERE ARTI_A_NR = C.CHAR_A_ARTINR)
FROM ZUGAENGE Z 
LEFT JOIN CHARGEN C ON C.CHAR_N_STAPELNR = Z.ZUGA_N_NR
WHERE ZUGA_D_DATUM = @ZUGA_D_DATUM 
GROUP BY CHAR_A_ARTINR
HAVING SUM(CHAR_N_MENGEOFFEN) > 0", cancellationToken);

            foreach (DataRow row in data.Rows)
            {
                cancellationToken.ThrowIfCancellationRequested();
                yield return ObjectErweiterung.DataRowZuObjekt(new WareEinlagernArtikel(), row);
            }
        }
        /// <summary>
        /// Setzt den aktuellen Lagerplatz für einen Artikel.
        /// </summary>
        /// <param name="artikel"></param>
        /// <param name="fbController"></param>
        /// <returns></returns>
        public async Task SetLagerplatzAsync(WareEinlagernArtikel artikel, FbController2 fbController)
        {
            fbController.AddParameter("@ARTI_A_LAGER", artikel.Lagerplatz);
            fbController.AddParameter("@ARTI_A_NR", artikel.Artikelnummer);
            await fbController.QueryAsync("UPDATE ARTIKEL SET ARTI_A_LAGER = @ARTI_A_LAGER WHERE ARTI_A_NR = @ARTI_A_NR");
        }
        /// <summary>
        /// Ruft für ein bestimmtes Datum alle Seriennummern für eine Artikelnummer ab, die zugebucht worden sind.
        /// </summary>
        /// <param name="datum"></param>
        /// <param name="artikelnummer"></param>
        /// <param name="fbController"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async IAsyncEnumerable<string> GetSeriennummernAsync(DateTime datum, string artikelnummer, FbController2 fbController, [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            fbController.AddParameter("@ZUGA_D_DATUM", datum);
            fbController.AddParameter("@CHAR_A_ARTINR", artikelnummer);
            DataTable data = await fbController.SelectDataAsync(@"SELECT SN.SNNR_A_SN FROM ZUGAENGE Z
INNER JOIN CHARGEN C ON Z.ZUGA_N_NR = C.CHAR_N_STAPELNR
INNER JOIN SN ON SN.SNNR_N_CHARGE = C.CHAR_N_NR
WHERE Z.ZUGA_D_DATUM = @ZUGA_D_DATUM AND CHAR_A_ARTINR = @CHAR_A_ARTINR");

            foreach (DataRow row in data.Rows)
            {
                cancellationToken.ThrowIfCancellationRequested();
                string seriennummer = row.Field<string>("SNNR_A_SN") ?? string.Empty;

                if(!string.IsNullOrWhiteSpace(seriennummer))
                {
                    yield return seriennummer;
                }
            }
        }
    }
}
