using ButcherFactory.BO.Bill;
using ButcherFactory.BO.Utils;
using Forks.EnterpriseServices.DomainObjects2;
using Forks.EnterpriseServices.DomainObjects2.DQuery;
using Forks.EnterpriseServices.SqlDoms;
using Forks.JsonRpc.Client;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ButcherFactory.BO.LocalBL
{
  public static class WeightCountEntityBL
  {
    const string RpcPath = @"/MainSystem/B3ClientService/Rpcs/WeightCountEntityRpc/";

    public static BindingList<WeightCountEntity> GetWeightCountEntity(bool produce, bool submited)
    {
      var query = new DQueryDom(new JoinAlias(typeof(WeightCountEntity)));
      query.Columns.Add(DQSelectColumn.Field("ID"));
      query.Columns.Add(DQSelectColumn.Field("RowIndex"));
      query.Columns.Add(DQSelectColumn.Field("Goods_Name"));
      query.Columns.Add(DQSelectColumn.Field("Number"));
      query.Columns.Add(DQSelectColumn.Field("GrossWeight"));
      query.Columns.Add(DQSelectColumn.Field("Discont"));
      query.Columns.Add(DQSelectColumn.Field("Weight"));
      //query.Columns.Add(DQSelectColumn.Field("CreateTime"));
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("ID", true));
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("ProduceOut", produce), DQCondition.EQ("Submited", submited), DQCondition.EQ("Delete", false)));
      if (submited)
      {
        query.Where.Conditions.Add(DQCondition.And(DQCondition.Between("CreateTime", DateTime.Today, DateTime.Today + new TimeSpan(23, 59, 59))));
        query.Range = SelectRange.Top(20);
      }
      var list = new BindingList<WeightCountEntity>();
      using (var session = DmoSession.New())
      {
        using (var reader = session.ExecuteReader(query))
        {
          while (reader.Read())
          {
            var entity = new WeightCountEntity();
            entity.ID = (long)reader[0];
            entity.RowIndex = (int)reader[1];
            entity.Goods_Name = (string)reader[2];
            entity.Number = (int)reader[3];
            entity.GrossWeight = (decimal?)reader[4];
            entity.Discont = (decimal?)reader[5];
            entity.Weight = (decimal?)reader[6];
            //entity.CreateTime = (DateTime)reader[5];
            list.Add(entity);
          }
        }
      }
      return list;
    }

    public static void InsertEntityByWeight(WeightCountEntity entity)
    {
      using (var session = DmoSession.New())
      {
        entity.Number = 1;
        entity.UserID = BO.Utils.AppContext.Worker.ID;
        CreateBarCode(session, entity);
        session.Insert(entity);
        session.Commit();
      }
    }

    static void CreateBarCode(IDmoSession session, WeightCountEntity entity)
    {
      var query = new DQueryDom(new JoinAlias(typeof(WeightCountEntity)));
      query.Where.Conditions.Add(DQCondition.Between("CreateTime", entity.CreateTime.Date, entity.CreateTime.Date + new TimeSpan(23, 59, 59)));
      query.Columns.Add(DQSelectColumn.Count());
      entity.BarCode = string.Format("260912011{0:yyyyMMdd}{1}{2:00000}", entity.CreateTime, BO.Utils.AppContext.ConnectInfo.ClientCode, query.EExecuteScalar(session));
    }

    public static void UpdateNumber(long id, int number)
    {
      var update = new DQUpdateDom(typeof(WeightCountEntity));
      update.Where.Conditions.Add(DQCondition.EQ("ID", id));
      update.Columns.Add(new DQUpdateColumn("Number", number));
      update.EExecute();
    }

    public static void UpdateSubmit(IEnumerable<long> ids)
    {
      var update = new DQUpdateDom(typeof(WeightCountEntity));
      update.Where.Conditions.Add(DQCondition.InList(DQExpression.Field("ID"), ids.Select(x => DQExpression.Value(x)).ToArray()));
      update.Columns.Add(new DQUpdateColumn("Submited", true));
      update.EExecute();
    }

    public static void Upload()
    {
      try
      {
        using (var session = DmoSession.New())
        {
          var needUpload = GetUnSyncData(session);
          if (needUpload.Count == 0)
            return;
          var method = RpcPath + "Upload";
          var json = JsonConvert.SerializeObject(needUpload);
          RpcFacade.Call<int>(method, json);
          foreach (var item in needUpload)
            SetLocalAsSyncd(item, session);
          session.Commit();
        }
      }
      catch
      {
#if DEBUG
        throw;
#endif
      }
    }

    static List<WeightCountEntity> GetUnSyncData(IDmoSession session)
    {
      var query = new DQueryDom(new JoinAlias(typeof(WeightCountEntity)));
      query.Columns.Add(DQSelectColumn.Field("ID"));
      query.Columns.Add(DQSelectColumn.Field("RowVersion"));
      query.Columns.Add(DQSelectColumn.Field("UserID"));
      query.Columns.Add(DQSelectColumn.Field("WorkUnit_ID"));
      query.Columns.Add(DQSelectColumn.Field("ProductBatch_ID"));
      query.Columns.Add(DQSelectColumn.Field("Goods_ID"));
      query.Columns.Add(DQSelectColumn.Field("Weight"));
      query.Columns.Add(DQSelectColumn.Field("CreateTime"));
      query.Columns.Add(DQSelectColumn.Field("Number"));
      query.Columns.Add(DQSelectColumn.Field("Store_ID"));
      query.Columns.Add(DQSelectColumn.Field("ProduceOut"));
      query.Columns.Add(DQSelectColumn.Field("BarCode"));
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("Submited", true), DQCondition.EQ("Sync", false)));
      query.Range = SelectRange.Top(10);
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("ID"));

      var upload = new List<WeightCountEntity>();
      using (var reader = session.ExecuteReader(query))
      {
        while (reader.Read())
        {
          var obj = new WeightCountEntity();
          obj.ID = (long)reader[0];
          obj.RowVersion = (int)reader[1];
          obj.UserID = (long)reader[2];
          obj.WorkUnit_ID = (long?)reader[4];
          obj.ProductBatch_ID = (long?)reader[4];
          obj.Goods_ID = (long?)reader[5];
          obj.Weight = (decimal?)reader[6];
          obj.CreateTime = (DateTime)reader[7];
          obj.Number = (int)reader[8];
          obj.Store_ID = (long?)reader[9];
          obj.ProduceOut = (bool)reader[10];
          obj.BarCode = (string)reader[11];
          upload.Add(obj);
        }
      }
      return upload;
    }

    static void SetLocalAsSyncd(WeightCountEntity obj, IDmoSession session)
    {
      var update = new DQUpdateDom(typeof(WeightCountEntity));
      update.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("ID", obj.ID), DQCondition.EQ("RowVersion", obj.RowVersion)));
      update.Columns.Add(new DQUpdateColumn("Sync", true));
      session.ExecuteNonQuery(update);
    }

    public static void Delete(long id)
    {
      var update = new DQUpdateDom(typeof(WeightCountEntity));
      update.Columns.Add(new DQUpdateColumn("Delete", true));
      update.Where.Conditions.Add(DQCondition.EQ("ID", id));
      update.EExecute();
    }
  }
}
