using ButcherFactory.BO;
using ButcherFactory.BO.LocalBL;
using ButcherFactory.BO.Rpcs;
using ButcherFactory.BO.Utils;
using ButcherFactory.Dialogs;
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 WinFormControl;
using ButcherFactory.Utils;
using NotAuto = ButcherFactory.SegmentProduction_;
using ButcherFactory.Controls;

namespace ButcherFactory.SegmentProductionAuto_
{
  public partial class SegmentProductionAutoForm : Form, IWithRoleForm
  {
    public List<short> RoleName
    {
      //get { return new List<short> { (short)设备类别.分割生产自动化 }; }
      get { return new List<short> { (short)设备类别.分割生产 }; }
    }

    public Form Generate()
    {
      return this;
    }

    Thread uploadData;
    Thread checkInStoreState;
    Thread initTask;
    BindingList<SegmentProduction> historyList;
    Dictionary<string, List<ClientGoodsSet_Detail>> goodsSetDic;
    long? batchID;
    DateTime? batchDate;
    NotAuto.SegmentProductionFormConfig config;
    public SegmentProductionAutoForm()
    {
      InitializeComponent();
      netStateWatch1.GetConnectState = () => LoginUtil.TestConnection(500);
      this.FormClosing += SegmentProductionAutoForm_FormClosing;
      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;
          batchDate = null;
        }
        else
        {
          var entity = productBatchSelect.SelectedItem as ProductBatch;
          batchID = entity.ID;
          batchDate = entity.Date;
        }
      };
    }

    void SegmentProductionAutoForm_FormClosing(object sender, FormClosingEventArgs e)
    {
      var unSyncCount = SegmentProductionBL.GetUnSyncCount();
      if (unSyncCount > 0)
      {
        if (MessageBox.Show(string.Format("{0}条数据等待上传，确认关闭？", unSyncCount), "关闭确认", MessageBoxButtons.OKCancel) != DialogResult.OK)
        {
          e.Cancel = true;
        }
      }

      if (initTask != null && initTask.IsAlive)
        initTask.Abort();
      if (uploadData != null && uploadData.IsAlive)
        uploadData.Abort();
      if (checkInStoreState != null && checkInStoreState.IsAlive)
        checkInStoreState.Abort();
    }

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

      checkInStoreState = new Thread(CheckInStored);
      checkInStoreState.Start();

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

    void LoadBind()
    {
      BLUtil.DeleteLocalDb<SegmentProduction>();
      SegmentProductionBL.DeleteBefore();
      GetBasicInfo();
    }

    bool ok = false;
    bool bind = false;
    void GetBasicInfo()
    {
      while (!ok)
      {
        try
        {
          var changed = BaseInfoSyncRpc.SyncGoodsByTag(ApplyClient.分割品);
          changed = BaseInfoSyncRpc.SyncBaseInfo<WorkUnit>() || changed;
          changed = BaseInfoSyncRpc.SyncProductBatch(1) || changed;
          ok = true;
          if (changed || !bind)
            BindBasicInfo();
          this.Invoke(new Action(() =>
          {
            msglbl.Text = string.Empty;
          }));
        }
        catch
        {
          if (!bind)
          {
            BindBasicInfo();
            bind = true;
          }
        }
        Thread.Sleep(500);
      }
    }

    void BindBasicInfo()
    {
      this.Invoke(new Action(() =>
      {
        productBatchSelect.EBindComboBox<ProductBatch>(null, 6, "Date");
        config = XmlUtil.DeserializeFromFile<NotAuto.SegmentProductionFormConfig>();
        var m = config.WorkUnitID;
        workUnitSelect.EBindComboBox<WorkUnit>(x => x.ID == m, top: 100);

        BindGoods();
        BindGrid();
      }));
    }

    void BindGoods()
    {
      goodsSetDic = FormClientGoodsSetBL.GetSelectedDetail();
      flowLayoutPanel1.Controls.Clear();
      flowLayoutPanel2.Controls.Clear();
      foreach (var item in goodsSetDic)
      {
        var btn = new ColorButton() { Width = 100, Height = 62, Text = item.Key, Font = new Font("宋体", 15), Margin = new Padding(15, 3, 15, 0), EnableGroup = true };
        btn.Click += GroupGoodsSetClick;
        flowLayoutPanel1.Controls.Add(btn);
      }
    }

    Color goodsColor = Color.FromArgb(250, 120, 24);
    string groupKey = string.Empty;
    void GroupGoodsSetClick(object sender, EventArgs e)
    {
      flowLayoutPanel2.Controls.Clear();
      var groupBtn = sender as ColorButton;
      groupKey = groupBtn.Text;
      var arr = goodsSetDic[groupKey];
      foreach (var item in arr)
      {
        var btn = new ColorButton() { Width = 140, Height = 90, Text = item.Goods_Name, Tag = item, Font = new Font("黑体", 15, FontStyle.Bold), BackColor = Color.Black, Margin = new Padding(20, 10, 20, 35), PlaySound = true, ForeColor = Color.White };
        btn.Click += GoodsBtnClick;
        flowLayoutPanel2.Controls.Add(btn);
      }
    }

    void GoodsBtnClick(object sender, EventArgs e)
    {
      if (batchID == null)
        throw new Exception("请先选择批次");
      var btn = sender as ColorButton;
      var detail = btn.Tag as ClientGoodsSet_Detail;
      var weight = uWeightControl1.Weight;
      if (weight == 0)
        throw new Exception("重量不能为0");
      if (detail.StandardWeight.HasValue)
      {
        if (weight < (detail.StandardWeightLow ?? 0) || weight > (detail.StandardWeightUp ?? 0))
          throw new Exception(string.Format("重量必须在{0:#0.######}-{1:#0.######}之间", detail.StandardWeightLow, detail.StandardWeightUp));
        weight = detail.StandardWeight.Value;
      }
      var entity = new SegmentProduction();
      entity.Goods_ID = detail.Goods_ID;
      entity.Weight = weight;
      entity.WorkUnit_ID = config.WorkUnitID;
      entity.ProductBatch_ID = batchID.Value;
      entity.StandardPic = detail.StandardPic;
      if (!string.IsNullOrEmpty(statisticNumberBox.Text))
        entity.StatisticNumber = decimal.Parse(statisticNumberBox.Text);
      SegmentProductionBL.InsertAndSetGroupID(entity, batchDate.Value);
      entity.Goods_Code = detail.Goods_Code;
      entity.Goods_Name = detail.Goods_Name;
      entity.Goods_Spec = detail.Goods_Spec;
      entity.MainUnit = detail.MainUnit;
      entity.ShotPrintName = detail.ShotPrintName;
      GoodsLabel.Text = entity.Goods_Name;

      historyList.Insert(0, entity);
      if (historyList.Count > 30)
        historyList.RemoveAt(30);
      historyDataGrid.FirstDisplayedScrollingRowIndex = 0;
      historyDataGrid.ClearSelection();
      historyDataGrid.Refresh();
      if (barPrintCheck.Checked)
      {
        var template = config.Template;
        if (detail.GoodsType.HasValue)
          template = detail.GoodsType == 0 ? "SegmentProductionPrint.html" : "SegmentProductionPrint1.html";
        NotAuto.SegmentProductionPrint.Print(entity, batchDate, template);
        var log = new SegmentLog(entity.BarCode, "打印");
        log.Message = string.Format("存货名称：{0} 重量：{1:#0.###}", entity.Goods_Name, entity.Weight);
        SegmentProductionBL.InsertLog(log);
      }
      var thd = new Thread(new ParameterizedThreadStart(RefreshTask));
      thd.Start(entity);
    }

    void RefreshTask(object obj)
    {
      var entity = obj as SegmentProduction;
      var list = SegmentProductionBL.GetProductTask(batchDate ?? DateTime.Today, entity);
      this.Invoke(new Action(() =>
      {
        taskDataGrid.DataSource = list;
        taskDataGrid.Refresh();
      }));
    }

    void BindGrid()
    {
      historyList = SegmentProductionBL.GetListByState(true);
      historyDataGrid.DataSource = historyList;
      historyDataGrid.Refresh();

      var first = historyList.FirstOrDefault();
      if (first != null)
        GoodsLabel.Text = first.Goods_Name;
    }

    void UpLoadLocalData()
    {
      while (true)
      {
        try
        {
          //this.Invoke(new Action(() =>
          //{
          if (netStateWatch1.NetState)
            SegmentProductionBL.UploadSegmentInfo();
          //}));
        }
        catch { }
        Thread.Sleep(2000);
      }
    }

    private void CheckInStored()
    {
      while (true)
      {
        try
        {
          if (netStateWatch1.NetState)
          {
            if (historyList.Any())
            {
              var arr = historyList.Reverse().Take(20);
              var inStored = SegmentProductionBL.GetInStoreState(arr.Select(x => x.BarCode).ToList());
              var tag = arr.Where(x => inStored.Contains(x.BarCode));
              if (tag.Any())
              {
                SegmentProductionBL.SetInStored(tag.Select(x => x.ID).ToList());
                this.Invoke(new Action(() =>
                {
                  foreach (var item in tag)
                    historyList.Remove(item);
                  historyDataGrid.ClearSelection();
                  historyDataGrid.Refresh();
                }));
              }
            }
          }
        }
        catch { }
        Thread.Sleep(5000);
      }
    }

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

    private void goodsSetBtn_Click(object sender, EventArgs e)
    {
      new ClientGoodsSetDialog().ShowDialog();
      BindGoods();
    }

    private void rePrintBtn_Click(object sender, EventArgs e)
    {
      if (barPrintCheck.Checked)
      {
        if (historyList.Count == 0)
          throw new Exception("请先选择要补打的记录");
        SegmentProduction item;
        var row = historyDataGrid.SelectedRows;
        if (row.Count > 0)
          item = row[0].DataBoundItem as SegmentProduction;
        else
          item = historyList.First();
        var template = config.Template;
        var goodsType = SegmentProductionBL.GetGoodsType(item.Goods_ID);
        if (goodsType.HasValue)
          template = goodsType == 0 ? "SegmentProductionPrint.html" : "SegmentProductionPrint1.html";
        NotAuto.SegmentProductionPrint.Print(item, batchDate, template);
        var log = new SegmentLog(item.BarCode, "补打");
        log.Message = string.Format("存货名称：{0} 重量：{1:#0.###}", item.Goods_Name, item.Weight);
        SegmentProductionBL.InsertLog(log);
      }
    }

    private void templateBtn_Click(object sender, EventArgs e)
    {
      new TemplateSelector(config).ShowDialog();
    }

    private void deleteBtn_Click(object sender, EventArgs e)
    {
      var row = historyDataGrid.SelectedRows;
      if (row.Count == 0)
        return;
      if (MessageBox.Show("确定删除选中记录？", "删除确认", MessageBoxButtons.OKCancel) != DialogResult.OK)
        return;
      var tag = historyDataGrid.SelectedRows[0].DataBoundItem as SegmentProduction;
      if (tag.CreateTime.AddMinutes(1) < DateTime.Now)
      {
        MessageBox.Show("已超出可删除时间范围");
        return;
      }
      SegmentProductionBL.Delete(tag);
      //SegmentProductionBL.SetAsDelete(tag.ID, tag.BarCode);
      historyList.Remove(tag);
      historyDataGrid.DataSource = historyList;
      historyDataGrid.ClearSelection();
      historyDataGrid.Refresh();

      var thd = new Thread(new ParameterizedThreadStart(RefreshTask));
      thd.Start(tag);
    }

    private void logBtn_Click(object sender, EventArgs e)
    {
      new LogForm().ShowDialog();
    }

    private void StatisticNumberBox_MouseClick(object sender, MouseEventArgs e)
    {
      var keyBoard = new NumberPad();
      if (keyBoard.ShowDialog() == true)
      {
        var box = (sender as TextBox);
        if (string.IsNullOrEmpty(keyBoard.Result))
          box.Text = string.Empty;
        else
        {
          decimal num = 0;

          if (!decimal.TryParse(keyBoard.Result, out num))
            throw new Exception("数量输入有误");
          box.Text = keyBoard.Result;
        }
      }
    }

    private void ViewTaskBtn_Click(object sender, EventArgs e)
    {
      if (string.IsNullOrEmpty(groupKey))
        throw new Exception("请选择存货分组");
      if (batchID == null)
        throw new Exception("请先选择批次");
      if (goodsSetDic == null)
        throw new Exception("请选择存货分组");
      var arr = goodsSetDic[groupKey];
      if(arr.Count==0)
        throw new Exception("分组中没有任何存货");
      var goods = arr.Select(x => new Goods { Code = x.Goods_Code, Name = x.Goods_Name, ID = x.Goods_ID });
      new ViewTaskForm(batchDate ?? DateTime.Today, batchID.Value, goods).ShowDialog();
    }
  }
}
