using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Net;
using System.ServiceModel;
using MySqlConnector;

namespace ActualizarEstatusPaqueteriaTodos
{
   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.TraeDataSet(query, new MySqlParameter[] { }, CommandType.StoredProcedure).Tables[0];
            log.EscribeLog(data.Rows.Count + " pedidos.");
            string[] estatuscompletado;
            foreach (DataRow order in data.Rows)
            {
               log.EscribeLog("----------");
               if (string.Compare(order["carrier_name"].ToString(), "CUSTOM",
                  StringComparison.CurrentCultureIgnoreCase) == 0)
               {
                  order["carrier_name"] = cn.TraeDataTable("SELECT carrier_name FROM carrier WHERE carrier_id=" + order["carrier_id"],
                     new MySqlParameter[] { }, CommandType.Text).Rows[0][0];
               }
               log.EscribeLog("Consulta estatus "+ order["carrier_name"].ToString().ToUpper() + ".");
               log.EscribeLog("Pedido: " + order["reference_order_number"]);
               log.EscribeLog("Estatus anterior: " + order["shipping_status"]);
               // validamos por paqueteria
               try
               {
                  switch (order["carrier_name"].ToString().ToUpper())
                  {
                     case "FEDEX EXPRESS SAVER":
                     case "FEDEX":
                        #region Fedex
                        if (!order["tracking_number"].ToString().StartsWith("MEL", StringComparison.CurrentCultureIgnoreCase))
                        {
                           var shipping_status = cotizaciones.Fedex_Tracking(order["tracking_number"].ToString(), order["sale_order_id"].ToString(), order["reference_order_number"].ToString());
                           if (shipping_status.HighestSeverity == CreateLabel_ML.wsFedexTrack.NotificationSeverityType.SUCCESS)
                           {
                              if (shipping_status.CompletedTrackDetails[0].HighestSeverity == CreateLabel_ML.wsFedexTrack.NotificationSeverityType.SUCCESS)
                              {
                                 if (shipping_status.CompletedTrackDetails[0].TrackDetails[0].StatusDetail != null)
                                 {
                                    // se cambia estatus en merch
                                    ValidaEntregado(new[]
                                       {
                                          "DL",
                                          "IT",
                                          "AR",
                                          "SE",
                                          "DP"
                                       }, shipping_status.CompletedTrackDetails[0].TrackDetails[0].StatusDetail.Code, order["reference_order_number"].ToString());
                                    if (shipping_status.CompletedTrackDetails[0].TrackDetails[0].StatusDetail.Code != null)
                                       ActualizaEstatus(log, cotizaciones, shipping_status.CompletedTrackDetails[0].TrackDetails[0].StatusDetail.Description, order["reference_order_number"].ToString(), order["sale_order_id"].ToString(), order["carrier_name"].ToString(), order["tracking_number"].ToString(), shipping_status.CompletedTrackDetails[0].TrackDetails[0].StatusDetail.CreationTime);
                                 }
                                 else
                                    log.EscribeLog("Error al consultar estatus Fedex.");
                              }
                              else
                                 log.EscribeLog("Error al consultar estatus Fedex.");
                           }
                           else
                              log.EscribeLog("Error al consultar estatus Fedex.");
                        }
                        else
                           ActualizaMercadoLibre(log, cotizaciones, order["reference_order_number"].ToString(), order["sale_order_id"].ToString(), order["carrier_name"].ToString(), order["tracking_number"].ToString());
                        #endregion
                        break;
                     case "ESTAFETA":
                        #region Estafeta
                        var xml_response = cotizaciones.GetEstafetaShippingStatus(order["tracking_number"].ToString(), order["sale_order_id"].ToString(), order["reference_order_number"].ToString());
                        var errorCode = xml_response.errorCode;
                        if (string.Compare(errorCode, "0", StringComparison.CurrentCultureIgnoreCase) != 0)
                           log.EscribeLog("Error al consultar estatus Estafeta.");
                        else
                        {
                           if (xml_response.trackingData.Length > 0)
                           {
                              var status_code = xml_response.trackingData[0].statusSPA;
                              ValidaEntregado(new[] { "CONFIRMADO" }, status_code, order["reference_order_number"].ToString());
                              var date_delivery = xml_response.trackingData[0].deliveryData.deliveryDateTime;
                              var newformat = string.Empty;
                              if (date_delivery.Trim().Length > 0)
                              {
                                 date_delivery = date_delivery.Substring(0, 10);
                                 newformat = "'" + date_delivery.Substring(6, 4) + "-" + date_delivery.Substring(3, 2) + "-" + date_delivery.Substring(0, 2) + "'";
                              }
                              else
                                 newformat = "NULL";
                              ActualizaEstatus(log,cotizaciones,status_code, order["reference_order_number"].ToString(), order["sale_order_id"].ToString(), order["carrier_name"].ToString(), order["tracking_number"].ToString(), date_delivery.Trim().Length > 0 ? DateTime.Parse(newformat) : DateTime.Now);
                           }
                           else
                              log.EscribeLog("Error al consultar estatus Estafeta.");
                        }
                        #endregion
                        break;
                     case "PAQUETEXPRESS":
                        #region PaquetExpress
                        var respuestaSrEnvios = cotizaciones.GetSkydropxShipingStatus(order["tracking_number"].ToString(), order["sale_order_id"].ToString(), order["reference_order_number"].ToString(), order["carrier_name"].ToString());
                        if (respuestaSrEnvios == null || respuestaSrEnvios.data.Count == 0)
                           log.EscribeLog("Error al consultar estatus Sr. Envios.");
                        else
                        {
                           ValidaEntregado(new[]
                           {
                           "DELIVERED",
                           "IN_TRANSIT",
                           "LAST_MILE",
                           "DELIVERY_ATTEMPT"
                        }, respuestaSrEnvios.data[0].status, order["reference_order_number"].ToString());
                           ActualizaEstatus(log,cotizaciones, respuestaSrEnvios.data[0].status, order["reference_order_number"].ToString(), order["sale_order_id"].ToString(), order["carrier_name"].ToString(), order["tracking_number"].ToString(),DateTime.Now);
                        }
                        #endregion
                        break;
                     case "REDPACK":
                        #region RedPack
                        var respuestaRedPack = cotizaciones.RedPackStatus(order["tracking_number"].ToString(), order["sale_order_id"].ToString(), order["reference_order_number"].ToString());
                        if (respuestaRedPack == null)
                           log.EscribeLog("Error al consultar estatus RedPack.");
                        else
                        {
                           if (respuestaRedPack.paquetes[0] != null)
                           {
                              ValidaEntregado(new[] { "ENTREGADO" }, respuestaRedPack.paquetes[0].detallesRastreo[0].evento, order["reference_order_number"].ToString());
                              ActualizaEstatus(log, cotizaciones, respuestaRedPack.paquetes[0].detallesRastreo[0].evento, order["reference_order_number"].ToString(), order["sale_order_id"].ToString(), order["carrier_name"].ToString(), order["tracking_number"].ToString(), respuestaRedPack.paquetes[0].detallesRastreo[0].fechaEvento.Value == null ? DateTime.Now : respuestaRedPack.paquetes[0].detallesRastreo[0].fechaEvento.Value);
                           }
                           else
                              log.EscribeLog("Error al consultar estatus RedPack.");
                        }
                        #endregion
                        break;
                     case "IENVIOS":
                        #region iEnvios
                        var respuestaiEnvios = cotizaciones.IEnviosStatus(order["tracking_number"].ToString(), order["sale_order_id"].ToString(), order["reference_order_number"].ToString());
                        if (respuestaiEnvios == null)
                           log.EscribeLog("Error al consultar estatus iEnvios.");
                        else
                        {
                           if (respuestaiEnvios.error == false)
                           {
                              ValidaEntregado(new[] { "Entregada" }, respuestaiEnvios.data.estatus, order["reference_order_number"].ToString());
                              ActualizaEstatus(log,cotizaciones, respuestaiEnvios.data.estatus, order["reference_order_number"].ToString(), order["sale_order_id"].ToString(), order["carrier_name"].ToString(), order["tracking_number"].ToString(),DateTime.Now);
                           }
                           else
                              log.EscribeLog("Error al consultar estatus iEnvios.");
                        }
                        #endregion
                        break;
                     case "EXPRESS":
                     case "FEDEX A SUCURSAL":
                     case "AGENCIAS MERCADO LIBRE":
                     case "PAQUETEXPRESS NORMAL A DOMICILIO":
                     case "MEL DISTRIBUTION":
                     case "DHL  A SUCURSAL":
                        ActualizaMercadoLibre(log, cotizaciones, order["reference_order_number"].ToString(), order["sale_order_id"].ToString(), order["carrier_name"].ToString(), order["tracking_number"].ToString());
                        break;
                  }
               }
               catch (Exception ex)
               {
                  log.EscribeLog("Error: " + ex.Message + " " + ex.StackTrace);
               }
               log.EscribeLog("Guia: " + order["tracking_number"]);
            }
         }
         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);
         }
      }

      private static void ValidaEntregado(string[] estatuscompletados, string estatus, string pedido)
      {
         if (estatuscompletados.Any(e => e == estatus))
         {
            if (string.Compare(ConfigurationManager.AppSettings["Plataforma"], "EK", StringComparison.CurrentCultureIgnoreCase) == 0)
            {
               var modeloelektra = new mdlElektra();
               modeloelektra.Login();
               modeloelektra.ConfirmDelivered(pedido);
            }
            var cotizaciones = new Cotizaciones();
            cotizaciones.UpdMerchantOrderHeader("shipping_status='delivered'", "reference_order_number='" + pedido + "'");
         }
      }

      private static void ActualizaEstatus(clsLog log, Cotizaciones cotizaciones, string estatus, string reference_order_number, string sale_order_id, string carrier_name, string tracking_number, DateTime fecha)
      {
         log.EscribeLog("Estatus nuevo: " + estatus);
         cotizaciones.UpdMerchantOrderHeader("carrier_shipping_status='" + estatus + "', carrier_date_tracking='" + fecha.ToString("yyyy-MM-dd HH:mm:ss") + "'", "reference_order_number='" + reference_order_number + "'");
         cotizaciones.AddSaleOrderTrackingHistory(sale_order_id, carrier_name, tracking_number, estatus, fecha);
      }

      private static void ActualizaMercadoLibre(clsLog log, Cotizaciones cotizaciones, string reference_order_number, string sale_order_id, string carrier_name, string tracking_number)
      {
         var modelomercadolibre = new mdlMercadoLibre();
         modelomercadolibre.Login();
         var pedido = modelomercadolibre.GetOrder(reference_order_number);
         var guia = modelomercadolibre.GetShipmentInfo(pedido.shipping.id.ToString());
         if (!string.IsNullOrEmpty(guia.substatus))
            ActualizaEstatus(log, cotizaciones, guia.substatus, reference_order_number, sale_order_id, carrier_name, tracking_number, DateTime.Now);
         else
         {
            if (!string.IsNullOrEmpty(guia.status))
               ActualizaEstatus(log, cotizaciones, guia.status, reference_order_number, sale_order_id, carrier_name, tracking_number, DateTime.Now);
         }
      }
   }
}
