using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
using WK5.Core.Models;
using WK5.Core.Models.API;
using WK5.Core.Models.API.Enumeration;

namespace WK5.Core.Services
{
    public class RegalfinderService
    {
        private readonly ArtikelService _artikelService;

        public RegalfinderService(ArtikelService artikelService)
        {
            _artikelService = artikelService;
        }
        public async Task<RegalFinderResponse> ChangeHerstellernummerAsync(string artikelnummer, string herstellernummer)
        {
            using FbController2 _fbController = new FbController2();
            Artikel? artikel = await _artikelService.GetAsync(artikelnummer, _fbController);

            if (artikel is null)
            {
                return new RegalFinderResponse
                {
                    Message = $"Artikel {artikelnummer.ToUpper()} konnte nicht gefunden werden.",
                    Status = RegalFinderStatus.ArtikelNichtGefunden,
                    Success = false
                };
            }

            _fbController.AddParameter("@ARTIKELNUMMER", artikel.Artikelnummer);
            _fbController.AddParameter("@MPN", herstellernummer);
            await _fbController.QueryAsync("UPDATE ARTIKEL SET ARTI_A_HERST_NR = @MPN WHERE UPPER(ARTI_A_NR) = @ARTIKELNUMMER");

            return new RegalFinderResponse
            {
                Message = $"Herstellernummer wurde erfolgreich für den Artikel {artikel.Artikelnummer} aktualisiert",
                Status = RegalFinderStatus.OK,
                Success = true
            };
        }

        public async Task<RegalFinderResponse> ChangeEanAsync(string artikelnummer, string ean)
        {
            using FbController2 _fbController = new FbController2();
            Artikel? artikel = await _artikelService.GetAsync(artikelnummer, _fbController);

            if (artikel is null)
            {
                return new RegalFinderResponse
                {
                    Message = $"Artikel {artikelnummer.ToUpper()} konnte nicht gefunden werden.",
                    Status = RegalFinderStatus.ArtikelNichtGefunden,
                    Success = false
                };
            }

            ean = StringErweiterung.ParseEan(ean);

            _fbController.AddParameter("@ARTIKELNUMMER", artikel.Artikelnummer);
            _fbController.AddParameter("@EAN", ean);
            await _fbController.QueryAsync("UPDATE ARTIKEL SET ARTI_A_EAN = @EAN WHERE UPPER(ARTI_A_NR) = @ARTIKELNUMMER");

            return new RegalFinderResponse
            {
                Message = $"EAN wurde erfolgreich für den Artikel {artikel.Artikelnummer} aktualisiert",
                Status = RegalFinderStatus.OK,
                Success = true
            };
        }

        public async Task<RegalFinderResponse> ChangeLagerplatzAsync(string artikelnummer, string lagerplatz)
        {
            using FbController2 _fbController = new FbController2();
            Artikel? artikel = await _artikelService.GetAsync(artikelnummer, _fbController);

            if (artikel is null)
            {
                return new RegalFinderResponse
                {
                    Message = $"Artikel {artikelnummer.ToUpper()} konnte nicht gefunden werden.",
                    Status = RegalFinderStatus.ArtikelNichtGefunden,
                    Success = false
                };
            }

            _fbController.AddParameter("@ARTIKELNUMMER", artikel.Artikelnummer);
            _fbController.AddParameter("@LAGERPLATZ", lagerplatz);
            await _fbController.QueryAsync("UPDATE ARTIKEL SET ARTI_A_LAGER = @LAGERPLATZ WHERE UPPER(ARTI_A_NR) = @ARTIKELNUMMER");

            return new RegalFinderResponse
            {
                Message = $"Lagerplatz des Artikels {artikel.Artikelnummer} wurde erfolgreich aktualisiert.",
                Status = RegalFinderStatus.OK,
                Success = true
            };
        }

        public async Task<RegalFinderResponse> AssoziationsnummerHinzufügenAsync(string artikelnummer, string alternativArtikelnummer)
        {
            using FbController2 _fbController = new FbController2();
            alternativArtikelnummer = alternativArtikelnummer.ToUpper();
            Artikel? artikel = await _artikelService.GetAsync(artikelnummer, _fbController);

            if (artikel is null)
            {
                return new RegalFinderResponse
                {
                    Message = $"Artikel {artikelnummer.ToUpper()} konnte nicht gefunden werden.",
                    Status = RegalFinderStatus.ArtikelNichtGefunden,
                    Success = false
                };
            }

            _fbController.AddParameter("@REPLACE_A_PRODUKT", alternativArtikelnummer);
            _fbController.AddParameter("@REPLACE_A_UNSERE", artikel.Artikelnummer);
            await _fbController.QueryAsync("UPDATE OR INSERT INTO WK5_ARTIKELNUMMER_REPLACE (REPLACE_A_PRODUKT, REPLACE_A_UNSERE) VALUES (@REPLACE_A_PRODUKT, @REPLACE_A_UNSERE) MATCHING (REPLACE_A_PRODUKT)");

            return new RegalFinderResponse
            {
                Message = $"Assoziationsnummer {alternativArtikelnummer} wurde dem Artikel {artikel.Artikelnummer} hinzugefügt.",
                Status = RegalFinderStatus.OK,
                Success = true
            };
        }

        public async Task<RegalFinderResponse> DruckEtikettAsync(string artikelnummer, int menge = 1)
        {
            using FbController2 _fbController = new FbController2();
            if (menge <= 0)
            {
                menge = 1;
            }

            Artikel? artikel = await _artikelService.GetAsync(artikelnummer, _fbController);

            if (artikel is null)
            {
                return new RegalFinderResponse
                {
                    Message = $"Artikel {artikelnummer.ToUpper()} konnte nicht gefunden werden.",
                    Status = RegalFinderStatus.ArtikelNichtGefunden,
                    Success = false
                };
            }

            for (int i = 0; i < menge; i++)
            {
                artikel.PrintEtikett();
            }

            return await Task.FromResult(new RegalFinderResponse
            {
                Message = "Artikeletikett erfolgreich gerdruckt",
                Status = RegalFinderStatus.OK,
                Success = true
            });

        }
        public async Task<RegalFinderResponse> DeleteAssoziationsnummerAsync(string assoziationsnummer)
        {
            using FbController2 _fbController = new FbController2();
            _fbController.AddParameter("@REPLACE_A_PRODUKT", assoziationsnummer);
            await _fbController.QueryAsync("DELETE FROM WK5_ARTIKELNUMMER_REPLACE WHERE REPLACE_A_PRODUKT = @REPLACE_A_PRODUKT");

            return new RegalFinderResponse
            {
                Message = $"Assoziationsnummer {assoziationsnummer} wurde erfolgreich gelöscht.",
                Status = RegalFinderStatus.OK,
                Success = true
            };
        }

        public async IAsyncEnumerable<ArtikelAssoziation> GetArtikelAssoziationenAsync()
        {
            using FbController2 _fbController = new FbController2();
            var data = await _fbController.SelectDataAsync("SELECT * FROM WK5_ARTIKELNUMMER_REPLACE");
            foreach (DataRow row in data.Rows)
            {
                yield return new ArtikelAssoziation(row["REPLACE_A_UNSERE"].ToString()!, row["REPLACE_A_PRODUKT"].ToString()!);
            }
        }
        public async Task<RegalFinderResponse> GetCurrentLagerplatzAsync(string artikelnummer)
        {
            using FbController2 _fbController = new FbController2();
            Artikel? artikel = await _artikelService.GetAsync(artikelnummer, _fbController);

            if (artikel is null)
            {
                return new RegalFinderResponse
                {
                    Message = $"Artikel {artikelnummer.ToUpper()} konnte nicht gefunden werden.",
                    Status = RegalFinderStatus.ArtikelNichtGefunden,
                    Success = false
                };
            }

            Lagerplatz? lager = await Lagerplatz.GetLagerAsync(artikel.Lagerplatz ?? String.Empty);
            string? lagerplatz = lager?.LAGE_A_NAME ?? "Unbekannt";

            return await Task.FromResult(new RegalFinderResponse
            {
                Message = $"{artikel.Artikelnummer}<br /><strong>{lagerplatz}</strong><br />Bedarf: <strong><a href=\"/Tools/ArtikelBedarf/{artikel.Artikelnummer}\">{artikel.Bedarf}<a></strong><br />Bestand: <strong>{artikel.Bestand}</strong>",
                Status = RegalFinderStatus.OK,
                Success = true
            });

        }

        /// <summary>
        /// Ruft alle Assoziationen von Artikelnummern ab.
        /// </summary>
        /// <returns></returns>
        public async IAsyncEnumerable<ArtikelAssoziation> GetAssoziationsnummernAsync()
        {
            using FbController2 _fbController = new FbController2();
            var data = await _fbController.SelectDataAsync("SELECT * FROM WK5_ARTIKELNUMMER_REPLACE");

            foreach (DataRow row in data.Rows)
            {
                yield return new ArtikelAssoziation(row["REPLACE_A_UNSERE"].ToString()!, row["REPLACE_A_PRODUKT"].ToString()!);
            }
        }
    }
}
