using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WooCommerceNET;
using WooCommerceNET.Base;
using WooCommerceNET.WooCommerce.v3;
//using WooCommerceNET.WooCommerce;


namespace SVS_XDWooSync_Isolcasa
{
    public partial class Form1 : Form
    {

        //INICIALIZAÇÃO DAS VARS
        public Form1()
        {
            InitializeComponent();
            this.lbVersao.Text = Application.ProductVersion;

            //globals.csXD = @"server=192.168.1.5;port=3308;userid=root;password=xd;database=xdisolcasa";
            //globals.WooURL = @"https://demos.svs.pt/wp/wp-json/wc/v3/";
            //globals.WooCK = "ck_a291b94a98ad3aee84ea103f5c046e9e90648790";
            //globals.WooCS = "cs_2df32822f1d708421a094116431197927cc23297";
            



            


            globals.csXD = @"server=127.0.0.1;port=3308;userid=root;password=Pa$$w0rdMySQL;database=xdisolcasa";
            globals.WooCK = "ck_430d7d95b2c117a262a0319cb7ad7906240930d2";
            globals.WooCS = "cs_a53e43b62f1c6c105a897ff28aec2891153918cc";
            globals.WooURL = "https://isolcasa.pt/wp/wp-json/wc/v3/";

            //const string consumerKey = "ck_a291b94a98ad3aee84ea103f5c046e9e90648790";
            //const string consumerSecret = "cs_2df32822f1d708421a094116431197927cc23297";
            //const string host = "https://demos.svs.pt/wp/wp-json/wc/v3/";
        }

        //------------AUXILIARES-----------------------

        private void ResponseFilter(HttpWebResponse response)
        {
            //var total = int.Parse(response.Headers["X-WP-Total"]);
            //var pagecount = int.Parse(response.Headers["X-WP-TotalPages"]);
            var statuscode = response.StatusCode; //int.Parse(response.Headers["StatusCode"]);
            var location = response.Method; // int.Parse(response.Headers["Location"]);
            var body = response.Headers;
            var resposta = response.GetResponseStream();
        }
        private void RequestFilter(HttpWebRequest request)
        {
            request.UserAgent = "SVS XDWooSync";
        }

        async Task PutTaskDelay()
        {
            await Task.Delay(5000);
        }


        //------------AUXILIARES-----------------------

        private async void btTestWoo_Click(object sender, EventArgs e)
        {

            try
            {

                RestAPI rest = new RestAPI(globals.WooURL, globals.WooCK,globals.WooCS, requestFilter: RequestFilter, responseFilter: ResponseFilter);
                WCObject wc = new WCObject(rest);

                //Get all products
                //var allproducts = wc.Product.GetAll().GetAwaiter().GetResult();
                //var allproductss = wc.Product.GetAll().Status;

                MyProduct prod = new MyProduct()
                {
                    sku = "154-454",
                    name = "produto de teste",
                    description = "Descrição do produto",
                    regular_price = 10,
                    manage_stock = true,
                    stock_quantity = 10,
                    ficha_tecnica = "ghghhgghhghguiui",
                    meta_data = new List<WooCommerceNET.WooCommerce.v2.ProductMeta>
                    {
                        new WooCommerceNET.WooCommerce.v2.ProductMeta()
                        {
                            id = 76665,
                            value = "SVS"
                        }
                    }
                };
                var result = await wc.Product.Add(prod);



                return;
                List<ProductCategory> existingCategories = await wc.Category.GetAll();

                ProductCategory newCategoryMale = new ProductCategory
                {
                    name = "MALE"
                };
                ProductCategory maleCategory = await wc.Category.Add(newCategoryMale);
                ProductCategory newCategoryShoes = new ProductCategory
                {
                    name = "shoes",
                    parent = maleCategory.id
                };
                ProductCategory shoes = await wc.Category.Add(newCategoryShoes);

                //Product prod = new Product()
                //{
                //    sku = "xxxxxx",
                //    name = Name,
                //    description = "Descrição do produto",
                //    regular_price = 10,
                //    manage_stock = true,
                //    stock_quantity = 10,
                //    categories = new List<ProductCategoryLine>
                //        {
                //            new ProductCategoryLine
                //            {
                //                id = shoes.id
                //            }
                //        },
                //    meta_data = new List<WooCommerceNET.WooCommerce.v2.ProductMeta>
                //    {
                //        new WooCommerceNET.WooCommerce.v2.ProductMeta()
                //        {
                //            key = "madeby",
                //            value = "SVS"
                //        }
                //    }
                //};

            }
            catch (WebException ex)
            {
                MessageBox.Show("Exception caught." + ex.Message + " : " + ex.HResult + " : " + ex.Response.Headers);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Exception caught." + ex.Message + " : " + ex.Source + " : " + ex.InnerException);
            }
        }
//############################################################
//                 SQL
//
//############################################################
        
        private async void btTestMaria_ClickAsync(object sender, EventArgs e)
        {
            picLoading.Show();
            picLoading.Update();
            try
            {
                var result = await woobatch();
                
            }
            catch (Exception ex)
            {
                //Handle Exception
            }
            picLoading.Hide();

        }

        //======= será necessário?
        private static int? FindProduct(Product obj)
        {
            return obj.id;
        }

        private async Task<Boolean> woobatch()
        {

            // INICIALIZO AS VARIAVEIS PARA ME LIGAR AO SQL          
            var con = new MySqlConnection(globals.csXD);
            // ABRO E TESTO A LIGAÇÃO
            con.Open();
            try
            {
                string sql = @"SELECT * FROM svs_vwos_items where IsToBeOnline=1";
                var cmd = new MySqlCommand(sql, con);

                // PREPARO E USO DATA ADAPTER
                MySqlDataAdapter MyDA = new MySqlDataAdapter();
                MyDA.SelectCommand = new MySqlCommand(sql, con);

                // CRIO E INICIALIZO DATA TABLE COM QUE VOU TRABALHAR
                DataTable XDItems = new DataTable();
                MyDA.Fill(XDItems);

                BindingSource bSource = new BindingSource();
                bSource.DataSource = XDItems;
                //dataGridView1.DataSource = bSource;

                //var dictTable = DataTableToDictionaryList(table);

                //DataView dataView = XDItems.DefaultView;
                ////dataView.RowFilter = "KeyId like '128%'";
                //dataGridView1.DataSource = dataView;


                MySqlDataReader rdr = cmd.ExecuteReader();
                //this.dataGridView1.DataSource = rdr;
                //this.dataGridView1.Refresh();

                ProductBatch batchOnXD = new ProductBatch();

                //Product <ProductBatch> produtosOnXD = new List<ProductBatch>;
                //new List<Product>();

                RestAPI rest = new RestAPI(globals.WooURL, globals.WooCK, globals.WooCS, requestFilter: RequestFilter, responseFilter: ResponseFilter);
                WCObject wc = new WCObject(rest);

                Dictionary<string, string> qDic = new Dictionary<string, string>();
                qDic.Add("per_page", "50");

//--                List<Product> lpWoo = new List<Product>();
//--                lpWoo = Task<response> wc.Product.GetAll().GetAwaiter(qDic).GetResult();
//--                lpWoo = await wc.Product.GetAll(qDic).GetAwaiter().GetResult();

                List<Product> lp = new List<Product>();
                List<int> dlp = new List<int>();

                while (rdr.Read())
                {
                    
                    Product myproduct = new Product();
                    
                    //O SKU será a REF do XD
                    myproduct.sku = rdr["Ref"].ToString();
                    //O ID se não estiver no XD será pesquisado pelo SKU, se não for encontrado é criado novo artigo
                    //Product pId = globals.products.Find(x => x.sku.Equals(myproduct.sku));
                    //myproduct.id = pId.id;
                    //Console.WriteLine(pId.id.ToString());

                    //==========STOCK
                    var tipodedados = rdr["Stock"].GetType();
                    
                    var qtd = rdr["Stock"];




                    myproduct.stock_quantity = 0;
                    //myproduct.stock_quantity = Convert.ToInt32(qtd);
                    //myproduct.stock_status = "instock";

                    //myproduct.categories
                    
                    
                    //==========PREÇOS
                    myproduct.regular_price = Convert.ToDecimal(rdr["PrecoSemIva"] ?? 0);

                    if (rdr["CapacidadeUnid"].ToString() == "32")
                    {

                        myproduct.meta_data = new List<WooCommerceNET.WooCommerce.v2.ProductMeta>
                    {
                        new WooCommerceNET.WooCommerce.v2.ProductMeta()

                        {
                            key = "xd_refval_price",
                            value = rdr["PrecoUnidCap"]
                        },
                        new WooCommerceNET.WooCommerce.v2.ProductMeta()
                        {
                            key = "xd_refval_unit",
                            value = rdr["CapacidadeUnidade"]
                        }

                    };

                    }

                    if (rdr["OnlineNome"].ToString() + "" == "")
                    {
                        myproduct.name = rdr["Designacao"].ToString();
                    }
                    else
                    {
                        myproduct.name = rdr["Designacao"].ToString();
                    };
                    myproduct.short_description = rdr["OnlineDescCurta"].ToString();
                    myproduct.description = rdr["OnlineDescLonga"].ToString();
                    
                    //myproduct.weight = Convert.ToDecimal(rdr[""]);
                    myproduct.short_description = rdr["OnlineDescCurta"].ToString();
                    myproduct.enable_html_short_description = Boolean.TrueString;
                    



                    switch (cbBatchAction.SelectedItem) 
                    {
                        case "Delete":
                            //dlp.Add(myproduct.id);
                            break;
                        case "Update":
                            lp.Add(myproduct);

                            break;
                        case "Add":
                            lp.Add(myproduct);

                            break;
                        default:
                            
                            break;

                    }

                    

                    if (lp.Count == 50)
                    {

                        Console.WriteLine("========== Atingiu " + lp.Count + " ============");
                        //vamos fazer update destes


                        switch (cbBatchAction.SelectedItem)
                        {
                            case "Delete":
                                batchOnXD.delete = dlp;
                                var d = await wc.Product.DeleteRange(batchOnXD);
                                break;
                            case "Update":
                                batchOnXD.update = lp;
                                var u = await wc.Product.UpdateRange(batchOnXD);
                                break;
                            case "Add":
                                batchOnXD.create = lp;
                                var a = await wc.Product.AddRange(batchOnXD);
                                break;
                            default:
                                MessageBox.Show("Escolher modo de batch!");
                                break;

                        }
                        //vamos limpar o batch e continuar
                        lp.Clear();
                        dlp.Clear();
                        Console.WriteLine("========== PAUSA 5s ============");
                        //Thread.Sleep(5000);
                        await PutTaskDelay();
                    }

                    //fWoo woo = new fWoo();
                    //woo.createWooProduct(myproduct);

                }
                if (lp.Count > 0)
                {

                    Console.WriteLine("========== Restaram: " + lp.Count + " ============");
                    //vamos fazer update destes



                    switch (cbBatchAction.SelectedItem)
                    {
                        case "Add":
                            batchOnXD.create = lp;
                            var a = await wc.Product.AddRange(batchOnXD);
                            break;
                        case "Update":
                            batchOnXD.update = lp;
                            var u = await wc.Product.UpdateRange(batchOnXD);
                            break;
                        case "Delete":
                            //batchOnXD.delete = lp;
                            //var d = await wc.Product.DeleteRange(batchOnXD);
                            break;
                        default:
                            MessageBox.Show("Escolher modo de batch!");
                            break;

                    }
                    //vamos limpar o batch e continuar
                    lp.Clear();
                }

                return true;


                //###########################################################################

                //object p = await wc.Product.AddRange(produtosOnXD);



                //BatchObject<Product> a = await wc.Product.UpdateRange(batchOnXD);

                //List<string> noPass = (from Product prod in a.update
                //                       where prod.name is null
                //                       select prod.id.Value.ToString()).ToList();
                //return noPass;

                //string strQueryGetValue = "select description from items";
                //string strValue = fXD.GetValueFromDBUsing(strQueryGetValue);
                //if (strValue.Length > 0)
                //{
                //    MessageBox.Show("Found");
                //    MessageBox.Show(strValue);
                //}
                //else
                //    MessageBox.Show("Not Found");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString() + " | " + ex.Source.ToString() + " | " + ex.InnerException.ToString());
                return false;
            }
        }



        protected async Task<List<Product>> getAllProductsAsync()
        {

            RestAPI rest = new RestAPI(globals.WooURL, globals.WooCK, globals.WooCS, requestFilter: RequestFilter, responseFilter: ResponseFilter);
            WCObject wc = new WCObject(rest);

            Dictionary<string, string> dic = new Dictionary<string, string>();

            dic.Add("per_page", "100");
            int pageNumber = 1;
            dic.Add("page", pageNumber.ToString());
            List<Product> products = new List<Product>();

            bool endWhile = false;
            while (!endWhile)
            {
                List<Product> productsTemp = await wc.Product.GetAll(dic);
                if (productsTemp.Count > 0)
                {
                    products.AddRange(productsTemp);
                    pageNumber++;
                    dic["page"] = pageNumber.ToString();
                }
                else
                {
                    endWhile = true;
                }
            }

            return products;
            cbBatchAction.Enabled = true;
            

        }



        private void btRequeryDataGrid_Click(object sender, EventArgs e)
        {
        }

        private void btGetStock_Click(object sender, EventArgs e)
        {
            MessageBox.Show(fXD.getStockXD(txtItemKeyId.Text));
        }

        private void btTestaXD_Click(object sender, EventArgs e)
        {
            // INICIALIZO AS VARIAVEIS PARA ME LIGAR AO SQL          
            var con = new MySqlConnection(globals.csXD);
            // ABRO E TESTO A LIGAÇÃO
            
            
            try
            {
            con.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            finally
            {
                MessageBox.Show(con.State.ToString());
            }
            
        }

        private async void btTestaWoo_ClickAsync(object sender, EventArgs e)
        {
            try
            {
                RestAPI rest = new RestAPI(globals.WooURL, globals.WooCK, globals.WooCS, requestFilter: RequestFilter, responseFilter: ResponseFilter);
                WCObject wc = new WCObject(rest);

                //Get all products
                //var allproducts = wc.Product.GetAll().GetAwaiter().GetResult();
                //var allproductss = wc.Product.GetAll().Status;
              
                var result = await wc.Product.GetAll();             

            }
            catch (WebException ex)
            {
                MessageBox.Show("Exception caught." + ex.Message + " : " + ex.HResult + " : " + ex.Response.Headers);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Exception caught." + ex.Message + " : " + ex.Source + " : " + ex.InnerException);
            }
        }

        private async void btWooRefExiste_ClickAsync(object sender, EventArgs e)
        {

            int WooId = await GetWooProductBySkuAsync(txtItemKeyId.Text) ;
            if (WooId == 0) {
                MessageBox.Show("O artigo com "+txtSKU.Text+" não existe na Loja Online.");
            }
            else
            {
                MessageBox.Show("O artigo com " + txtSKU.Text + " tem o ID: " + WooId);
            }

        }


        private async Task<int> GetWooProductBySkuAsync(string sku)
        {
            RestAPI rest = new RestAPI(globals.WooURL, globals.WooCK, globals.WooCS, requestFilter: RequestFilter, responseFilter: ResponseFilter);
            WCObject wc = new WCObject(rest);

            //Get one product

            //string SKU = txtSKU.Text;

            //Product product = new Product();
            List<Product> products = new List<Product>();
            
            Dictionary<string, string> pDic = new Dictionary<string, string>();
            pDic.Add("sku", sku);

            //int? productIDfromSKU = 0;
            
            products = await wc.Product.GetAll(pDic);
            //products = await wc.Product.GetAll();

            if (products.Count == 1)
            {
                return Convert.ToInt32(products[0].id);
                //Instead of products[0] you can use products.FirstOrDefault()
                //products.First(), or products.Single() depending on what your code is expecting.
                //productIDfromSKU = products[0].id;
            }

            return 0;

        }

        private async void btGetAllProductsFromWoo_ClickAsync(object sender, EventArgs e)
        {
            globals.products = await getAllProductsAsync();

        }

        private void pbSettings_Click(object sender, EventArgs e)
        {
            Form form = new frmSettings();
            form.Show();
        }
    }
}