using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using WK5.Core.Email;

namespace WK5.Core.Models
{
    public class ArtikelDokument
    {
        public int ARDI_N_NR { get; set; }
        public string ARDI_A_ARTINR { get; set; } = String.Empty;
        public string ARDI_A_REL_DOCPFAD { get; set; } = String.Empty;
        public bool ARDI_L_IN_VERSAND { get; set; } = false;



        public static string DokumentenRoot { get; set; } = Path.Combine(GlobalConfig.WWWRoot, "assets/dokumente");


        public static async IAsyncEnumerable<ArtikelDokument> GetArtikelDokumenteAsync(string ARTI_A_NR)
        {
            using FbController2 fbController = new FbController2();
            await foreach (ArtikelDokument dokument in GetArtikelDokumenteAsync(ARTI_A_NR, fbController))
            {
                yield return dokument;
            }
        }
        public static async IAsyncEnumerable<ArtikelDokument> GetArtikelDokumenteAsync(string ARTI_A_NR, FbController2 fbController)
        {
            string sql = "SELECT * FROM WK5_ARTIKELDOKUMENTE WHERE ARDI_A_ARTINR = @ARDI_A_ARTINR";
            fbController.AddParameter("@ARDI_A_ARTINR", ARTI_A_NR);
            DataTable data = await fbController.SelectDataAsync(sql);

            foreach (DataRow row in data.Rows)
            {
                if (row is not null)
                {
                    yield return ObjectErweiterung.DataRowZuObjekt(new ArtikelDokument(), row);
                }
            }
        }

        public static async Task DeleteArtikelDokumentAsync(int ARDI_N_NR)
        {
            using FbController2 fbController = new FbController2();
            await DeleteArtikelDokumentAsync(ARDI_N_NR, fbController);
        }
        public static async Task DeleteArtikelDokumentAsync(int ARDI_N_NR, FbController2 fbController)
        {
            string sql = "DELETE FROM WK5_ARTIKELDOKUMENTE WHERE ARDI_N_NR = @ARDI_N_NR";
            fbController.AddParameter("@ARDI_N_NR", ARDI_N_NR);
            await fbController.QueryAsync(sql);
        }

        public static async Task UpdateArtikelDokumentAsync(ArtikelDokument dokument)
        {
            using FbController2 fbController = new FbController2();

            await UpdateArtikelDokumentAsync(dokument, fbController);


        }
        public static async Task UpdateArtikelDokumentAsync(ArtikelDokument dokument, FbController2 fbController)
        {

            fbController.AddParameter("@ARDI_A_ARTINR", dokument.ARDI_A_ARTINR);
            fbController.AddParameter("@ARDI_A_REL_DOCPFAD", dokument.ARDI_A_REL_DOCPFAD);
            fbController.AddParameter("@ARDI_N_NR", dokument.ARDI_N_NR);
            fbController.AddParameter("@ARDI_L_IN_VERSAND", dokument.ARDI_L_IN_VERSAND);

            string sql = @"UPDATE WK5_ARTIKELDOKUMENTE SET 
ARDI_A_ARTINR = @ARDI_A_ARTINR,
ARDI_A_REL_DOCPFAD = @ARDI_A_REL_DOCPFAD,
ARDI_L_IN_VERSAND = @ARDI_L_IN_VERSAND
WHERE ARDI_N_NR = @ARDI_N_NR";

            await fbController.QueryAsync(sql);


        }

        public static async Task<ArtikelDokument> CreateArtikelDokumentAsync(ArtikelDokument dokument)
        {
            using FbController2 fbController = new FbController2();

            return await CreateArtikelDokumentAsync(dokument, fbController);
        }

        public static async Task<ArtikelDokument> CreateArtikelDokumentAsync(ArtikelDokument dokument, FbController2 fbController)
        {
            fbController.AddParameter("@ARDI_A_ARTINR", dokument.ARDI_A_ARTINR);
            fbController.AddParameter("@ARDI_A_REL_DOCPFAD", dokument.ARDI_A_REL_DOCPFAD);
            fbController.AddParameter("@ARDI_L_IN_VERSAND", dokument.ARDI_L_IN_VERSAND);

            string sql = @"INSERT INTO WK5_ARTIKELDOKUMENTE (ARDI_A_ARTINR, ARDI_A_REL_DOCPFAD, ARDI_L_IN_VERSAND)
VALUES
(@ARDI_A_ARTINR, @ARDI_A_REL_DOCPFAD, @ARDI_L_IN_VERSAND)
RETURNING ARDI_N_NR";

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

            if (idObj is not null)
            {
                dokument.ARDI_N_NR = Convert.ToInt32(idObj);
            }

            return dokument;
        }

        public async Task<byte[]> GetBytesAsync()
        {
            string pfad = Path.Combine(DokumentenRoot, ARDI_A_REL_DOCPFAD);

            return await File.ReadAllBytesAsync(pfad);
        }

        public EmailAnhang ToEmailAnhang()
        {
            string pfad = Path.Combine(DokumentenRoot, ARDI_A_REL_DOCPFAD);
            return new EmailAnhang()
            {
                Name = Path.GetFileName(pfad),
                Pfad = pfad
            };
        }

        public static async IAsyncEnumerable<ArtikelDokument> GetArtikelDokumenteAsync(Beleg beleg)
        {
            foreach (Belegposition pos in beleg.GetEndPositionen())
            {
                await foreach (ArtikelDokument dokument in GetArtikelDokumenteAsync(pos.Artikelnummer))
                {
                    yield return dokument;
                }
            }
        }



        public bool Exists()
        {
            return File.Exists(Path.Combine(DokumentenRoot, ARDI_A_REL_DOCPFAD));
        }

        public async Task<byte[]?> GetFileAsync(CancellationToken cts = default)
        {
            string absoluteFilePath = Path.Combine(DokumentenRoot, ARDI_A_REL_DOCPFAD);
            if (!File.Exists(absoluteFilePath))
            {
                return null;
            }
            else
            {
                return await File.ReadAllBytesAsync(absoluteFilePath, cts);
            }
        }

    }
}