using KarleyLibrary.Attributes;
using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Net;
using System.Threading.Tasks;

namespace WK5.Core.OpenCart.Karley
{
    public class KarleyProduct : Product
    {
        private string _youtube = String.Empty;
        private string _shortDescriptionEN = String.Empty;
        private string _shortDescription = String.Empty;
        private string _taxonomy = "Elektronik > Drucker-, Kopierer-, Scanner- ";
        private string _cachedName = String.Empty;
        private string _sonderAngebotArt = "Sonderangebot";
        private string _shortHeadText = String.Empty;
        private string _mFilterValues = String.Empty;
        private string _mFilterTags = String.Empty;

        public string? Video { get; set; }
        public string Youtube { get => _youtube; set => _youtube = value ?? String.Empty; }
        public string? Family { get; set; } = String.Empty;
        [CompareField("quantity_intern")]
        public int QuantityIntern { get; set; }
        [CompareField("quantity_extern")]
        public int QuantityExtern { get; set; }
        [CompareField("preis_auf_anfrage")]
        public bool PreisAufAnfrage { get; set; } = false;
        [CompareField("short_descriptionEN")]
        public string ShortDescriptionEN { get => _shortDescriptionEN; set => _shortDescriptionEN = value ?? String.Empty; }
        [CompareField("short_description")]
        public string ShortDescription { get => _shortDescription; set => _shortDescription = value ?? String.Empty; }                
        public bool Abverkauf { get; set; } = false;
        public decimal DirectPrice { get; set; } = 0.0m;
        public bool MultipleMinimumQty { get; set; } = false;
        public bool MusterButton { get; set; } = false;
        public bool MietButton { get; set; } = false;
        public bool VPE { get; set; } = false;
        public string Taxonomy { get => _taxonomy; set => _taxonomy = value ?? String.Empty; }
        [CompareField("cached_name")]
        public string CachedName { get => _cachedName; set => _cachedName = value ?? String.Empty; }
        public string SonderAngebotArt { get => _sonderAngebotArt; set => _sonderAngebotArt = value ?? String.Empty; }
        [CompareField("short_headtext")]
        public string ShortHeadText { get => _shortHeadText; set => _shortHeadText = value ?? String.Empty; }
        [CompareField("jt_verfuegbar")]
        public bool JTVerfügbar { get; set; } = false;
        public int Warranty { get; set; } = 12;
        [CompareField("mfilter_values")]
        public string MFilterValues { get => _mFilterValues; set => _mFilterValues = value ?? String.Empty; }
        [CompareField("mfilter_tags")]
        public string MFilterTags { get => _mFilterTags; set => _mFilterTags = value ?? String.Empty; }
        [CompareField("preis_nach_login")]
        public bool PreisNachLogin { get; set; } = false;
        public static async Task<KarleyProduct?> GetProductAsync(int product_id)
        {
            return await GetProductAsync<KarleyProduct>(new KarleyProduct(), product_id, GlobalConfig.KarleyMySql);
        }

        public static async Task<KarleyProduct?> GetProductByNameAsync(string name)
        {
            using MySqlController2 mySqlController = new MySqlController2(GlobalConfig.KarleyMySql);

            mySqlController.AddParameter("@name", name);
            DataRow? row = await mySqlController.SelectRowAsync("SELECT * FROM `product` p LEFT JOIN `product_description` pd ON p.product_id = pd.product_id WHERE pd.name = @name");
            return row == null ? null : ObjectErweiterung.DataRowZuObjekt<KarleyProduct>(new KarleyProduct(), row);
        }

        public static async Task<KarleyProduct?> GetProductAsync(string model)
        {
            return await GetProductAsync<KarleyProduct>(new KarleyProduct(), model, GlobalConfig.KarleyMySql);
        }

        public async Task UpdateProductAsync()
        {
            using MySqlController2 mySqlController = new MySqlController2(GlobalConfig.KarleyMySql);

            string baseProps = GetUpdateProperties(mySqlController);

            string sql = $@"UPDATE `product` SET
{baseProps}
video = @video,
youtube = @youtube,
family = @family,
quantity_intern = @quantity_intern,
quantity_extern = @quantity_extern,
preis_auf_anfrage = @preis_auf_anfrage,
short_descriptionEN = @short_descriptionEN,
short_description = @short_description,
abverkauf = @abverkauf,
directprice = @directprice,
multipleminimumqty = @multipleminimumqty,
musterbutton = @musterbutton,
mietbutton = @mietbutton,
vpe = @vpe,
taxonomy = @taxonomy,
cached_name = @cached_name,
sonderangebotArt = @sonderangebotArt,
short_headtext = @short_headtext,
jt_verfuegbar = @jt_verfuegbar,
warranty = @warranty,
mfilter_values = @mfilter_values,
mfilter_tags = @mfilter_tags,
preis_nach_login = @preis_nach_login

WHERE product_id = @product_id";

            mySqlController.AddParameter("@video", Video);
            mySqlController.AddParameter("@youtube", Youtube);
            mySqlController.AddParameter("@family", Family);
            mySqlController.AddParameter("@quantity_intern", QuantityIntern);
            mySqlController.AddParameter("@quantity_extern", QuantityExtern);
            mySqlController.AddParameter("@preis_auf_anfrage", PreisAufAnfrage ? 1 : 0);
            mySqlController.AddParameter("@short_descriptionEN", ShortDescriptionEN);
            mySqlController.AddParameter("@short_description", ShortDescription);            
            mySqlController.AddParameter("@abverkauf", Abverkauf ? 1 : 0);
            mySqlController.AddParameter("@directprice", DirectPrice);
            mySqlController.AddParameter("@multipleminimumqty", MultipleMinimumQty.ToOpencartBool());
            mySqlController.AddParameter("@musterbutton", MusterButton ? 1 : 0);
            mySqlController.AddParameter("@mietbutton", MietButton ? 1 : 0);
            mySqlController.AddParameter("@vpe", VPE);
            mySqlController.AddParameter("@taxonomy", Taxonomy);
            mySqlController.AddParameter("@cached_name", CachedName);
            mySqlController.AddParameter("@sonderangebotArt", SonderAngebotArt);
            mySqlController.AddParameter("@short_headtext", ShortHeadText);
            mySqlController.AddParameter("@jt_verfuegbar", JTVerfügbar ? 1 : 0);
            mySqlController.AddParameter("@warranty", Warranty);
            mySqlController.AddParameter("@mfilter_values", MFilterValues);
            mySqlController.AddParameter("@mfilter_tags", MFilterTags);
            mySqlController.AddParameter("@preis_nach_login", PreisNachLogin ? 1 : 0);

            await mySqlController.QueryAsync(sql);
        }

        public static async Task UpdateProductAsync(KarleyProduct product)
        {
            await product.UpdateProductAsync();
        }

        public IAsyncEnumerable<KarleyProduct> GetZubehörAsync()
        {
            using MySqlController2 mySqlController = new MySqlController2(GlobalConfig.KarleyMySql);
            return GetZubehörAsync<KarleyProduct>(mySqlController);
        }

        public IAsyncEnumerable<KarleyProduct> GetZubehörAsync(MySqlController2 mySqlController)
        {
            return GetZubehörAsync<KarleyProduct>(mySqlController);
        }

        public Task DeleteZubehörAsync(int related_id)
        {
            using MySqlController2 mySqlController = new MySqlController2(GlobalConfig.KarleyMySql);
            return DeleteZubehörAsync(related_id, mySqlController);
        }        

        public Task AddZubehörAsync(int related_id)
        {
            using MySqlController2 mySqlController = new MySqlController2(GlobalConfig.KarleyMySql);
            return AddZubehörAsync(related_id, mySqlController);
        }

        public Task<string?> DownloadImage(string targetPath)
        {
            
            string remoteImageLink = $"{KarleyProductImage.OPENCART_IMAGE_BASE}{Image}";
            string? dirname = Path.GetDirectoryName(targetPath);
            if (String.IsNullOrWhiteSpace(dirname))
            {
                return Task.FromResult<string?>(null);
            }

            (bool success, string nachricht) dirResult = FileErweiterung.EnsureCreateDirectory(dirname);

            if (dirResult.success)
            {
                try
                {
                    using WebClient client = new WebClient();
                    client.DownloadFileAsync(new Uri(remoteImageLink), targetPath);
                    return Task.FromResult<string?>(targetPath);
                }
                catch(Exception)
                {
                    return Task.FromResult<string?>(null);
                }
            }

            return Task.FromResult<string?>(null);
        }

    }
}
