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

namespace ButcherFactory.CarcassSaleOut_
{
  public partial class CarcassSaleOutForm : Form, 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;
    public CarcassSaleOutForm()
    {
      InitializeComponent();
      this.Resize += CarcassSaleOutForm_Resize;
      this.FormClosing += delegate
      {
        if (checkWeight != null && checkWeight.IsAlive)
          checkWeight.Abort();
      };
      uWeightControl1.ReceivedValue += uWeightControl1_ReceivedValue;

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

      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);
      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);
      }
      this.mainGridView.BorderStyle = BorderStyle.FixedSingle;
      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();
    }

    void CarcassSaleOutForm_Resize(object sender, EventArgs e)
    {
      if (this.Height < this.MinimumSize.Height)
        return;
      groupBox1.Height = (this.Height - 200) / 2;
      groupBox2.Height = groupBox1.Height;
      groupBox2.Location = new Point(groupBox2.Location.X, groupBox1.Height + 100);
    }

    static object _lock = new object();
    void uWeightControl1_ReceivedValue(decimal weight)
    {
      lock (_lock)
      {
        this.Invoke(new Action(() =>
        {
          var detail = CarcassSaleOutBL.Insert(weight);
          if (weightRecord.Any())
            detail.Idx = weightRecord.Max(x => x.Idx) + 1;
          else
            detail.Idx = 1;
          weightRecord.Insert(0, detail);
          sendGridView.FirstDisplayedScrollingRowIndex = 0;
          if (!checkBox1.Checked)
            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)
        SoundPalyUtil.PlaySound(string.Format("Sounds\\l{0}.wav", first));
    }

    void uScanPanel1_AfterScan()
    {
      var barCode = uScanPanel1.TextBox.Text.Trim();
      if (!barCode.StartsWith("G") && weightRecord.Any(x => x.BarCode == barCode))
        return;
      AfterScan(barCode);
    }

    void AfterScan(string barCode)
    {
      if (string.IsNullOrEmpty(barCode))
        throw new Exception("条码错误");
      var first = weightRecord.LastOrDefault(x => !x.Filled);
      if (first == null)
        return;
      //throw new Exception("请先过磅");
      CarcassSaleOutBL.FillDetail(first, barCode, batchID);
      SoundPalyUtil.PlaySound(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);
      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 ds = CarcassSaleOutBL.GetSaleOutStoreDetailList(id);
      if (ds.Any(x => x.SSecondNumber == null || x.SSecondNumber == 0))
      {
        if (MessageBox.Show("有未配货的明细，确认配货完成？", "配货完成确认", MessageBoxButtons.OKCancel) != DialogResult.OK)
          return;
      }
      CarcassSaleOutBL.SetGoodsFinish(id); 
      AfterChangeFinishGoods(id);
      UMessageBox.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);
      UMessageBox.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);
      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();
      UMessageBox.Show("提交成功！");
    }

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

    private void queryControl_MouseDown(object sender, MouseEventArgs e)
    {
      var textBox = sender as TextBox;
      switch (textBox.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)
          {
            textBox.Text = dgl.Result.Item1;
            deliverGoodsLineID = dgl.Result.Item2;
          }
          break;
        case "customerBox":
          var cb = new SelectCustomerDialog();
          if (cb.ShowDialog() == DialogResult.OK)
          {
            textBox.Text = cb.Result.Item1;
            customerID = cb.Result.Item2;
          }
          break;
        case "billStateBox":
          var bs = new SelectBillStateDialog();
          if (bs.ShowDialog() == DialogResult.OK)
          {
            textBox.Text = bs.Result.Item1;
            billState = bs.Result.Item2;
          }
          break;
        case "storeBox":
          var sb = new SelectStoreDialog();
          if (sb.ShowDialog() == DialogResult.OK)
          {
            textBox.Text = sb.Result.Item1;
            storeID = sb.Result.Item2;
            XmlUtil.SerializerObjToFile(new CarcassSaleOutFormConfig { Weight = strErrorWeight, Store_ID = storeID, Store_Name = textBox.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.Clear();
      deliverGoodsLineID = null;

      customerBox.Clear();
      customerID = null;

      storeBox.Clear();
      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 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 sendGridView_CellClick(object sender, DataGridViewCellEventArgs e)
    {

    }
  }
}
