using BBWY.Client.APIServices;
using BBWY.Client.Models;
using BBWY.Client.Views.BillCorrection;
using BBWY.Common.Models;
using BBWY.Common.Trigger;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
using Newtonsoft.Json;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using BBWY.Common.Extensions;

namespace BBWY.Client.ViewModels
{
    public class BillCorrectionViewModel : BaseVM, IDenpendency
    {
        private BillCorrectionService billCorrectionService;
        private string searchShopKeyWord;
        private DelayTrigger delayTrigger;
        private bool isLoading;
        private KVModel selectedLocalFilterOperation;
        private bool isEnableCanCorrectionOrder;
        private KVModel selectedStorageType;
        private string searchLocalOrderId;
        private Shop selectedLocalShop;
        private Shop allShop;
        private KVModel allStorageType;

        private GlobalContext globalContext;

        public DateTime StartDate { get; set; }

        public DateTime EndDate { get; set; }

        /// <summary>
        /// 销售运费快递账单文件列表
        /// </summary>
        public ObservableCollection<string> SaleFreightBillFileList { get; set; }

        /// <summary>
        /// 销售运费账单列表
        /// </summary>
        public List<BillModel> SaleFreightBillList { get; set; }



        public IList<Shop> ShopList { get; set; }

        public IList<Shop> LocalShopList { get; set; }

        /// <summary>
        /// 店铺搜索关键词
        /// </summary>
        public string SearchShopKeyWord
        {
            get => searchShopKeyWord;
            set
            {
                if (Set(ref searchShopKeyWord, value))
                {
                    delayTrigger.SetKey(value);
                }
            }
        }

        /// <summary>
        /// 导入快递账单
        /// </summary>
        public ICommand ImportSaleFreightBillCommand { get; set; }

        /// <summary>
        /// 查询订单
        /// </summary>
        public ICommand SearchBillCorrectionOrderCommand { get; set; }

        /// <summary>
        /// 清空数据
        /// </summary>
        public ICommand ClearCommand { get; set; }

        /// <summary>
        /// 矫正费用
        /// </summary>
        public ICommand CorrectCommand { get; set; }

        public ICommand SearchLocalCommand { get; set; }

        public ICommand ClearLocalConditionCommand { get; set; }

        /// <summary>
        /// 保存
        /// </summary>
        public ICommand SaveCommand { get; set; }

        public bool IsLoading { get => isLoading; set { Set(ref isLoading, value); } }

        public IList<BillCorrectionOrder> OrderList { get; set; }

        public IList<BillCorrectionOrder> LocalOrderList { get; set; }

        public IList<KVModel> LocalFilterOperationList { get; set; }

        public IList<KVModel> LocalStorageTypeList { get; set; }

        public KVModel SelectedLocalFilterOperation { get => selectedLocalFilterOperation; set { Set(ref selectedLocalFilterOperation, value); } }

        public bool IsEnableCanCorrectionOrder { get => isEnableCanCorrectionOrder; set { Set(ref isEnableCanCorrectionOrder, value); } }

        public KVModel SelectedStorageType { get => selectedStorageType; set { Set(ref selectedStorageType, value); } }

        public string SearchLocalOrderId { get => searchLocalOrderId; set { Set(ref searchLocalOrderId, value); } }

        public Shop SelectedLocalShop { get => selectedLocalShop; set { Set(ref selectedLocalShop, value); } }


        public BillCorrectionViewModel(GlobalContext globalContext, BillCorrectionService billCorrectionService)
        {
            this.billCorrectionService = billCorrectionService;
            this.globalContext = globalContext;
            var shopList = JsonConvert.DeserializeObject<List<Shop>>(JsonConvert.SerializeObject(globalContext.User.ShopList));
            this.ShopList = new ObservableCollection<Shop>(shopList);
            this.LocalShopList = new ObservableCollection<Shop>();
            SaleFreightBillFileList = new ObservableCollection<string>();
            SaleFreightBillList = new List<BillModel>();
            StartDate = DateTime.Now.Date.AddDays((DateTime.Now.Day - 1) * -1).AddMonths(-1);
            EndDate = StartDate.AddMonths(1).AddDays(-1);
            delayTrigger = new DelayTrigger(500);
            delayTrigger.OnExecute = OnSearchShopKeyWordChanged;
            OrderList = new ObservableCollection<BillCorrectionOrder>();
            LocalOrderList = new ObservableCollection<BillCorrectionOrder>();
            LocalFilterOperationList = new List<KVModel>()
            {
                new KVModel(){ Key="保留",Value="save" },
                new KVModel(){ Key="过滤",Value="filter"}
            };
            LocalStorageTypeList = new List<KVModel>();

            var storageTypeArray = Enum.GetValues(typeof(StorageType));
            foreach (var storageType in storageTypeArray)
            {
                LocalStorageTypeList.Add(new KVModel()
                {
                    Key = storageType.ToString(),
                    Value = ((int)storageType).ToString()
                });
            }
            ImportSaleFreightBillCommand = new RelayCommand<string>(ImportSaleFreightBill);
            SearchBillCorrectionOrderCommand = new RelayCommand(SearchBillCorrectionOrder);
            CorrectCommand = new RelayCommand(Correct);
            ClearCommand = new RelayCommand(Clear);
            SearchLocalCommand = new RelayCommand(SearchLocalOrderList);
            ClearLocalConditionCommand = new RelayCommand(ClearLocalCondition);
            SaveCommand = new RelayCommand(Save);
            SelectedLocalFilterOperation = LocalFilterOperationList[0];
            allShop = new Shop() { ShopId = 0, ShopName = "全部" };
            allStorageType = new KVModel() { Key = "全部", Value = string.Empty };

            LocalStorageTypeList.Insert(0, allStorageType);
            SelectedStorageType = allStorageType;

            LocalShopList.Insert(0, allShop);
            SelectedLocalShop = allShop;
        }

        private void OnSearchShopKeyWordChanged(string key)
        {
            foreach (var s in this.ShopList)
                s.IsSelected = false;

            App.Current.Dispatcher.Invoke(() =>
            {
                this.ShopList.Clear();

                var keyWordShopList = string.IsNullOrEmpty(key) ? globalContext.User.ShopList : globalContext.User.ShopList.Where(s => s.ShopName.Contains(key));
                if (keyWordShopList.Count() > 0)
                {
                    foreach (var shop in keyWordShopList)
                        ShopList.Add(shop);
                }
            });
        }

        private void ImportSaleFreightBill(string expressName)
        {
            var ofd = new OpenFileDialog() { Filter = "excel文件|*.xlsx;*.xls" };
            if (ofd.ShowDialog() != true)
                return;
            var fileName = ofd.FileName.Substring(ofd.FileName.LastIndexOf("\\") + 1);
            var filePath = ofd.FileName;
            if (SaleFreightBillFileList.Contains(fileName))
            {
                MessageBox.Show("请勿重复导入快递账单", "导入快递账单");
                return;
            }
            IWorkbook xbook = null;
            try
            {
                using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    if (filePath.EndsWith(".xls"))
                        xbook = new HSSFWorkbook(fs);
                    else if (filePath.EndsWith(".xlsx"))
                        xbook = new XSSFWorkbook(fs);
                }
                using (xbook)
                {
                    IList<BillModel> billModelList = null;
                    if (expressName == "YT")
                    {
                        var basicAmountW = new YTBasicAmount();
                        if (basicAmountW.ShowDialog() != true)
                            return;
                        var basicAmount = basicAmountW.BasicAmount;
                        billModelList = LoadYTSaleBillFile(xbook, fileName, basicAmount);
                    }
                    else if (expressName == "YZ")
                    {
                        billModelList = LoadYZSaleBillFile(xbook, fileName);
                    }
                    else if (expressName == "JD")
                    {
                        billModelList = LoadJDSaleBillFile(xbook, fileName);
                    }
                    if (billModelList != null && billModelList.Count() > 0)
                    {
                        SaleFreightBillList.AddRange(billModelList);
                        SaleFreightBillFileList.Add(fileName);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "导入账单失败提示");
                return;
            }
        }

        /// <summary>
        /// 读取圆通运费账单
        /// </summary>
        /// <param name="xbook"></param>
        /// <param name="belongFileName"></param>
        /// <param name="basicSaleFreight">基础面单价格</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private IList<BillModel> LoadYTSaleBillFile(IWorkbook xbook, string belongFileName, decimal basicSaleFreight)
        {
            var sheet = xbook.GetSheetAt(0);
            var waybillNoCellTitle = sheet.GetRow(0).GetCell(1);
            if (waybillNoCellTitle == null || waybillNoCellTitle.StringCellValue != "运单号码")
                throw new Exception("验证圆通快递账单失败-未读取到运单号码");
            var saleExpressFreightCellTitle = sheet.GetRow(0).GetCell(5);
            if (saleExpressFreightCellTitle == null || saleExpressFreightCellTitle.StringCellValue != "补差")
                throw new Exception("验证圆通快递账单失败-未读取到补差");

            var rowCount = sheet.LastRowNum;
            IList<BillModel> list = new List<BillModel>();
            for (var i = 1; i < rowCount; i++)
            {
                var row = sheet.GetRow(i);
                if (row == null)
                    break;
                var waybillNoCell = row.GetCell(1);
                if (string.IsNullOrEmpty(waybillNoCell.StringCellValue))
                    break;
                var saleExpressFreightCell = row.GetCell(5);
                list.Add(new BillModel()
                {
                    Amount = Convert.ToDecimal(saleExpressFreightCell.NumericCellValue) + basicSaleFreight,
                    BillNo = waybillNoCell.StringCellValue,
                    BillType = BillCorrectionType.销售运费账单,
                    BelongFileName = belongFileName
                });
            }
            return list;
        }

        /// <summary>
        /// 读取邮政运费账单
        /// </summary>
        /// <param name="xbook"></param>
        /// <param name="belongFileName"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private IList<BillModel> LoadYZSaleBillFile(IWorkbook xbook, string belongFileName)
        {
            var sheet = xbook.GetSheetAt(0);
            var waybillNoCellTitle = sheet.GetRow(0).GetCell(2);
            if (waybillNoCellTitle == null || waybillNoCellTitle.StringCellValue != "邮件号")
                throw new Exception("验证邮政快递账单失败-未读取到邮件号");
            var saleExpressFreightCellTitle = sheet.GetRow(0).GetCell(8);
            if (saleExpressFreightCellTitle == null || saleExpressFreightCellTitle.StringCellValue != "总邮资")
                throw new Exception("验证邮政快递账单失败-未读取到总邮资");

            var rowCount = sheet.LastRowNum;
            IList<BillModel> list = new List<BillModel>();
            for (var i = 1; i < rowCount; i++)
            {
                var row = sheet.GetRow(i);
                if (row == null)
                    break;
                var waybillNoCell = row.GetCell(2);
                if (string.IsNullOrEmpty(waybillNoCell.StringCellValue))
                    break;
                var saleExpressFreightCell = row.GetCell(8);
                list.Add(new BillModel()
                {
                    Amount = Convert.ToDecimal(saleExpressFreightCell.NumericCellValue),
                    BillNo = waybillNoCell.StringCellValue,
                    BillType = BillCorrectionType.销售运费账单,
                    BelongFileName = belongFileName
                });
            }
            return list;
        }

        /// <summary>
        /// 读取JD运费账单
        /// </summary>
        /// <param name="xbook"></param>
        /// <param name="belongFileName"></param>
        /// <returns></returns>
        private IList<BillModel> LoadJDSaleBillFile(IWorkbook xbook, string belongFileName)
        {
            var sheet = xbook.GetSheetAt(1);
            if (sheet == null)
                throw new Exception("验证JD快递账单失败-未读取到sheet1");
            var waybillNoCellTitle = sheet.GetRow(0).GetCell(2);
            if (waybillNoCellTitle == null || waybillNoCellTitle.StringCellValue != "运单号")
                throw new Exception("验证JD快递账单失败-未读取到运单号");
            var saleExpressFreightCellTitle = sheet.GetRow(0).GetCell(35);
            if (saleExpressFreightCellTitle == null || saleExpressFreightCellTitle.StringCellValue != "结算金额")
                throw new Exception("验证JD快递账单失败-未读取到结算金额");
            var rowCount = sheet.LastRowNum;
            IList<BillModel> list = new List<BillModel>();
            for (var i = 1; i < rowCount; i++)
            {
                var row = sheet.GetRow(i);
                if (row == null)
                    break;
                var waybillNoCell = row.GetCell(2);
                if (string.IsNullOrEmpty(waybillNoCell.StringCellValue))
                    break;
                var saleExpressFreightCell = row.GetCell(35);
                var b = list.FirstOrDefault(b => b.BillNo == waybillNoCell.StringCellValue);
                if (b == null)
                {
                    b = new BillModel()
                    {
                        BelongFileName = belongFileName,
                        BillNo = waybillNoCell.StringCellValue,
                        BillType = BillCorrectionType.销售运费账单
                    };
                    list.Add(b);
                }
                b.Amount += Convert.ToDecimal(saleExpressFreightCell.NumericCellValue);
            }
            return list;
        }

        /// <summary>
        /// 查询
        /// </summary>
        private void SearchBillCorrectionOrder()
        {
            OrderList.Clear();
            LocalShopList.Clear();
            var selectShops = ShopList.Where(s => s.IsSelected).ToList();
            if (selectShops.Count() == 0)
            {
                MessageBox.Show("至少选择一个店铺", "提示");
                return;
            }
            IsLoading = true;
            foreach (var shop in selectShops)
                LocalShopList.Add(shop);
            LocalShopList.Insert(0, allShop);
            SelectedLocalShop = LocalShopList[0];
            var shopIds = selectShops.Select(s => s.ShopId).ToList();
            Task.Factory.StartNew(() => billCorrectionService.GetBillCorrectionOrderList(shopIds, StartDate, EndDate))
                        .ContinueWith(t =>
                        {
                            IsLoading = false;
                            var response = t.Result;
                            if (!response.Success)
                            {
                                App.Current.Dispatcher.Invoke(() => MessageBox.Show(response.Msg, "提示"));
                                return;
                            }
                            if (response.Data == null || response.Data.Count() == 0)
                                return;

                            var list = response.Data.Map<IList<BillCorrectionOrder>>();

                            App.Current.Dispatcher.Invoke(() =>
                            {
                                foreach (var order in list)
                                {
                                    //if (string.IsNullOrEmpty(order.WaybillNo))
                                    //    continue;
                                    //var billModel = SaleFreightBillList.FirstOrDefault(b => b.BillNo == order.WaybillNo);
                                    //if (billModel == null)
                                    //    continue;

                                    //if (billModel.Amount != order.DeliveryExpressFreight)
                                    //{
                                    //    order.NewDeliveryExpressFreight = billModel.Amount;
                                    //    order.ChangedContent = $"销售运费 {order.DeliveryExpressFreight} -> {order.NewDeliveryExpressFreight}";
                                    //}
                                    OrderList.Add(order);
                                }
                                SearchLocalOrderList();
                            });
                        });
        }

        private void SearchLocalOrderList()
        {
            LocalOrderList.Clear();
            var where = OrderList.Where(o => true);
            if (SelectedLocalShop != null && SelectedLocalShop.ShopId != 0)
                where = where.Where(o => o.ShopId == SelectedLocalShop.ShopId);
            if (SelectedStorageType != null && !string.IsNullOrEmpty(SelectedStorageType.Value))
                where = where.Where(o => o.StorageType == (StorageType)Convert.ToInt32(SelectedStorageType.Value));
            if (!string.IsNullOrEmpty(SearchLocalOrderId))
                where = where.Where(o => o.OrderId == SearchLocalOrderId);
            if (IsEnableCanCorrectionOrder)
            {
                if (SelectedLocalFilterOperation.Value == "save")
                    where = where.Where(o => !string.IsNullOrEmpty(o.ChangedContent));
                else
                    where = where.Where(o => string.IsNullOrEmpty(o.ChangedContent));
            }
            var list = where.ToList();
            foreach (var o in list)
                LocalOrderList.Add(o);
        }

        /// <summary>
        /// 矫正费用
        /// </summary>
        private void Correct()
        {
            if (OrderList.Count() == 0)
            {
                MessageBox.Show("缺少待矫正订单");
                return;
            }
            if (SaleFreightBillList.Count() == 0)
            {
                MessageBox.Show("缺少运费账单");
                return;
            }

            foreach (var order in OrderList)
            {
                //矫正销售运费
                if (!string.IsNullOrEmpty(order.WaybillNo))
                {
                    var expressBillModel = SaleFreightBillList.FirstOrDefault(b => b.BillNo == order.WaybillNo);
                    if (expressBillModel != null && expressBillModel.Amount != order.DeliveryExpressFreight)
                    {
                        order.NewDeliveryExpressFreight = expressBillModel.Amount;
                        order.ChangedContent = $"销售运费{order.DeliveryExpressFreight}->{order.NewDeliveryExpressFreight} ";
                    }
                }

                //矫正入仓操作


                //矫正出仓操作

            }
            var correctionCount = OrderList.Count(o => !string.IsNullOrEmpty(o.ChangedContent));
            MessageBox.Show($"矫正完成,本次矫正{correctionCount}笔订单", "矫正费用");
        }

        private void Clear()
        {
            SaleFreightBillFileList.Clear();
            SaleFreightBillList.Clear();
            OrderList.Clear();
            LocalOrderList.Clear();
            SelectedStorageType = allStorageType;
            IsEnableCanCorrectionOrder = false;
            SearchShopKeyWord = string.Empty;
            SearchLocalOrderId = string.Empty;
            SelectedLocalShop = allShop;
            SelectedLocalFilterOperation = LocalFilterOperationList[0];
        }

        private void ClearLocalCondition()
        {
            SelectedStorageType = allStorageType;
            IsEnableCanCorrectionOrder = false;
            SearchLocalOrderId = string.Empty;
            SelectedLocalShop = allShop;
            SearchLocalOrderList();
        }

        private void Save()
        {
            var saveOrderList = OrderList.Where(o => !string.IsNullOrEmpty(o.ChangedContent));
            if (saveOrderList.Count() == 0)
            {
                MessageBox.Show("没有需要矫正的订单", "提示");
                return;
            }

            var billCorrectionOrderList = saveOrderList.Select(o => new BillCorrectionRequest()
            {
                OrderId = o.OrderId,
                NewDeliveryExpressFreight = o.NewDeliveryExpressFreight
            }).ToList();
            IsLoading = true;
            Task.Factory.StartNew(() => billCorrectionService.CorrectOrder(billCorrectionOrderList))
                        .ContinueWith(t =>
                        {
                            IsLoading = false;
                            var response = t.Result;
                            if (!response.Success)
                            {
                                App.Current.Dispatcher.Invoke(() => MessageBox.Show(response.Msg, "矫正费用 "));
                                return;
                            }

                            App.Current.Dispatcher.Invoke(() => MessageBox.Show("矫正账单成功", "矫正费用"));
                            this.Clear();
                        });

        }
    }
}