using ButcherFactory.BO;
using ButcherFactory.BO.LocalBL;
using ButcherFactory.BO.Utils;
using ButcherFactory.CarcassSaleOut_;
using ButcherFactory.Controls;
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;

namespace ButcherFactory.CarcassSaleOut2_
{
  public partial class CarcassSaleOutForm : FormTemplate, IWithRoleForm
  {
    #region IWithRoleForm
    public List<short> RoleName
    {
      get { return new List<short> { (short)设备类别.白条发货 }; }
    }

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

    BindingList<SaleOutStore> saleOutStoreList;
    BindingList<SaleOutStore_Detail> details;
    BindingList<CarcassSaleOut_Detail> weightRecord;
    Thread checkWeight;
    string strErrorWeight = "";
    List<int> errorWeight = new List<int>();
    internal DateTime sendTime = DateTime.Today;
    internal long? deliverGoodsLineID;
    internal long? customerID;
    internal int billState;
    internal long? storeID;
    long? batchID;
    bool already = false;
    bool scanCode = true;
    DateTime? mProductTime = null;

    public CarcassSaleOutForm()
    {
      InitializeComponent();
      this.FormClosing += delegate
      {
        if (checkWeight != null && checkWeight.IsAlive)
          checkWeight.Abort();
      };
      weightControl1.ReceivedValue += weightControl1_ReceivedValue;

      uScanPanel1.AfterScan += uScanPanel1_AfterScan;
      productBatchSelect.SelectedIndexChanged += delegate
      {
        if (productBatchSelect.SelectedValue == null)
        {
          batchID = null;
          mProductTime = null;
        }
        else
        {
          batchID = (long)productBatchSelect.SelectedValue;
          mProductTime = (productBatchSelect.SelectedItem as ProductBatch).Date;
        }
      };

      sendGridView.CellFormatting += sendGridView_CellFormatting;
    }

    static Image CheckImg = System.Drawing.Image.FromFile("Images\\check.png");
    static Image UnCheckImg = System.Drawing.Image.FromFile("Images\\uCheck.png");

    void sendGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
      if (e.RowIndex < 0 || e.ColumnIndex != 2)
        return;
      var v = (bool)sendGridView.Rows[e.RowIndex].Cells[1].Value;
      e.Value = v ? CheckImg : UnCheckImg;
    }

    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);

      BLUtil.DeleteSaleOutStoreInfo<CarcassSaleOut_Delete>();
      BLUtil.DeleteSaleOutStoreInfo<CarcassSaleOut_Detail>();
      billState = 0;
      billStateBox.Text = "未审核";
      sendDateBox.Text = sendTime.ToString("yyyy-MM-dd");

      var config = XmlUtil.DeserializeFromFile<CarcassSaleOutFormConfig>();
      if (config.Store_ID.HasValue)
      {
        storeBox.Text = config.Store_Name;
        storeID = config.Store_ID;
      }
      if (!string.IsNullOrEmpty(config.Weight))
      {
        strErrorWeight = config.Weight;
        var arr = strErrorWeight.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).OrderBy(x => x);
        errorWeight.AddRange(arr);
      }
      BindWeightRecord();
      BindProductBatch();
    }

    void BindWeightRecord()
    {
      weightRecord = CarcassSaleOutBL.GetUnSubmitWeightRecord();
      sendGridView.DataSource = weightRecord;
      sendGridView.Refresh();
    }

    private void BindProductBatch()
    {
      var batchs = CarcassSaleOutBL.GetBatchFromEMS(0);
      productBatchSelect.DisplayMember = "Name";
      productBatchSelect.ValueMember = "ID";

      productBatchSelect.DataSource = batchs;
      var idx = batchs.FindIndex(x => x.Date == DateTime.Today);
      if (idx > 0)
        productBatchSelect.SelectedIndex = idx;
      productBatchSelect.Refresh();
    }

    static object _lock = new object();
    void weightControl1_ReceivedValue(decimal weight)
    {
      lock (_lock)
      {
        this.Invoke(new Action(() =>
        {
          var detail = CarcassSaleOutBL.Insert(weight);
          if (weightRecord.Any())
            detail.Idx = weightRecord.First().Idx + 1;
          else
            detail.Idx = 1;
          weightRecord.Insert(0, detail);
          sendGridView.FirstDisplayedScrollingRowIndex = 0;
          if (!scanCode)
            AfterScan("G8536");
          else
            sendGridView.Refresh();
          checkWeight = new Thread(new ParameterizedThreadStart(CheckWeight));
          checkWeight.Start(weight);
        }));
      }
    }

    void CheckWeight(object objWeight)
    {
      decimal weight = (decimal)objWeight;
      var first = errorWeight.FirstOrDefault(x => x > weight);
      if (first != 0)
        WinFormControl.SoundPalyUtil.PlaySound(string.Format("Sounds\\l{0}.wav", first));
    }

    void uScanPanel1_AfterScan()
    {
      var barCode = uScanPanel1.TextBox.Text.Trim();
      if (!barCode.StartsWith("G") && !barCode.StartsWith("P"))
      {
        if (weightRecord.Any(x => x.BarCode == barCode))//未提交队列里重复码
          throw new Exception("扫码重复");
        if (CarcassSaleOutBL.BarCodeUsed(barCode))
          throw new Exception("扫码重复");
      }
      AfterScan(barCode);
    }

    void AfterScan(string barCode)
    {
      if (string.IsNullOrEmpty(barCode))
        throw new Exception("条码错误");
      if (barCode.StartsWith("P"))
      {
        if (orderGridView.CurrentRow == null)
          throw new Exception("请选择发货明细");
        var detail = new CarcassSaleOut_Detail();
        var bind = orderGridView.CurrentRow.DataBoundItem as SaleOutStore_Detail;
        detail.Weight = detail.Number = bind.Number ?? 0;
        detail.BarCode = barCode;
        detail.BillID = bind.SaleOutStore_ID;
        detail.DetailID = bind.ID;
        detail.Filled = true;
        detail.Goods_ID = long.Parse(barCode.TrimStart('P'));
        CarcassSaleOutBL.InsertPackage(detail);
        if (weightRecord.Any())
          detail.Idx = weightRecord.First().Idx + 1;
        else
          detail.Idx = 1;
        weightRecord.Insert(0, detail);
        sendGridView.FirstDisplayedScrollingRowIndex = 0;
      }
      else
      {
        var first = weightRecord.LastOrDefault(x => !x.Filled);
        if (first == null)
          return;
        //throw new Exception("请先过磅");
        CarcassSaleOutBL.FillDetail(first, barCode, batchID);
      }
      WinFormControl.SoundPalyUtil.PlaySound(WinFormControl.SoundType.Click);
      sendGridView.Refresh();
    }

    private void refreshBtn_Click(object sender, EventArgs e)
    {
      already = false;
      Refersh();
    }

    private void weightRecordBtn_Click(object sender, EventArgs e)
    {
      if (orderGridView.CurrentRow == null)
        throw new Exception("请选择配货明细");
      var detail = orderGridView.CurrentRow.DataBoundItem as SaleOutStore_Detail;
      var dg = new WeightRecordDialog(details.First(x => x.ID == detail.ID), already, batchID, mProductTime);
      dg.ShowDialog();
      if (dg.Changed)
        BindOrderGrid(detail.SaleOutStore_ID);
      if (dg.rolBack)
        BindWeightRecord();
    }

    private void goodsFinishBtn_Click(object sender, EventArgs e)
    {
      if (mainGridView.CurrentRow == null)
        throw new Exception("请选择要配货完成的发货单");
      var id = (long)mainGridView.CurrentRow.Cells[0].Value;

      var hasNoAssignDetail = CarcassSaleOutBL.HasNoAssignDetail(id);
      if (hasNoAssignDetail)
      {
        if (MessageBox.Show("有未配货的明细，确认配货完成？", "配货完成确认", MessageBoxButtons.OKCancel) != DialogResult.OK)
          return;
      }
      CarcassSaleOutBL.SetGoodsFinish(id);
      AfterChangeFinishGoods(id);
      MessageBox.Show("配货完成！");
    }

    private void unFinishBtn_Click(object sender, EventArgs e)
    {
      if (mainGridView.CurrentRow == null)
        throw new Exception("请选择要撤销完毕的发货单");
      var id = (long)mainGridView.CurrentRow.Cells[0].Value;
      CarcassSaleOutBL.SetGoodsUnFinish(id);
      AfterChangeFinishGoods(id);
      MessageBox.Show("撤销成功！");
    }

    private void AfterChangeFinishGoods(long id)
    {
      saleOutStoreList.Remove(saleOutStoreList.First(x => x.ID == id));
      mainGridView.Refresh();
      if (details != null)
        details.Clear();
      orderGridView.Refresh();

      billIDLabel.Text = string.Empty;
      customerLabel.Text = string.Empty;
      addressLabel.Text = string.Empty;
      carNumberLabel.Text = string.Empty;
    }

    private void commitBtn_Click(object sender, EventArgs e)
    {
      if (orderGridView.CurrentRow == null)
        throw new Exception("请选择配货明细");
      var subList = weightRecord.Where(x => x.Selected).ToList();
      if (subList.Count() == 0)
        throw new Exception("没有发货明细");
      if (subList.Any(x => !x.Filled))
        throw new Exception("有未扫码的明细");
      var detailID = (long)orderGridView.CurrentRow.Cells[0].Value;
      var detail = details.First(x => x.ID == detailID);
      CarcassSaleOutBL.SubmitDetails(subList, detail, mProductTime);
      foreach (var item in subList)
        weightRecord.Remove(item);
      var idx = weightRecord.Count;
      foreach (var item in weightRecord)
      {
        item.Idx = idx;
        idx--;
      }

      sendGridView.Refresh();
      orderGridView.Refresh();
      MessageBox.Show("提交成功！");
    }

    private void queryControl_MouseDown(object sender, MouseEventArgs e)
    {
      var simpleLbl = sender as Label;
      switch (simpleLbl.Name)
      {
        case "sendDateBox":
          var cs = new CalendarSelecter();
          if (cs.ShowDialog() == true)
          {
            sendTime = cs.Result;
            sendDateBox.Text = sendTime.ToString("yyyy-MM-dd");
          }
          break;
        case "deliverGoodsLineBox":
          var dgl = new SelectDeliverGoodsLineDialog();
          if (dgl.ShowDialog() == DialogResult.OK)
          {
            simpleLbl.Text = dgl.Result.Item1;
            deliverGoodsLineID = dgl.Result.Item2;
          }
          break;
        case "customerBox":
          var cb = new SelectCustomerDialog();
          if (cb.ShowDialog() == DialogResult.OK)
          {
            simpleLbl.Text = cb.Result.Item1;
            customerID = cb.Result.Item2;
          }
          break;
        case "billStateBox":
          var bs = new SelectBillStateDialog();
          if (bs.ShowDialog() == DialogResult.OK)
          {
            simpleLbl.Text = bs.Result.Item1;
            billState = bs.Result.Item2;
          }
          break;
        case "storeBox":
          var sb = new SelectStoreDialog();
          if (sb.ShowDialog() == DialogResult.OK)
          {
            simpleLbl.Text = sb.Result.Item1;
            storeID = sb.Result.Item2;
            XmlUtil.SerializerObjToFile(new CarcassSaleOutFormConfig { Weight = strErrorWeight, Store_ID = storeID, Store_Name = simpleLbl.Text });
          }
          break;
      }
    }

    private void clearBtn_Click(object sender, EventArgs e)
    {
      billState = 0;
      billStateBox.Text = "未审核";

      sendTime = DateTime.Today;
      sendDateBox.Text = sendTime.ToString("yyyy-MM-dd");

      deliverGoodsLineBox.Text = string.Empty;
      deliverGoodsLineID = null;

      customerBox.Text = string.Empty;
      customerID = null;

      storeBox.Text = string.Empty;
      storeID = null;
    }

    private void mainGridView_CellClick(object sender, DataGridViewCellEventArgs e)
    {
      var id = (long)mainGridView.CurrentRow.Cells[0].Value;
      var first = saleOutStoreList.First(x => x.ID == id);
      billIDLabel.Text = id.ToString();
      customerLabel.Text = first.Customer_Name;
      addressLabel.Text = first.Address;
      carNumberLabel.Text = first.CarNumber;
      BindOrderGrid(null);
    }

    void BindOrderGrid(long? detailID)
    {
      var id = long.Parse(billIDLabel.Text);
      details = CarcassSaleOutBL.GetSaleOutStoreDetailList(id);
      foreach (var item in details)
      {
        item.SaleOutStore_ID = id;
        item.Customer_Name = customerLabel.Text;
      }
      orderGridView.DataSource = details;
      if (detailID.HasValue)
      {
        foreach (DataGridViewRow row in orderGridView.Rows)
        {
          if ((long)row.Cells[0].Value == detailID)
          {
            row.Selected = true;
            break;
          }
        }
      }
      else
      {
        if (details.Any())
          orderGridView.FirstDisplayedScrollingRowIndex = 0;
      }
      orderGridView.Refresh();
    }

    private void alreadyViewBtn_Click(object sender, EventArgs e)
    {
      already = true;
      Refersh();
    }

    void Refersh()
    {
      commitBtn.Enabled = !already;
      goodsFinishBtn.Enabled = !already;
      unFinishBtn.Enabled = already;
      if (details != null)
      {
        details.Clear();
        orderGridView.Refresh();
      }

      saleOutStoreList = CarcassSaleOutBL.GetSaleOutStoreList(sendTime, deliverGoodsLineID, customerID, billState, storeID, already);
      mainGridView.DataSource = saleOutStoreList;
      mainGridView.Refresh();
    }

    private void deleteBtn_Click(object sender, EventArgs e)
    {
      if (sendGridView.CurrentRow == null)
        return;
      var id = (long)sendGridView.CurrentRow.Cells[0].Value;
      CarcassSaleOutBL.Delete(id);
      var tag = weightRecord.First(x => x.ID == id);
      weightRecord.Remove(tag);
      foreach (var item in weightRecord.Where(x => x.Idx > tag.Idx))
        item.Idx -= 1;
      sendGridView.Refresh();
    }

    private void orderGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
    {
      DataGridViewRow dgrSingle = orderGridView.Rows[e.RowIndex];
      var v = (decimal?)dgrSingle.Cells["D_SNumber"].Value;
      if (v.HasValue && v > 0)
      {
        dgrSingle.DefaultCellStyle.BackColor = Color.YellowGreen;
      }
    }

    private void sendGridView_CellClick(object sender, DataGridViewCellEventArgs e)
    {
      if (e.RowIndex == -1 && e.ColumnIndex == 2)
      {
        foreach (var item in weightRecord)
          item.Selected = !item.Selected;
        sendGridView.Refresh();
        return;
      }
      if (e.RowIndex < 0)
        return;
      var id = (long)sendGridView.CurrentRow.Cells[0].Value;
      var first = weightRecord.First(x => x.ID == id);
      first.Selected = !first.Selected;
      sendGridView.Refresh();
    }

    private void halfBtn_Click(object sender, EventArgs e)
    {
      SetWeightNumber(0.5m);
    }

    private void fullBtn_Click(object sender, EventArgs e)
    {
      SetWeightNumber(1);
    }

    private void SetWeightNumber(decimal number)
    {
      if (sendGridView.CurrentRow == null)
        return;
      var id = (long)sendGridView.CurrentRow.Cells[0].Value;
      CarcassSaleOutBL.UpdateWeightNumber(id, number);
      var first = weightRecord.First(x => x.ID == id);
      first.Selected = true;
      first.Number = number;
      sendGridView.Refresh();
    }

    private void scanCodeBtn_Click(object sender, EventArgs e)
    {
      scanCode = !scanCode;
      scanCodeBtn.Text = scanCode ? "扫码发货" : "自动发货";
    }
  }
}
