using System;
using System.Configuration;
using System.Data;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.ServiceModel;
using System.Text;
using System.Xml;
using AsignadorKits_Almex_ML;
using MySqlConnector;
using Newtonsoft.Json;
using ServiceReference1;
using tempuri.org;

namespace CreateLabel_ML
{
   public class Program
   {
      public static void Main(string[] args)
      {
         var log = new clsLog();
         try
         {
            var cotizaciones = new Cotizaciones();
            var query = ConfigurationManager.AppSettings["SPConsulta"];
            var cont = 0;
            var cn = new clsConexion();
            var data = cn.TraeDataTable(query, new MySqlParameter[] { }, CommandType.StoredProcedure);
            var dtRemitente = cn.TraeDataTable("SELECT * FROM warehouse WHERE warehouse_id=@warehouse_id", new[]
            {
               new MySqlParameter("@warehouse_id", ConfigurationManager.AppSettings["WareHouse_ID"])
            }, CommandType.Text);
            var drRemitente = dtRemitente.Rows[0];
            log.EscribeLog(data.Rows.Count + " pedidos.");
            foreach (DataRow order in data.Rows)
            {
               log.EscribeLog("----------");
               var so = order["sale_order_id"].ToString();
               // Variables para el ZPL
               var sale_order = "so: " + order["sale_order_id"];
               var sku = "sku: " + order["product_id"];
               var sellersku = "ssku: " + order["seller_sku"];
               var qty = "qty: " + order["quantity"];
               log.EscribeLog("soid: " + order["sale_order_id"]);
               log.EscribeLog("reference_order_number: " + order["reference_order_number"]);
               log.EscribeLog("qty: " + order["quantity"]);
               if (order.IsNull("pack_id") || order["pack_id"].ToString() == "")
               {
                  if (int.Parse(order["flag_creation_track"].ToString()) == 0)
                  {
                     // validamos stock disponible
                     var items_in_kit_list = cotizaciones.GetKitItems(int.Parse(order["product_id"].ToString()));
                     var inStock = false;
                     foreach (DataRow kit in items_in_kit_list.Rows)
                     {
                        var inStock_kit = cotizaciones.GetInStock(int.Parse(kit["kit_product_id"].ToString()), int.Parse(ConfigurationManager.AppSettings["WareHouse_ID"]), int.Parse(order["quantity"].ToString()) * int.Parse(kit["quantity"].ToString()));
                        inStock = inStock_kit >= 1;
                     }
                     if (inStock)
                     {
                        // ajustamos paqueteria
                        var carrier = string.Empty;
                        switch (order["carrier_name"].ToString())
                        {
                           case "FedEx Express Saver":
                           case "Fedex":
                           case "FedEx Standard Overnight":
                           case "FedEx a sucursal":
                           case "FedEx Standard Overnight a Sucursal":
                              carrier = "Fedex";
                              break;
                           case "Express":
                           case "DHL  a sucursal":
                           case "Est�ndar":
                              carrier = "DHL";
                              break;
                           case "UPS Express":
                              carrier = "UPS";
                              break;
                           case "Estafeta Est�ndar Domicilio":
                           case "Estafeta Estándar Domicilio":
                              carrier = "Estafeta";
                              break;
                           case "Paquetexpress normal a domicilio":
                              carrier = "Fedex";
                              break;
                           default:
                              carrier = order["carrier_name"].ToString();
                              break;
                        }
                        log.EscribeLog("carrier: " + carrier);
                        var zpl_code = "";
                        var seller_sku = order["seller_sku"].ToString().ToLower();
                        log.EscribeLog("seller_sku: " + seller_sku);
                        var new_zpl_code = "0";
                        var pdf_base64 = "0";
                        if (int.Parse(order["count_items_2"].ToString()) <= 1)
                        { // ===> Mercadolibre (solo los que no son carritos)
                          //die("58");
                           var modeloMercadoLibre = new mdlMercadoLibre();
                           modeloMercadoLibre.Login();
                           pdf_base64 = modeloMercadoLibre.GetLabelPDF(long.Parse(order["shipping_id_number"].ToString())); // se arma url para descargar guia en zpl
                                                                                                                            //die("<br />" . $zip_url);
                           if (string.Compare(pdf_base64, "0", StringComparison.CurrentCultureIgnoreCase) != 0)
                           {
                              var modelopdf = new clsPDF();
                              pdf_base64 = modelopdf.Base64Converter(pdf_base64, so, order["product_id"].ToString(), order["seller_sku"].ToString(), int.Parse(order["quantity"].ToString()), order["carrier_name"].ToString(), int.Parse(order["customer_id"].ToString()), order["reference_order_number"].ToString());
                           }
                           else
                           {
                              // no se pudo descargar guia, se descarga base64
                              log.EscribeLog("ERROR al descargar guia PDF");
                              var data_pdf = cn.TraeDataTable("SELECT tracking_base64 FROM sale_order_tracking_number WHERE sale_order_id = @sale_order_id order by date_created DESC LIMIT 1", new[]
                                 {
                                    new MySqlParameter("sale_order_id",so)
                                 }, CommandType.Text);
                              //die($data_pdf[0]["tracking_base64"]);
                              pdf_base64 = data_pdf.Rows[0]["tracking_base64"].ToString();
                           }
                           if (pdf_base64.Length < 10)
                           {
                              pdf_base64 = "0";
                              log.EscribeLog("ERROR al descargar guia base 64");
                              new_zpl_code = "0";
                           }
                        }
                        if (string.Compare(new_zpl_code, "0", StringComparison.CurrentCultureIgnoreCase) == 0 && string.Compare(pdf_base64, "0", StringComparison.CurrentCultureIgnoreCase) == 0)
                           log.EscribeLog("No se descargo guia correctamente, no se puede enviar pedido.");
                        else
                        {
                           log.EscribeLog("Procesando envio....");
                           if (string.Compare(ConfigurationManager.AppSettings["WareHouse_Reference"], "Almex", StringComparison.CurrentCultureIgnoreCase) == 0)
                           {
                              var a = 0;
                              var xml_post_string_kit = string.Empty;
                              foreach (DataRow kit in items_in_kit_list.Rows)
                              {
                                 a++;
                                 xml_post_string_kit += "<partidaList><skuId>" + kit["seller_sku"] + "</skuId><idPartida>" + a + "</idPartida><cantidad>" + (int.Parse(order["quantity"].ToString()) * int.Parse(kit["quantity"].ToString())) +
                                                        "</cantidad></partidaList>";
                              }
                              var xml_post_string = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.engine.ck.com/\">" +
                                                    "<soapenv:Header>" +
                                                    "<Usuario>desarrollo</Usuario>" +
                                                    "<Password>desa2013</Password>" +
                                                    "</soapenv:Header>" +
                                                    "<soapenv:Body><ws:requestOutputBean><output>" +
                                                    "<direccion>" +
                                                    "<calle>Necaxa</calle>" +
                                                    "<colonia>Portales Norte</colonia>" +
                                                    "<cp>03300</cp>" +
                                                    "<del_mun>Benito Juarez</del_mun>" +
                                                    "<entreCalles>Saratoga y Sevilla</entreCalles>" +
                                                    "<estado>Ciudad de Mexico</estado>" +
                                                    "<nombreRecibe>Mercadazo</nombreRecibe>" +
                                                    "<numeroExt>165</numeroExt>" +
                                                    "<numeroInt>BIS</numeroInt>" +
                                                    "<referencias>Porton Cafe</referencias>" +
                                                    "<telefonoContacto1>55555555</telefonoContacto1>" +
                                                    "<telefonoContacto2>555555555</telefonoContacto2>" +
                                                    "</direccion>" +
                                                    "<idPedido>" + so + "</idPedido>" +
                                                    xml_post_string_kit +
                                                    "<idTipoSalida>5</idTipoSalida>" +
                                                    "<fechaEntrega>" + DateTime.Now.ToString("yyyy-MM-dd") + "</fechaEntrega>" +
                                                    "<cuenta>2638</cuenta>" +
                                                    "<atributo1></atributo1>" +
                                                    "<guiaPdf>" + pdf_base64 + "</guiaPdf>" +
                                                    "<guia>" + order["tracking_number"] + "</guia>" +
                                                    "<claveTransporte>" + carrier + "</claveTransporte>" +
                                                    "<referenciaSalidaCliente></referenciaSalidaCliente>" +
                                                    "<salidaPrioridad>1</salidaPrioridad>" +
                                                    "</output></ws:requestOutputBean></soapenv:Body></soapenv:Envelope>";
                              //var_dump($xml_post_string);
                              //die();
                              var response_almex = string.Empty;
                              try
                              {
                                 var SoapByte = Encoding.UTF8.GetBytes(xml_post_string);
                                 ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
                                 var api_url = cn.TraeDataTable("SELECT `value` from m_configuration where `name` = 'ENDPOINT_ALMEX'", new MySqlParameter[] { }, CommandType.Text);
                                 var Request = WebRequest.Create(api_url.Rows[0][0].ToString());
                                 Request.Headers.Add("SOAPAction", "");
                                 Request.ContentType = "text/xml; charset=utf-8";
                                 Request.ContentLength = SoapByte.Length;
                                 Request.Method = "POST";
                                 var DataStream = Request.GetRequestStream();
                                 DataStream.Write(SoapByte, 0, SoapByte.Length);
                                 DataStream.Close();
                                 var Response = Request.GetResponse();
                                 DataStream = Response.GetResponseStream();
                                 var Reader = new StreamReader(DataStream);
                                 var SD2Request = Reader.ReadToEnd();
                                 // add tracking info
                                 log.AgregaPcgRequest(xml_post_string, SD2Request, "0", so, "Asignador Kits Almex");
                                 var xmlResponse = new XmlDocument();
                                 xmlResponse.LoadXml(SD2Request);
                                 response_almex = xmlResponse.GetElementsByTagName("return").Item(0).InnerXml;
                              }
                              catch (WebException wex)
                              {
                                 log.AgregaPcgRequest(xml_post_string, wex.Message, "0", so, "Asignador Kits Almex");
                                 response_almex = wex.Message;
                              }
                              catch (Exception ex)
                              {
                                 log.AgregaPcgRequest(xml_post_string, ex.Message, "0", so, "Asignador Kits Almex");
                                 response_almex = ex.Message;
                              }
                              if (string.Compare(response_almex, "OK", StringComparison.CurrentCultureIgnoreCase) == 0)
                              {
                                 log.EscribeLog("Pedido enviado correctamente");
                                 // descontamos inventario
                                 foreach (DataRow kit in items_in_kit_list.Rows)
                                 {
                                    cn.EjecutaConsulta("SP_ProductStockUpdate", new[]
                                    {
                                       new MySqlParameter("var_product_id", MySqlDbType.Int32)
                                       {
                                          Value = kit["kit_product_id"]
                                       },
                                       new MySqlParameter("var_quantity", MySqlDbType.Int32)
                                       {
                                          Value = int.Parse(order["quantity"].ToString()) * int.Parse(kit["quantity"].ToString())
                                       },
                                       new MySqlParameter("var_move_type", MySqlDbType.Int32)
                                       {
                                          Value = 3
                                       },
                                       new MySqlParameter("var_source_id", MySqlDbType.Int32)
                                       {
                                          Value = order["sale_order_id"]
                                       },
                                       new MySqlParameter("var_comments", MySqlDbType.VarChar)
                                       {
                                          Value = "Asignado por Asignador .Net"
                                       },
                                       new MySqlParameter("var_source_location_id", MySqlDbType.Int32)
                                       {
                                          Value = string.Compare(ConfigurationManager.AppSettings["WareHouse_Reference"], "Almex", StringComparison.CurrentCultureIgnoreCase) == 0
                                             ? 4
                                             : 398
                                       },
                                       new MySqlParameter("var_destination_location_id", MySqlDbType.Int32)
                                       {
                                          Value = 18
                                       }
                                    }, CommandType.StoredProcedure);
                                    log.EscribeLog("Stock Actualizado");
                                 }
                              }
                              else
                              {
                                 log.EscribeLog("Error: " + response_almex);
                              }
                           }
                           else
                           {
                                        //var dtCTI = cn.TraeDataTable("SELECT * FROM m_configuration WHERE name ='ENDPOINT_CTIGROUP'", new MySqlParameter[] { }, CommandType.Text);
                                        //var urlCTI = dtCTI.Rows[0]["value"].ToString();
                                        //var pedido = new Pedido
                                        //{
                                        //   carrier = carrier,
                                        //   sale_order_id = int.Parse(so),
                                        //   tracking_number = order["tracking_number"].ToString(),
                                        //   tracking = pdf_base64,
                                        //   items = (from DataRow kit in items_in_kit_list.Rows
                                        //      select new Items
                                        //      {
                                        //         quantity = int.Parse(order["quantity"].ToString()) *
                                        //                    int.Parse(kit["quantity"].ToString()),
                                        //         sku = kit["kit_product_id"].ToString()
                                        //      }).ToArray()
                                        //};
                                        //var respuestaCTI = string.Empty;
                                        //try
                                        //{
                                        //   var ws = new ImportarPedidosSoapClient(new BasicHttpBinding(BasicHttpSecurityMode.None), new EndpointAddress(urlCTI));
                                        //   var respuesta = ws.InsertarPedidosAsync(pedido).Result.Body.InsertarPedidosResult;
                                        //   respuestaCTI = respuesta.description;
                                        //}
                                        //catch (WebException wex)
                                        //{
                                        //   log.AgregaPcgRequest(JsonConvert.SerializeObject(pedido), wex.Message, "0", so, "Asignador Kits CTI");
                                        //   respuestaCTI = wex.Message;
                                        //}
                                        //catch (Exception ex)
                                        //{
                                        //   log.AgregaPcgRequest(JsonConvert.SerializeObject(pedido), ex.Message, "0", so, "Asignador Kits CTI");
                                        //   respuestaCTI = ex.Message;
                                        //}
                                        //if (string.Compare(respuestaCTI, "PEDIDO IMPORTADO", StringComparison.CurrentCultureIgnoreCase) == 0)
                                        //{
                                        //   log.EscribeLog("Pedido enviado correctamente");
                                        //   // descontamos inventario
                                        //   foreach (DataRow kit in items_in_kit_list.Rows)
                                        //   {
                                        //      cn.EjecutaConsulta("SP_ProductStockUpdate", new[]
                                        //      {
                                        //         new MySqlParameter("var_product_id", MySqlDbType.Int32)
                                        //         {
                                        //            Value = kit["kit_product_id"]
                                        //         },
                                        //         new MySqlParameter("var_quantity", MySqlDbType.Int32)
                                        //         {
                                        //            Value = int.Parse(order["quantity"].ToString()) * int.Parse(kit["quantity"].ToString())
                                        //         },
                                        //         new MySqlParameter("var_move_type", MySqlDbType.Int32)
                                        //         {
                                        //            Value = 3
                                        //         },
                                        //         new MySqlParameter("var_source_id", MySqlDbType.Int32)
                                        //         {
                                        //            Value = order["sale_order_id"]
                                        //         },
                                        //         new MySqlParameter("var_comments", MySqlDbType.VarChar)
                                        //         {
                                        //            Value = "Asignado por Asignador .Net"
                                        //         },
                                        //         new MySqlParameter("var_source_location_id", MySqlDbType.Int32)
                                        //         {
                                        //            Value = string.Compare(ConfigurationManager.AppSettings["WareHouse_Reference"], "Almex", StringComparison.CurrentCultureIgnoreCase) == 0
                                        //               ? 4
                                        //               : 398
                                        //         },
                                        //         new MySqlParameter("var_destination_location_id", MySqlDbType.Int32)
                                        //         {
                                        //            Value = 18
                                        //         }
                                        //      }, CommandType.StoredProcedure);
                                        //      log.EscribeLog("Stock Actualizado");
                                        //   }
                                        //}
                                        //else
                                        //{
                                        //   log.EscribeLog("Error: " + respuestaCTI);
                                        //}


                                        WebRequest Request;
                                        WebResponse Response;
                                        Stream DataStream;
                                        StreamReader Reader;
                                        byte[] SoapByte;
                                        string json_request, api_url;
                                        json_request = "";

                                        try
                                        {

                                            log.EscribeLog("Procesando envio CTI Cargo Wise");

                                            ItemsRequest[] listaItem = new ItemsRequest[items_in_kit_list.Rows.Count];

                                            int i = 0;
                                            foreach (DataRow kit in items_in_kit_list.Rows)
                                            {
   
                                                ItemsRequest Item_R;
                                                Item_R = new ItemsRequest()
                                                {
                                                    SKU = kit["kit_product_id"].ToString().ToLower(),
                                                    Cantidad = (int.Parse(order["quantity"].ToString()) * int.Parse(kit["quantity"].ToString()))
                                                };
                                                listaItem[i] = Item_R;
                                                i++;
                                            }                                          

                                            log.EscribeLog("Procesando envio CTI Cargo Wise... creamos el ITEM");
                                            ServiceReference1.OrderRequest orderRequest = new ServiceReference1.OrderRequest
                                            {
                                                cliente_id = "TIEMERMEX",
                                                sale_order_id = so,
                                                num_guia = order["tracking_number"].ToString(),
                                                carrier = carrier,
                                                items = listaItem
                                            };

                                            log.EscribeLog("Procesando envio CTI Cargo Wise... creamos la orden");

                                            var ser = new DataContractJsonSerializer(typeof(ServiceReference1.OrderRequest));

                                            log.EscribeLog("Procesando envio CTI Cargo Wise... deserializamos");

                                            MemoryStream mem = new MemoryStream();
                                            ser.WriteObject(mem, orderRequest);
                                            json_request = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
                                            api_url = "https://cargowise.ctigroup.com.mx:44443/CTIService.svc/Order";

                                            SoapByte = Encoding.UTF8.GetBytes(json_request);
                                            Request = WebRequest.Create(api_url);
                                            Request.Headers.Add("SOAPAction", "http://tempuri.org/ICTIService/Order");
                                            Request.ContentType = "application/json";
                                            Request.ContentLength = SoapByte.Length;
                                            Request.Method = "POST";
                                            DataStream = Request.GetRequestStream();

                                            log.EscribeLog("Procesando envio CTI Cargo Wise.... procesamos request");

                                            DataStream.Write(SoapByte, 0, SoapByte.Length);
                                            DataStream.Close();
                                            Response = Request.GetResponse();
                                            DataStream = Response.GetResponseStream();
                                            Reader = new StreamReader(DataStream);
                                            string SD2Request = Reader.ReadToEnd();

                                            log.EscribeLog("Procesando envio CTI Cargo Wise.... obtenemos respuesta" + SD2Request);

                                            log.AgregaPcgRequest(json_request, SD2Request, "0", so, "Asignador CTI CargoWise");

                                            DataStream.Close();
                                            Reader.Close();
                                            Response.Close();

                                            log.EscribeLog("Procesando envio CTI Cargo Wise  ....cerramos la petición");
                                            // Termina Asignacion de pruebas de CargoWise

                                            if (!SD2Request.Contains("ERROR"))
                                            {
                                                log.EscribeLog("Pedido enviado correctamente");
                                                // descontamos inventario
                                                cn.EjecutaConsulta("SP_ProductStockUpdate", new[]
                                                {
                                                    new MySqlParameter("var_product_id", MySqlDbType.Int32)
                                                    {
                                                        Value =order["product_id"]
                                                    },
                                                    new MySqlParameter("var_quantity", MySqlDbType.Int32)
                                                    {
                                                        Value = order["quantity"]
                                                    },
                                                    new MySqlParameter("var_move_type", MySqlDbType.Int32)
                                                    {
                                                        Value = 3
                                                    },
                                                    new MySqlParameter("var_source_id", MySqlDbType.Int32)
                                                    {
                                                        Value = order["sale_order_id"]
                                                    },
                                                    new MySqlParameter("var_comments", MySqlDbType.VarChar)
                                                    {
                                                        Value = "Asignado por Asignador .Net"
                                                    },
                                                    new MySqlParameter("var_source_location_id", MySqlDbType.Int32)
                                                    {
                                                        Value = string.Compare(ConfigurationManager.AppSettings["WareHouse_Reference"], "Almex",
                                                        StringComparison.CurrentCultureIgnoreCase) == 0
                                                        ? 4
                                                        : 398
                                                    },
                                                    new MySqlParameter("var_destination_location_id", MySqlDbType.Int32)
                                                    {
                                                        Value = 18
                                                    }
                                                }, CommandType.StoredProcedure);

                                                log.EscribeLog("Stock Actualizado");
                                            }
                                            else
                                            {
                                                log.EscribeLog("Error: " + SD2Request);
                                            }

                                        }
                                        catch (WebException wex)
                                        {
                                            log.AgregaPcgRequest(json_request, wex.Message, "0", so, "Asignador CTI CargoWise");
                                            log.EscribeLog("Procesando envio CTI Cargo Wise... webException : " + wex.Message);
                                        }
                                        catch (Exception ex)
                                        {
                                            log.AgregaPcgRequest(json_request, ex.Message, "0", so, "Asignador CTI CargoWise");
                                            log.EscribeLog("Procesando envio CTI Cargo Wise... Exception : " + ex.Message);
                                        }

                                    }
                                }
                        log.EscribeLog("----------------------");
                        cont++;
                        log.EscribeLog("** PEDIDOS ASIGNADOS: " + cont);
                     }
                     else
                     {
                        // no hay suficiente stock
                        log.EscribeLog("Yijaaa Vaquero!!!... no se puede asginar este pedido porque no hay stock suficiente");
                        log.EscribeLog("----------------------");
                     }
                  }
                  else
                  {
                     log.EscribeLog("No se puede asignar, el quantity es mayor al package_quantity");
                     log.EscribeLog("----------------------");
                  }
               }
               else
               {
                  log.EscribeLog("No se puede asignar, el pack_id esta en mas pedido, separar y volver a intentar");
                  log.EscribeLog("----------------------");
               }
               log.EscribeLog("----------");
            }
         }
         catch (FaultException fex)
         {
            log.EscribeLog("Error: " + fex.Message + " " + fex.Reason + " " + fex.StackTrace);
         }
         catch (WebException wex)
         {
            log.EscribeLog("Error: " + wex.Message + " " + wex.Response);
         }
         catch (Exception ex)
         {
            log.EscribeLog("Error: " + ex.Message + " " + ex.StackTrace);
         }
      }
   }
}
