using ButcherFactory.BO;
using ButcherFactory.BO.LocalBL;
using ButcherFactory.BO.Utils;
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.Tasks;
using System.Windows.Forms;
using WinFormControl;

namespace ButcherFactory.SegmentSaleOut_
{
  public partial class SegmentSaleOutForm : 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<SegmentSaleOut_Detail> weightRecord;
    string strDiscontWeight = "";
    internal DateTime sendTime = DateTime.Today;
    internal long? deliverGoodsLineID;
    internal long? customerID;
    internal int billState;
    internal long? storeID;
    long? batchID;
    bool already = false;
    decimal? discont = null;

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

    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);
      BLUtil.DeleteSaleOutStoreInfo<SegmentSaleOut_Detail>();
      billState = 0;
      billStateBox.Text = "未审核";
      sendDateBox.Text = sendTime.ToString("yyyy-MM-dd");

      var config = XmlUtil.DeserializeFromFile<SegmentSaleOutFormConfig>();
      if (config.Store_ID.HasValue)
      {
        storeBox.Text = config.Store_Name;
        storeID = config.Store_ID;
      }
      if (!string.IsNullOrEmpty(config.DiscontWeight))
        strDiscontWeight = config.DiscontWeight;
      BindProductBatch();
      BindDiscontBtn();
    }

    private void BindProductBatch()
    {
      var batchs = SegmentSaleOutBL.GetBatchFromEMS();
      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 uScanPanel1_AfterScan()
    {
      var barCode = uScanPanel1.TextBox.Text.Trim();
      if (string.IsNullOrEmpty(barCode))
        throw new Exception("条码错误");
      if (already)
        throw new Exception("正在查看已配货记录，不允许配货");
      if (details == null || details.Count == 0)
        throw new Exception("没有订货明细");
      if (weightRecord.Any(x => x.BarCode == barCode))
        throw new Exception("扫码重复");
      if (SegmentSaleOutBL.BarCodeUsed(barCode))
        throw new Exception("扫码重复");
      if (stockUpSendCheck.Checked)
        BatchInsertByScan(barCode);
      else
        InsertDetailByScan(barCode);

      WinFormControl.SoundPalyUtil.PlaySound(WinFormControl.SoundType.Click);
    }

    void InsertDetailByScan(string barCode)
    {
      //var orderDetail = detailGridView.CurrentRow.DataBoundItem as SaleOutStore_Detail;
      var detail = new SegmentSaleOut_Detail();
      detail.BarCode = barCode;
      if (weightRecord.Any())
        detail.Idx = weightRecord.Max(x => x.Idx) + 1;
      else
        detail.Idx = 1;

      var detailID = SegmentSaleOutBL.InsertByCode(details, detail);

      weightRecord.Insert(0, detail);
      weightRecordGridView.FirstDisplayedScrollingRowIndex = 0;
      weightRecordGridView.Refresh();
      BindDetailByLocal(detailID);
    }

    void BatchInsertByScan(string barCode)
    {
      var results = SegmentSaleOutBL.InsertByStockUp(barCode, details);
      var orderDetail = detailGridView.CurrentRow.DataBoundItem as SaleOutStore_Detail;
      var idx = weightRecord.Any() ? weightRecord.Max(x => x.Idx) + 1 : 1;
      foreach (var item in results)
      {
        item.Idx = idx;
        weightRecord.Insert(0, item);
        idx++;
      }
      weightRecordGridView.FirstDisplayedScrollingRowIndex = 0;
      weightRecordGridView.Refresh();

      foreach (var item in details)
      {
        item.SNumber = (item.SNumber ?? 0) + results.Where(x => x.DetailID == item.ID).Sum(x => x.Number);
        if (item.SNumber == 0)
          item.SNumber = null;
        item.SSecondNumber = (item.SSecondNumber ?? 0) + results.Where(x => x.DetailID == item.ID).Sum(x => x.SecondNumber);
        if (item.SSecondNumber == 0)
          item.SSecondNumber = null;
      }
      detailGridView.Refresh();
    }

    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 SegmentSaleOutFormConfig { DiscontWeight = strDiscontWeight, Store_ID = storeID, Store_Name = simpleLbl.Text });
          }
          break;
      }
    }

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

    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 alreadyViewBtn_Click(object sender, EventArgs e)
    {
      already = true;
      Refersh();
    }

    void Refersh()
    {
      goodsFinishBtn.Enabled = !already;
      unFinishBtn.Enabled = already;
      deleteBtn.Enabled = !already;
      readBtn.Enabled = !already;

      saleOutStoreList = SegmentSaleOutBL.GetSaleOutStoreList(sendTime, deliverGoodsLineID, customerID, billState, storeID, already);
      orderGridView.DataSource = saleOutStoreList;
      orderGridView.Refresh();

      BindLabels(saleOutStoreList.FirstOrDefault() ?? new SaleOutStore());

      BindDetailGrid();
    }

    private void weightRecordBtn_Click(object sender, EventArgs e)
    {
      if (detailGridView.CurrentRow == null)
        throw new Exception("请选择配货明细");
      var detail = detailGridView.CurrentRow.DataBoundItem as SaleOutStore_Detail;
      var dg = new SegmentSaleOut_.WeightRecordDialog(details.First(x => x.ID == detail.ID), already, batchID);
      dg.ShowDialog();
      if (dg.Changed)
      {
        weightRecord = SegmentSaleOutBL.GetWeightRecord(detail.ID);
        weightRecordGridView.DataSource = weightRecord;
        weightRecordGridView.Refresh();
        BindDetailByLocal(detail.ID);
      }
    }

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

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

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

    private void AfterChangeFinishGoods(long id)
    {
      saleOutStoreList.Remove(saleOutStoreList.First(x => x.ID == id));
      orderGridView.Refresh();

      details = new BindingList<SaleOutStore_Detail>();
      detailGridView.DataSource = details;
      detailGridView.Refresh();

      weightRecord = new BindingList<SegmentSaleOut_Detail>();
      weightRecordGridView.DataSource = weightRecord;
      weightRecordGridView.Refresh();

      BindLabels(new SaleOutStore());
    }

    private void deleteBtn_Click(object sender, EventArgs e)
    {
      if (weightRecordGridView.CurrentRow == null)
        return;
      if (MessageBox.Show("确定删除选中明细？", "删除确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
        return;
      var id = (long)weightRecordGridView.CurrentRow.Cells[0].Value;
      var tag = weightRecord.First(x => x.ID == id);
      SegmentSaleOutBL.DeleteAndUpdate(tag);
      weightRecord.Remove(tag);
      foreach (var item in weightRecord.Where(x => x.Idx > tag.Idx))
        item.Idx -= 1;
      weightRecordGridView.Refresh();
      BindDetailByLocal(tag.DetailID.Value);
    }

    private void readBtn_Click(object sender, EventArgs e)
    {
      if (weightControl1.Weight == 0)
        return;
      if (already)
        throw new Exception("正在查看已配货记录，不允许配货");
      if (detailGridView.CurrentRow == null)
        throw new Exception("没有订货明细");
      var weight = weightControl1.Weight - (discont ?? 0);
      if (weight <= 0)
        throw new Exception(string.Format("扣重后重量为{0:#0.##}", weight));

      InsertDetailByReadWeight(weight);
    }

    private void InsertDetailByReadWeight(decimal weight)
    {
      var orderDetail = detailGridView.CurrentRow.DataBoundItem as SaleOutStore_Detail;
      var detail = new SegmentSaleOut_Detail();
      detail.Number = weight;
      detail.DiscontWeight = discont;
      if (weightRecord.Any())
        detail.Idx = weightRecord.Max(x => x.Idx) + 1;
      else
        detail.Idx = 1;

      SegmentSaleOutBL.InsertReadWeight(orderDetail, detail);

      weightRecord.Insert(0, detail);
      weightRecordGridView.FirstDisplayedScrollingRowIndex = 0;
      weightRecordGridView.Refresh();
      BindDetailByLocal(orderDetail.ID);
    }

    private void orderGridView_CellClick(object sender, DataGridViewCellEventArgs e)
    {
      if (orderGridView.CurrentRow == null)
        return;
      BindLabels(orderGridView.CurrentRow.DataBoundItem as SaleOutStore);
      BindDetailGrid();
    }

    private void detailGridView_CellClick(object sender, DataGridViewCellEventArgs e)
    {
      BindWeightRecord();
    }

    void BindDetailGrid()
    {
      var row = orderGridView.CurrentRow;
      if (row == null)
        details = new BindingList<SaleOutStore_Detail>();
      else
      {
        var id = long.Parse(billIDLabel.Text);
        details = SegmentSaleOutBL.GetSaleOutStoreDetailList(id);
        foreach (var item in details)
        {
          item.SaleOutStore_ID = id;
          item.Customer_Name = customerLabel.Text;
        }
      }
      detailGridView.DataSource = details;
      detailGridView.Refresh();
      BindWeightRecord();
    }

    void BindWeightRecord()
    {
      var row = detailGridView.CurrentRow;
      if (row == null)
        weightRecord = new BindingList<SegmentSaleOut_Detail>();
      else
        weightRecord = SegmentSaleOutBL.GetWeightRecord((long)row.Cells["D_ID"].Value);
      weightRecordGridView.DataSource = weightRecord;
      weightRecordGridView.Refresh();
    }

    void BindDetailByLocal(long detailID)
    {
      var first = details.First(x => x.ID == detailID);
      var list = weightRecord.Where(x => x.DetailID == detailID);
      first.SNumber = list.Sum(x => x.Number);
      first.SSecondNumber = list.Sum(x => x.SecondNumber ?? 0);
      foreach (DataGridViewRow row in detailGridView.Rows)
      {
        if ((long)row.Cells[0].Value == detailID)
        {
          row.Selected = true;
          break;
        }
      }
      detailGridView.Refresh();
    }

    void BindLabels(SaleOutStore entity)
    {
      billIDLabel.Text = entity.ID == 0 ? "" : entity.ID.ToString();
      customerLabel.Text = entity.Customer_Name;
      addressLabel.Text = entity.Address;
      carNumberLabel.Text = entity.CarNumber;
    }

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

    Color btnColor = Color.FromArgb(10, 106, 201);
    Color selectedColor = Color.FromArgb(255, 0, 25);
    void BindDiscontBtn()
    {
      var arr = strDiscontWeight.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => decimal.Parse(x)).OrderBy(x => x);
      flowLayoutPanel1.Controls.Clear();
      foreach (var v in arr)
      {
        var btn = new ColorButton { Width = 84, Height = 35, BackColor = btnColor, SelectedColor = selectedColor, EnableGroup = true, Margin = new Padding(10, 5, 10, 5), Text = v.ToString("#0.##"), Font = new Font("黑体", 12) };
        btn.Click += delegate { discont = v; disContLbl.Text = discont.Value.ToString("#0.##"); };
        flowLayoutPanel1.Controls.Add(btn);
      }
    }

    private void discontSetBtn_Click(object sender, EventArgs e)
    {
      var dialog = new DiscontSetDialog();
      if (dialog.ShowDialog() == DialogResult.OK)
      {
        strDiscontWeight = dialog.disCont;
        BindDiscontBtn();
      }
    }

    private void disContLbl_Click(object sender, EventArgs e)
    {
      var keyBoard = new NumberPad();
      if (keyBoard.ShowDialog() == true)
      {
        discont = decimal.Parse(keyBoard.Result);
        disContLbl.Text = discont.Value.ToString("#0.##");
      }
    }
  }
}
