using ButcherFactory.BO;
using ButcherFactory.BO.LocalBL;
using ButcherFactory.BO.Rpcs;
using ButcherFactory.BO.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ButcherFactory.Utils;
using WinFormControl;
using ButcherFactory.Dialogs;

namespace ButcherFactory.CarcassTakeOut_
{
  public partial class CarcassTakeOutForm : Form, IWithRoleForm
  {
    #region IWithRoleForm
    public List<short> RoleName
    {
      get { return new List<short> { (short)设备类别.白条领用 }; }
    }

    public Form Generate()
    {
      return this;
    }
    #endregion

    Thread syncBeforeInfo;
    Thread uploadData;
    BindingList<CarcassTakeOut> needSubmitedList;
    BindingList<CarcassTakeOut> historyList;
    BindingList<CarcassTakeOutWeightTemp> weightList;
    long? batchID;
    CarcassTakeOutFormConfig config;
    public CarcassTakeOutForm()
    {
      InitializeComponent();
      netStateWatch1.GetConnectState = () => LoginUtil.TestConnection(500);
      uScanPanel1.AfterScan += uScanPanel1_AfterScan;
      storeSelect.SelectedIndexChanged += delegate
      {
        if (storeSelect.SelectedValue == null)
          config.Store_ID = null;
        else
          config.Store_ID = (long)storeSelect.SelectedValue;
        XmlUtil.SerializerObjToFile(config);
      };
      workUnitSelect.SelectedIndexChanged += delegate
      {
        if (workUnitSelect.SelectedValue == null)
          config.WorkUnitID = null;
        else
          config.WorkUnitID = (long)workUnitSelect.SelectedValue;
        XmlUtil.SerializerObjToFile(config);
      };
      productBatchSelect.SelectedIndexChanged += delegate
      {
        if (productBatchSelect.SelectedValue == null)
          batchID = null;
        else
          batchID = (long)productBatchSelect.SelectedValue;
      };
      this.FormClosing += delegate
      {
        if (syncBeforeInfo != null && syncBeforeInfo.IsAlive)
          syncBeforeInfo.Abort();
        if (uploadData != null && uploadData.IsAlive)
          uploadData.Abort();
      };
    }

    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);
      var initTask = new Thread(LoadBind);
      initTask.Start();

      syncBeforeInfo = new Thread(GetBeforeInfo);
      syncBeforeInfo.Start();

      uploadData = new Thread(UpLoadLocalData);
      uploadData.Start();
    }

    private void LoadBind()
    {
      this.Invoke(new Action(() =>
      {
        BLUtil.DeleteLocalDb<CarcassTakeOut>();
        if (netStateWatch1.NetState)
        {
          BaseInfoSyncRpc.SyncGoodsByTag(ApplyClient.白条出入库);
          BaseInfoSyncRpc.SyncBaseInfo<WorkUnit>();
          BaseInfoSyncRpc.SyncProductBatch(0);
          BaseInfoSyncRpc.SyncBaseInfo<Store>();
        }

        productBatchSelect.EBindComboBox<ProductBatch>(x => x.Date == DateTime.Today, 6, "Date");
        config = XmlUtil.DeserializeFromFile<CarcassTakeOutFormConfig>();
        workUnitSelect.EBindComboBox<WorkUnit>(x => x.ID == config.WorkUnitID, top: 100);
        storeSelect.EBindComboBox<Store>(x => x.ID == config.Store_ID, top: 100);
        BindGoods();
        BindGrid();
      }));
    }

    List<UButton> goodsBtns = new List<UButton>();
    void BindGoods()
    {
      var goods = FormClientGoodsSetBL.GetGoodsList();
      foreach (var item in goods)
      {
        var btn = new UButton() { Width = 120, Height = 75, Text = item.Goods_Name, Tag = item.Goods_ID, Font = new Font("宋体", 15), Margin = new Padding(22, 10, 22, 30), PlaySound = true };
        btn.Click += GoodsBtnClick;
        goodsBtns.Add(btn);
        flowLayoutPanel1.Controls.Add(btn);
      }
    }

    void GoodsBtnClick(object sender, EventArgs e)
    {
      if (batchID == null)
        throw new Exception("请先选择批次");
      var c = sender as UButton;
      Insert(null, (long)c.Tag, c.Text);
    }

    void BindGrid()
    {
      weightList = CarcassTakeOutBL.GetWeightList();
      weightGrid.DataSource = weightList;
      weightGrid.Refresh();

      needSubmitedList = CarcassTakeOutBL.GetLocalDataWithState(false);
      needSubmitGrid.DataSource = needSubmitedList;
      needSubmitGrid.Refresh();

      historyList = CarcassTakeOutBL.GetLocalDataWithState(true);
      historyDataGrid.DataSource = historyList;
      historyDataGrid.Refresh();
    }

    private void GetBeforeInfo()
    {
      while (true)
      {
        if (this.IsHandleCreated)
        {
          this.Invoke(new Action(() =>
          {
            if (netStateWatch1.NetState)
            {
              bool ff = true;
              var list = needSubmitedList.Where(x => x.BeforeWeight == null && !string.IsNullOrEmpty(x.BarCode)).Take(5);
              if (!list.Any())
              {
                list = historyList.Where(x => x.BeforeWeight == null && !string.IsNullOrEmpty(x.BarCode)).Take(5);
                ff = false;
              }
              if (list.Any())
              {
                var back = CarcassTakeOutBL.GetBeforeInfo(list.Select(x => x.BarCode));
                if (back.Any())
                {
                  foreach (var item in back)
                  {
                    var f = list.First(x => x.BarCode == item.StringExt1);
                    f.BeforeWeight = item.DecimalExt1;
                    f.Goods_Name = item.StringExt2;
                  }
                  if (ff)
                    needSubmitGrid.Refresh();
                  else
                    historyDataGrid.Refresh();
                }
              }
            }
          }));
        }
        Thread.Sleep(2000);
      }
    }

    private void UpLoadLocalData()
    {
      while (true)
      {
        if (this.IsHandleCreated)
        {
          this.Invoke(new Action(() =>
          {
            if (netStateWatch1.NetState)
              CarcassTakeOutBL.UploadCarcassInfo();
          }));
        }
        Thread.Sleep(2000);
      }
    }

    void uScanPanel1_AfterScan()
    {
      if (config.Store_ID == null)
        throw new Exception("请先选择仓库");
      var barCode = uScanPanel1.TextBox.Text.Trim();
      if (string.IsNullOrEmpty(barCode))
        throw new Exception("请先扫码");
      if (barCode.StartsWith("G"))
      {
        var gId = barCode.TrimStart('G');
        var first = goodsBtns.FirstOrDefault(x => x.Tag.ToString() == gId);
        if (first == null)
          throw new Exception(string.Format("没找到ID为{0}的存货", gId));
        GoodsBtnClick(first, EventArgs.Empty);
      }
      else
      {
        if (barCode.Length != 23)
          throw new Exception("条码格式不正确");
        Insert(barCode, null, null);
      }
    }

    void Insert(string barCode, long? goodsID, string goodsName)
    {
      var entity = CarcassTakeOutBL.Insert(config.WorkUnitID, batchID, goodsID, barCode, config.Store_ID.Value);
      if (entity == null)
        return;
      if (string.IsNullOrEmpty(barCode))
        entity.Goods_Name = goodsName;
      needSubmitedList.Insert(0, entity);
      needSubmitGrid.FirstDisplayedScrollingRowIndex = 0;
      needSubmitGrid.Rows[0].Selected = true;
      needSubmitGrid.Refresh();
      uScanPanel1.TextBox.Clear();
    }

    private void closeBtn_Click(object sender, EventArgs e)
    {
      Close();
    }

    private void submitBtn_Click(object sender, EventArgs e)
    {
      if (weightList.Count == 0)
        throw new Exception("没有称重记录");
      if (needSubmitedList.Count == 0)
        throw new Exception("没有扫码记录");
      var weight = weightList.Sum(x => x.Weight);
      var arr = needSubmitedList.ToList();
      CarcassTakeOutBL.Submit(weight, arr);
      arr.Reverse();
      foreach (var item in arr)
      {
        historyList.Insert(0, item);
        if (historyList.Count > 50)
          historyList.RemoveAt(50);
        needSubmitedList.Remove(item);
      }
      weightList.Clear();
      historyDataGrid.FirstDisplayedScrollingRowIndex = 0;
      historyDataGrid.Refresh();
      needSubmitGrid.Refresh();
      weightGrid.Refresh();
    }

    private void readBtn_Click(object sender, EventArgs e)
    {
      if (uWeightControl1.Weight == 0)
        throw new Exception("重量为0，不能读入");
      var entity = CarcassTakeOutBL.InsertWeight(uWeightControl1.Weight);
      weightList.Insert(0, entity);
      weightGrid.FirstDisplayedScrollingRowIndex = 0;
      weightGrid.Refresh();
    }
  }
}
