using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Core;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using CK.SCP.Models;
using CK.SCP.Models.Enums;
using CK.SCP.Models.ScpEntity;
using CK.SCP.Models.UniApiEntity;
using CK.SCP.Utils;

namespace CK.SCP.Controller
{
    public static class UniApiController
    {
      
        public static void Get_TS_UNI_API_List(TS_UNI_API p_entity, Action<ResultObject<IQueryable<TS_UNI_API>>> p_action)
        {
            ResultObject<IQueryable<TS_UNI_API>> _ret = new ResultObject<IQueryable<TS_UNI_API>>();
            try
            {
                using (Models.ScpEntities db = EntitiesFactory.CreateScpInstance())
                {
                    IQueryable<TS_UNI_API> q = db.TS_UNI_API;

                    if (!string.IsNullOrEmpty(p_entity.PartCode))
                    {
                        q = q.Where(p => p.PartCode.Contains(p_entity.PartCode));
                    }
                    if (!string.IsNullOrEmpty(p_entity.VendId))
                    {
                        q = q.Where(p => p.VendId == p_entity.VendId);
                    }
                    if (!string.IsNullOrEmpty(p_entity.BillNum))
                    {
                        q = q.Where(p => p.BillNum == p_entity.BillNum);
                    }
                    q = q.Where(p => p.State == p_entity.State);
                    q = q.Where(p => p.InterfaceType == p_entity.InterfaceType);
                    _ret.State = ReturnStatus.Succeed;
                    _ret.Result = q;
                    p_action(_ret);
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)//捕获实体验证异常
            {
                var sb = new StringBuilder();
                foreach (var error in dbEx.EntityValidationErrors.ToList())
                {
                    error.ValidationErrors.ToList().ForEach(i =>
                    {
                        sb.AppendFormat("表:{0},字段:{1},信息:{2}\r\n", error.Entry.Entity.GetType().Name, i.PropertyName, i.ErrorMessage);
                    });
                }
                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(dbEx);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(UniApiController), "Get_TS_UNI_API_List", sb.ToString());
                throw new ScpException(ResultCode.DbEntityValidationException, sb.ToString(), "字段验证失败" + sb.ToString());
            }
            catch (OptimisticConcurrencyException ex)//并发冲突异常
            {
                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(UniApiController), "Get_TS_UNI_API_List", ex.ToString());
                throw new ScpException(ResultCode.Exception, "9999", ex.ToString());
            }
            catch (ScpException ex)
            {
                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(UniApiController), "Get_TS_UNI_API_List", ex.ToString());
                if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UpdateException))
                {
                    var inner = (UpdateException)ex.InnerException;
                    throw new ScpException(ResultCode.Exception, "0000", ex.ToString());
                }
                else
                {
                    if (ex.InnerException != null) throw ex.InnerException;
                }
            }
            catch (Exception e)
            {
                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(e);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(UniApiController), "Get_TS_UNI_API_List", e.Message);
                throw e;
            }
        }
        public static void RemoveList(ScpEntities db, List<TS_UNI_API> uniApiList)
        {
            db.TS_UNI_API.RemoveRange(uniApiList);
        }
        public static void AddHisList(ScpEntities db, List<TS_UNI_API_HIS> uniApiHisList)
        {

            db.TS_UNI_API_HIS.AddRange(uniApiHisList);
        }

        public static void AddApiData(ScpEntities wdb, TS_UNI_API apiData)
        {
            wdb.TS_UNI_API.Add(apiData);
        }


        public static void AddApiDataList(ScpEntities wdb, List<TS_UNI_API> apiDataList)
        {
            wdb.TS_UNI_API.AddRange(apiDataList);
        }


        public static WmsTableName GetTableName(UniApiType uniApiType)
        {
            WmsTableName tableName;
            switch (uniApiType)
            {
                case UniApiType.Pobillnum:
                    tableName = WmsTableName.TS_UNI_API;//中间表的名字
                    break;
                case UniApiType.Receive:
                    tableName = WmsTableName.TS_UNI_API;
                    break;
                case UniApiType.BarCode:
                    tableName = WmsTableName.TS_UNI_API;
                    break;
                case UniApiType.Invoice:
                    tableName = WmsTableName.TS_UNI_API;
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(uniApiType), uniApiType, null);
            }
            return tableName;
        }

        //创建采购订单
        public static TS_UNI_API CreateBy(TB_PO bill, TB_PO_DETAIL detail, UniApiType uniApiType)
        {
            var tableName = GetTableName(uniApiType);
            var apiData = new TS_UNI_API
            {
                InterfaceType = uniApiType.ToString(),
                TableName = tableName.ToString(),
                BillNum = bill.PoBillNum,
                PartCode = detail.PartCode,
                Batch = "",
                Qty = detail.PlanQty,
                PoUnit = detail.PoUnit,
                LocUnit = detail.LocUnit,
                State = detail.State,
                CreateOper = bill.CreateUser,
                CreateTime = bill.CreateTime,
                PutTime = ScpCache.GetServerTime(),
                VendId = bill.VendId,
                BillType = (int)BillType.PuchaseOrder,
                SubBillType = 0,
                ValidDate = (DateTime)detail.EndTime,
                ErpBillNum = bill.ErpBillNum,
                ErpLineNum = int.Parse(detail.PoBillNum),
                VendBatch = "",
                SourceBillNum = "",
                Price = detail.Price,
                PackQty = detail.PackQty,
                Currency = detail.Currency,
                Attn = "",//TODO
                Buyer = bill.Buyer,
                BuyerPhone = bill.BuyerPhone,
                ModType = bill.ModType.ToString(),
                Receiver = "",//TODO
                UmConv = (decimal)detail.UnConv,
            };
            return apiData;
        }

        private static ScpEntities db = EntitiesFactory.CreateScpInstance();
        public static TS_UNI_API CreateBy(TB_PO bill, List<TB_PO_DETAIL> detail, UniApiType uniApiType)
        {
            var tableName = GetTableName(uniApiType);
            TS_UNI_API asp = new TS_UNI_API();
            foreach (var item in detail)
            {
                asp.InterfaceType = uniApiType.ToString();
                asp.TableName = tableName.ToString();

                asp.BillNum = bill.PoBillNum;
                asp.Batch = string.Empty;
                asp.CreateOper = bill.CreateUser;
                asp.CreateTime = bill.CreateTime;
                asp.PutTime = ScpCache.GetServerTime();
                asp.VendId = bill.VendId;
                asp.BillType = (int)BillType.PO;
                asp.SubBillType = 0;
                asp.VendBatch = string.Empty;
                asp.SourceBillNum = string.Empty;
                asp.Attn = "";//TODO
                asp.Buyer = bill.Buyer;
                asp.BuyerPhone = bill.BuyerPhone;
                asp.ModType = bill.ModType.ToString();
                asp.Receiver = "";//TODO
                asp.PartCode = item.PartCode;

                asp.Qty = item.PlanQty;
                asp.PoUnit = item.PoUnit;
                asp.LocUnit = item.LocUnit;
                asp.State = item.State;

                asp.ValidDate = (DateTime)item.EndTime;
                asp.ErpBillNum = bill.ErpBillNum;//暂时跟billnum 一样  后期可能会改  预留
                asp.ErpLineNum = item.PoLine;   

                asp.Price = item.Price;
                asp.PackQty = item.PackQty;
                asp.Currency = item.Currency;

                asp.UmConv = (decimal)item.UnConv;

                db.TS_UNI_API.Add(asp);
                db.SaveChanges();
            }

            return asp;
        }
        public static DataTable FindUniapi(string p_type, string p_billNum, string p_domain)
        {
            string sql = string.Empty;
            switch (p_type)
            {
                case "xxqad_pod_det":
                    sql ="SELECT * FROM[xxqad_pod_det] a inner join xxqad_ctrl b on a.xxqad_pod_seq = b.xxqad_seq where xxqad_domain = '{1}' and xxqad_pod_nbr in ({0}) order by xxqad_pod_nbr, b.xxqad_seq ";
                    break;
                case "xxqad_prh_det":
                    sql = "SELECT *  FROM[xxqad_prh_det] a inner join xxqad_ctrl b on a.xxqad_prh_seq = b.xxqad_seq where xxqad_domain = '{1}' and (xxqad_prh_psnbr in ({0})  or xxqad_prh_receiver in ({0}))  order by xxqad_prh_psnbr, b.xxqad_seq ";
                    break;
                case "xxwms_rc_det":
                    sql = "select * from xxwms_rc_det a inner join xxwms_ctrl b on a.xxwms_rc_seq = b.xxwms_seq where xxwms_domain = '{1}' and (xxwms_rc_nbr  in ({0})   order by xxwms_rc_nbr, b.xxwms_seq";
                    break;
                //case "xxscm_tx_mstr":
                //    sql = "select * from xxscm_tx_mstr a inner join xxscm_ctrl b on a.xxscm_tx_seq = b.xxscm_seq where xxscm_domain = '{1}' and xxscm_tx_nbr in ({0}) order by xxscm_tx_nbr, b.xxscm_seq";
                //    break;
                case "xxscm_inv_det":
                    sql = "select * from xxscm_inv_det a inner join xxscm_ctrl b on a.xxscm_inv_seq = b.xxscm_seq where xxscm_domain = '{1}' and xxscm_inv_nbr IN({0}) order by xxscm_inv_nbr,b.xxscm_seq";
                    break;
            }
            DataTable _dt = new DataTable();
            var dbSetting = GlobalConfig.UniApiDatabase;
            var strConn = EntitiesFactory.GetEfConnectionString(dbSetting);
            SqlConnection conn = new System.Data.SqlClient.SqlConnection();
            try
            {

                conn.ConnectionString = strConn;
                if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                cmd.CommandText = string.Format(sql, p_billNum, p_domain);
                SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                adapter.Fill(_dt);
                conn.Close();

            }
            catch (Exception e)
            {
                conn.Close();
            }
            return _dt;
        }

        //创建发货单
        public static TS_UNI_API CreateBy(V_TB_ASN bill, V_TB_ASN_DETAIL detail, UniApiType uniApiType)
        {
            var tableName = GetTableName(uniApiType);
            var apiData = new TS_UNI_API();
                apiData.InterfaceType = uniApiType.ToString();
                apiData.TableName = tableName.ToString();
                apiData.BillNum = bill.AsnBillNum;
                apiData.PartCode = detail.PartCode;
                apiData.Batch = detail.Batch;
                apiData.Qty = detail.Qty;
                apiData.PoUnit = detail.PoUnit;
                apiData.LocUnit = detail.LocUnit;
                apiData.State = (int)detail.State;
                apiData.CreateOper = bill.CreateUser;
                apiData.CreateTime = bill.CreateTime;
                apiData.PutTime = ScpCache.GetServerTime();
                apiData.VendId = bill.VendId;
                apiData.BillType = (int)BillType.PuchaseOrder;
                apiData.SubBillType = 0;
                apiData.ValidDate = bill.EndTime;
                apiData.ErpBillNum = bill.PoBillNum;
                apiData.ErpLineNum = detail.PoLine;
                 apiData.ModType= detail.UpdateInfo;
                 apiData.Barcode = "";
            var ts = db.TS_UNI_API.Count(p => p.ErpLineNum == detail.PoLine && p.ErpBillNum == bill.PoBillNum);
            string str = "000";
            string st = bill.PoBillNum.Substring(0,4);
            //if (ts == 0)
            //{
                string str1= detail.PoLine.ToString();
              
                    apiData.Extend3 =  str1;
            //}
           //else
           // {
           //     if (ts == 1)
           //     {
           //     var ts1 = db.TB_PO_DETAIL.Where(p => p.PoLine == detail.PoLine && p.PoBillNum == bill.PoBillNum).Select(r => r.PoLine).Max(); 
           //     int ts2 = ts1 + 50;
           //     string str2 = ts2.ToString();
                 
           //             apiData.Extend3 = str2;
           //     }
           //    else if (ts == 2)
           //     {
           //         var ts1 = db.TB_PO_DETAIL.Where(p => p.PoLine == detail.PoLine && p.PoBillNum == bill.PoBillNum).Select(r => r.PoLine).Max();
           //         int ts2 = ts1 + 60;
           //         string str3 = ts2.ToString();
                 
           //             apiData.Extend3 = str3;
           //     }
           //    else if (ts == 3)
           //     {
           //         var ts1 = db.TB_PO_DETAIL.Where(p => p.PoLine == detail.PoLine && p.PoBillNum == bill.PoBillNum).Select(r => r.PoLine).Max();
           //         int ts2 = ts1 + 70;
           //         string str4 = ts2.ToString();
                 
           //             apiData.Extend3 = str4;                   
           //     }
           //     else
           //     {
           //         var ts3 = db.TS_UNI_API.Where(p => p.ErpLineNum == detail.PoLine && p.ErpBillNum == bill.PoBillNum).Select(r => r.Extend3).Max();
           //         int ts4 = int.Parse(ts3) + 10;
           //         string str5 = ts4.ToString();
                
           //             apiData.Extend3 = str5;                    
           //     }
           // }
            if (bill.SubSite == "W21")
            {
                apiData.VendBatch = detail.UpdateUser;
            }
            else
            {
                apiData.VendBatch = detail.VendBatch;
            }

              
                apiData.Price = detail.Price;
                apiData.PackQty = detail.PackQty;
                apiData.Currency = detail.Currency;
                apiData.UmConv = (decimal) detail.UnConv;
                apiData.Buyer = bill.Buyer;
                apiData.BuyerPhone = bill.BuyerPhone;
                apiData.Domain = bill.Site;
                apiData.Site = bill.SubSite ==null ? bill.Site : bill.SubSite;

            apiData.Extend1 = Utils.JsonHelper.GetJson(bill);
            apiData.Extend2 = Utils.JsonHelper.GetJson(detail);


            return apiData;
        }



       

        //创建条码
        public static TS_UNI_API CreateBy(TB_ASN bill, TS_BARCODE detail, UniApiType uniApiType)
        {
            var tableName = GetTableName(uniApiType);
            var apiData = new TS_UNI_API();

            apiData.Barcode = detail.BarCode;
            apiData.InterfaceType = uniApiType.ToString();
            apiData.TableName = tableName.ToString();
            apiData.BillNum = bill.AsnBillNum;
            apiData.PartCode = detail.PartCode;
            apiData.Batch = detail.Batch;
            apiData.Qty = detail.Qty;
            apiData.PoUnit = detail.PoUnit;
            apiData.LocUnit = detail.LocUnit;
            apiData.State = detail.State;
            apiData.CreateOper = bill.CreateUser;
            apiData.CreateTime = bill.CreateTime;
            apiData.PutTime = ScpCache.GetServerTime();
            apiData.VendId = bill.VendId;
            apiData.BillType = (int)BillType.PuchaseOrder;
            apiData.SubBillType = 0;
            apiData.ValidDate = detail.ProduceDate;
            apiData.ErpBillNum = bill.PoBillNum;
            apiData.ErpLineNum = detail.PoBillLine;
            apiData.VendBatch = detail.VendBatch;
            apiData.SourceBillNum = bill.AsnBillNum;
            apiData.Domain = bill.Site;
            if(bill.Site=="")

            apiData.Site = bill.Remark;
            //detail.FullBarCode;
            apiData.PackQty = detail.PackQty;
            
            return apiData;
        }

        //创建发票
        public static TS_UNI_API CreateBy(V_TB_INVOICE bill, V_TB_INVOICE_DETAIL detail, UniApiType uniApiType)
        {
            var tableName = GetTableName(uniApiType);
            var apiData = new TS_UNI_API
            {
                InterfaceType = uniApiType.ToString(),
                TableName = tableName.ToString(),
                BillNum = bill.InvcBillNum,
                PartCode = detail.PartCode,
                Batch = "",
                Qty = detail.Qty,
                PoUnit = detail.PoUnit,
                LocUnit = detail.PoUnit,
                State = (int)detail.State,
                CreateOper = bill.CreateUser,
                CreateTime = (DateTime)bill.CreateTime,
                PutTime = ScpCache.GetServerTime(),
                VendId = bill.VendId,
                BillType = (int)BillType.PuchaseOrder,
                SubBillType = 0,
                ValidDate = DateTime.Now,//暂时添上
                ErpBillNum = detail.PoBillNum,
                ErpLineNum = detail.PoLineNum,
                VendBatch = detail.ProjectId,
                SourceBillNum = detail.AsnBillNum,
                Price = detail.Price,
                PackQty = (decimal)detail.PackQty,
                Currency = detail.Currency,
                Invoice = bill.InvoiceNum,
                Receiver = detail.ErpRecvBillNum,
                Tax = (decimal)bill.Tax,
                TaxAmt = (decimal)(detail.Price * bill.Tax),
                Domain = bill.Site,
                Site = bill.Site,
                Attn = Utils.JsonHelper.GetJson(bill),
                Extend1 = Utils.JsonHelper.GetJson(bill),
                Extend2 = Utils.JsonHelper.GetJson(detail)
            };
            return apiData;
        }

        public static List<TS_UNI_API> GetNewInterfaceList(ScpEntities wdb)
        {
            return wdb.TS_UNI_API.Where(p => p.State == (int)BillState.New).OrderBy(p => p.UID).ToList();
        }
    }
}