using BBWY.Client.APIServices;
using BBWY.Client.Extensions;
using BBWY.Client.Models;
using BBWY.Common.Models;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace BBWY.Client.ViewModels
{
    public class ProcurementAuditViewModel : BaseVM, IDenpendency
    {
        private AuditFile selectAuditFile;
        private bool isLoading;
        private bool isAudited;
        private bool isShowPayBillPanel;
        private bool isShowPurchaseOrderPanel;
        private bool isShowShopOrderPanel;
        private bool onlyException;
        private ShopService shopService;

        public IList<AuditFile> AuditFileList { get; set; }

        public IList<AuditPayBill> AuditPayBillList { get; set; }

        public IList<AuditPurchaseOrder> AuditPurchaseOrderList { get; set; }

        public IList<AuditShopOrder> AuditShopOrderList { get; set; }

        public IList<AuditPayBill> ShowAuditPayBillList { get; set; }

        public IList<AuditPurchaseOrder> ShowAuditPurchaseOrderList { get; set; }

        public IList<AuditShopOrder> ShowAuditShopOrderList { get; set; }

        public AuditFile SelectAuditFile
        {
            get => selectAuditFile; set
            {
                if (Set(ref selectAuditFile, value))
                    OnSelectAuditFileChanged();
            }
        }

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

        public bool IsShowPayBillPanel
        {
            get => isShowPayBillPanel; set
            {
                if (Set(ref isShowPayBillPanel, value))
                {
                    if (value)
                    {
                        IsShowPurchaseOrderPanel = false;
                        IsShowShopOrderPanel = false;
                    }
                }
            }
        }
        public bool IsShowPurchaseOrderPanel
        {
            get => isShowPurchaseOrderPanel; set
            {
                if (Set(ref isShowPurchaseOrderPanel, value))
                {
                    if (value)
                    {
                        IsShowPayBillPanel = false;
                        IsShowShopOrderPanel = false;
                    }
                }
            }
        }
        public bool IsShowShopOrderPanel
        {
            get => isShowShopOrderPanel; set
            {
                if (Set(ref isShowShopOrderPanel, value))
                {
                    if (value)
                    {
                        IsShowPayBillPanel = false;
                        IsShowPurchaseOrderPanel = false;
                    }
                }
            }
        }

        public bool OnlyException
        {
            get => onlyException; set
            {
                if (Set(ref onlyException, value))
                    OnOnlyExceptionChanged();
            }
        }

        public ICommand AuditCommand { get; set; }

        public ICommand ClearAuditCommand { get; set; }

        public ICommand ImportAliPayBillCommand { get; set; }

        public ICommand Import1688PurchaseOrderCommand { get; set; }

        public ICommand ImportJDShopOrderCommand { get; set; }

        public ProcurementAuditViewModel(ShopService shopService)
        {
            AuditFileList = new ObservableCollection<AuditFile>();
            AuditCommand = new RelayCommand(Audit);
            ClearAuditCommand = new RelayCommand(ClearAudit);
            ImportAliPayBillCommand = new RelayCommand(ImportAliPayBill);
            this.shopService = shopService;


            Import1688PurchaseOrderCommand = new RelayCommand(Import1688PurchaseOrder);


            ImportJDShopOrderCommand = new RelayCommand(ImportJDShopOrder);

            AuditFileList = new ObservableCollection<AuditFile>();
            AuditPayBillList = new List<AuditPayBill>();
            AuditPurchaseOrderList = new List<AuditPurchaseOrder>();
            AuditShopOrderList = new List<AuditShopOrder>();
            ShowAuditPayBillList = new ObservableCollection<AuditPayBill>();
            ShowAuditPurchaseOrderList = new ObservableCollection<AuditPurchaseOrder>();
            ShowAuditShopOrderList = new ObservableCollection<AuditShopOrder>();

            //AuditFileList.Add(new AuditFile() { FileName = "支付宝账单20220527.csv", AuditFileType = AuditFileType.账单 });
            //AuditFileList.Add(new AuditFile() { FileName = "1688采购单20220527.csv", AuditFileType = AuditFileType.采购单 });
            //AuditFileList.Add(new AuditFile() { FileName = "支付宝账单20220527.csv", AuditFileType = AuditFileType.销售订单 });

        }

        private void Audit()
        {
            if (IsLoading)
                return;
            if (AuditPayBillList.Count() == 0 ||
                AuditPurchaseOrderList.Count() == 0 ||
                AuditShopOrderList.Count() == 0)
            {
                MessageBox.Show("审核数据不全", "提示");
                return;
            }

            var waitList = new List<EventWaitHandle>()
            {
                new ManualResetEvent(false),
                new ManualResetEvent(false)
            };
            IsLoading = true;
            Task.Factory.StartNew(() =>
            {
                AuditByPayBill(waitList[0]);
                AuditByPurchaseOrder(waitList[1]);
            }).ContinueWith(t =>
            {
                WaitHandle.WaitAll(waitList.ToArray(), -1);
                IsLoading = false;
                IsAudited = true;

                App.Current.Dispatcher.BeginInvoke((Action)delegate
                {
                    SelectAuditFile = AuditFileList.FirstOrDefault(f => f.AuditFileType == AuditFileType.账单);
                });
            });

        }

        private void AuditByPayBill(EventWaitHandle ewh)
        {
            try
            {
                foreach (var payBill in AuditPayBillList)
                {
                    #region 匹配采购单
                    var relationPurchaseOrder = AuditPurchaseOrderList.FirstOrDefault(p => p.PurchaseOrderId == payBill.MerchantOrderNo);
                    if (relationPurchaseOrder == null)
                    {
                        //未通过商户订单号找到采购单,则通过账单金额和日期匹配
                        relationPurchaseOrder = AuditPurchaseOrderList.FirstOrDefault(p => p.PayAmount == payBill.ExpenditureAmount &&
                                                                                           p.PayTime != null && payBill.PayTime != null &&
                                                                                           Math.Abs((payBill.PayTime.Value - p.PayTime.Value).TotalSeconds) <= 60);
                    }
                    if (relationPurchaseOrder == null)
                    {
                        payBill.ErrorMessage = "未匹配采购单";
                        continue;
                    }
                    payBill.RelationPurchaseOrderId = relationPurchaseOrder.PurchaseOrderId;
                    #endregion

                    #region 匹配销售订单
                    var relationShopOrder = AuditShopOrderList.FirstOrDefault(o => (!string.IsNullOrEmpty(o.VenderRemark) && o.VenderRemark.Contains(relationPurchaseOrder.PurchaseOrderId)) ||
                                                                                   (o.Phone == relationPurchaseOrder.Phone &&
                                                                                    o.ContactName == relationPurchaseOrder.ContactName &&
                                                                                    o.PayTime != null && relationPurchaseOrder.PayTime != null &&
                                                                                   (relationPurchaseOrder.PayTime.Value - o.PayTime.Value).TotalDays <= 2));
                    if (relationShopOrder == null)
                    {
                        payBill.ErrorMessage = "未匹配销售订单";
                        continue;
                    }
                    payBill.RelationShopOrderId = relationShopOrder.OrderId;
                    #endregion
                }

                var relationShoporderIds = AuditPayBillList.Where(p => !string.IsNullOrEmpty(p.RelationShopOrderId)).Select(p => p.RelationShopOrderId).ToList();
                var belongResponse = shopService.GetOrderBelongShop(relationShoporderIds);
                if (!belongResponse.Success || belongResponse.Data.Count() == 0)
                    return;

                foreach (var payBill in AuditPayBillList)
                {
                    if (string.IsNullOrEmpty(payBill.RelationShopOrderId))
                        continue;
                    var belongShop = belongResponse.Data.FirstOrDefault(x => x.OrderIdList.Contains(payBill.RelationShopOrderId));
                    if (belongShop != null)
                        payBill.BelongShop = belongShop.ShopName;
                }
            }
            catch (Exception ex)
            {
                App.Current.Dispatcher.Invoke(() => MessageBox.Show(ex.Message, "账单匹配"));
            }
            finally
            {
                ewh.Set();
            }
        }

        private void AuditByPurchaseOrder(EventWaitHandle ewh)
        {
            try
            {
                foreach (var purchaseOrder in AuditPurchaseOrderList)
                {
                    #region 匹配账单
                    var relationPayBill = AuditPayBillList.FirstOrDefault(b => b.MerchantOrderNo == purchaseOrder.PurchaseOrderId);
                    if (relationPayBill == null)
                    {
                        //未通过商户订单号找到采购单,则通过账单金额和日期匹配
                        relationPayBill = AuditPayBillList.FirstOrDefault(b => purchaseOrder.PayAmount == b.ExpenditureAmount &&
                                                                               purchaseOrder.PayTime != null && b.PayTime != null &&
                                                                               Math.Abs((b.PayTime.Value - purchaseOrder.PayTime.Value).TotalSeconds) <= 60);
                    }
                    if (relationPayBill == null)
                    {
                        purchaseOrder.ErrorMessage = "未匹配支付账单";
                        continue;
                    }
                    purchaseOrder.RelationPayBillNo = relationPayBill.PayBillNo;
                    #endregion

                    #region 匹配销售单
                    var relationShopOrder = AuditShopOrderList.FirstOrDefault(o => (!string.IsNullOrEmpty(o.VenderRemark) && o.VenderRemark.Contains(purchaseOrder.PurchaseOrderId)) ||
                                                                                  (o.Phone == purchaseOrder.Phone &&
                                                                                   o.ContactName == purchaseOrder.ContactName &&
                                                                                   o.PayTime != null && purchaseOrder.PayTime != null &&
                                                                                  (purchaseOrder.PayTime.Value - o.PayTime.Value).TotalDays <= 2));
                    if (relationShopOrder == null)
                    {
                        purchaseOrder.ErrorMessage = "未匹配销售订单";
                        continue;
                    }
                    purchaseOrder.RelationShopOrderId = relationShopOrder.OrderId;
                    #endregion
                }

                var relationShopOrderIds = AuditPurchaseOrderList.Where(p => !string.IsNullOrEmpty(p.RelationShopOrderId)).Select(p => p.RelationShopOrderId).ToList();
                var belongResponse = shopService.GetOrderBelongShop(relationShopOrderIds);
                if (!belongResponse.Success || belongResponse.Data.Count() == 0)
                    return;
                foreach (var purchaseOrder in AuditPurchaseOrderList)
                {
                    if (string.IsNullOrEmpty(purchaseOrder.RelationShopOrderId))
                        continue;
                    var belongShop = belongResponse.Data.FirstOrDefault(x => x.OrderIdList.Contains(purchaseOrder.RelationShopOrderId));
                    if (belongShop != null)
                        purchaseOrder.BelongShop = belongShop.ShopName;
                }
            }
            catch (Exception ex)
            {
                App.Current.Dispatcher.Invoke(() => MessageBox.Show(ex.Message, "采购单匹配"));
            }
            finally
            {
                ewh.Set();
            }
        }

        private void ClearAudit()
        {
            SelectAuditFile = null;
            AuditFileList.Clear();
            AuditPayBillList.Clear();
            AuditPurchaseOrderList.Clear();
            AuditShopOrderList.Clear();
            ShowAuditPayBillList.Clear();
            ShowAuditPurchaseOrderList.Clear();
            ShowAuditShopOrderList.Clear();
            IsAudited = false;
            IsShowPayBillPanel = false;
            IsShowPurchaseOrderPanel = false;
            IsShowShopOrderPanel = false;
            OnlyException = false;
        }

        private (string ErrorMessage, string FileName, IList<string> Lines) ImportAuditFile(AuditFileType auditFileType)
        {
            var ofd = new OpenFileDialog() { Filter = "CSV Files (*.csv)|*.csv" };
            if (ofd.ShowDialog() != true)
                return (string.Empty, string.Empty, null);
            var fileName = ofd.FileName.Substring(ofd.FileName.LastIndexOf("\\") + 1);
            var filePath = ofd.FileName;
            if (AuditFileList.Any(f => f.FileName == fileName))
                return ("文件已存在", string.Empty, null);
            try
            {
                var lines = File.ReadAllLines(filePath, Encoding.GetEncoding("GB2312")).ToList();
                AuditFileList.Add(new AuditFile() { FileName = fileName, AuditFileType = auditFileType });
                return (string.Empty, fileName, lines);
            }
            catch (Exception ex)
            {
                return (ex.Message, string.Empty, null);
            }
        }

        /// <summary>
        /// 导入支付宝账单
        /// </summary>
        private void ImportAliPayBill()
        {
            var importResult = ImportAuditFile(AuditFileType.账单);
            if (!string.IsNullOrEmpty(importResult.ErrorMessage))
            {
                MessageBox.Show(importResult.ErrorMessage, "导入支付宝账单");
                return;
            }
            if (importResult.Lines == null || importResult.Lines.Count() == 0)
                return;
            //忽略前5行
            /*
            #支付宝账务明细查询											
            #账号:[20883422054731100156]											
            #起始日期:[2022年04月01日 00:00:00]   终止日期:[2022年05月01日 00:00:00]											
            #-----------------------------------------账务明细列表----------------------------------------											
            账务流水号	业务流水号	商户订单号	商品名称	发生时间	对方账号	收入金额(+元)	支出金额(-元)	账户余额(元)	交易渠道	业务类型	备注
            */
            for (var i = 0; i < 5; i++)
                importResult.Lines.RemoveAt(0);

            //忽略后4行
            /*
             #-----------------------------------------账务明细列表结束------------------------------------										
             #支出合计:681笔,共-39623.27元										
             #收入合计:85笔,共43889.26元										
             #导出时间:[2022年05月01日 10:13:45]			
             */
            for (var i = 0; i < 4; i++)
            {
                importResult.Lines.RemoveAt(importResult.Lines.Count() - 1);
            }

            var payBillNo = "";
            try
            {
                foreach (var line in importResult.Lines)
                {
                    var array = line.CSVstrToArry();
                    var sourceMerchantOrderNo = array[2].FormatString();
                    if (!string.IsNullOrEmpty(sourceMerchantOrderNo) && sourceMerchantOrderNo.StartsWith("XP"))
                        continue; //暂时不支持此类商户单号

                    var expenditureAmount = decimal.Parse(array[7].FormatString());
                    if (expenditureAmount == 0)  //支出为0的账单不参与审计
                        continue;
                    payBillNo = array[0].FormatString();
                    if (AuditPayBillList.Any(p => p.PayBillNo == payBillNo))
                        continue;
                    var payBill = new AuditPayBill()
                    {
                        BelongFileName = importResult.FileName,
                        PayBillNo = payBillNo,
                        PayBillType = PayBillType.AliPay,
                        SourceMerchantOrderNo = sourceMerchantOrderNo,
                        ProductName = array[3].FormatString(),
                        PayTime = DateTime.Parse(array[4].FormatString()),
                        OppositeAccount = array[5].FormatString(),
                        ExpenditureAmount = Math.Abs(expenditureAmount)
                    };
                    payBill.MerchantOrderNo = payBill.SourceMerchantOrderNo;
                    if (payBill.SourceMerchantOrderNo.StartsWith("T50060NP"))
                        payBill.MerchantOrderNo = payBill.SourceMerchantOrderNo.Substring(8);

                    AuditPayBillList.Add(payBill);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"问题账单号{payBillNo} {ex.Message}", "导入支付宝账单");
            }
        }

        /// <summary>
        /// 导入1688采购单
        /// </summary>
        private void Import1688PurchaseOrder()
        {
            var importResult = ImportAuditFile(AuditFileType.采购单);
            if (!string.IsNullOrEmpty(importResult.ErrorMessage))
            {
                MessageBox.Show(importResult.ErrorMessage, "导入1688采购单");
                return;
            }
            if (importResult.Lines == null || importResult.Lines.Count() == 0)
                return;

            //去掉列名
            importResult.Lines.RemoveAt(0);

            var purchaseOrderId = "";
            try
            {
                foreach (var line in importResult.Lines)
                {
                    var array = line.CSVstrToArry();
                    purchaseOrderId = array[0].FormatString();
                    if (string.IsNullOrEmpty(purchaseOrderId) || AuditPurchaseOrderList.Any(p => p.PurchaseOrderId == purchaseOrderId))
                        continue;
                    var purchaseOrder = new AuditPurchaseOrder()
                    {
                        PurchaseOrderId = purchaseOrderId,
                        Platform = Platform.阿里巴巴,
                        BelongFileName = importResult.FileName,
                        ProductAmount = decimal.Parse(array[5].FormatString()),
                        Freight = decimal.Parse(array[6].FormatString()),
                        PayAmount = decimal.Parse(array[8].FormatString()),
                        CreateTime = DateTime.Parse(array[10].FormatString()),
                        ContactName = array[13].FormatString(),
                        Address = array[14].FormatString(),
                        Phone = array[17].FormatString(),
                        Quantity = int.Parse(array[20].FormatString())
                    };
                    if (!string.IsNullOrEmpty(array[11]))
                        purchaseOrder.PayTime = DateTime.Parse(array[11].FormatString());
                    AuditPurchaseOrderList.Add(purchaseOrder);
                }
                Console.WriteLine(AuditPurchaseOrderList.Count());
            }
            catch (Exception ex)
            {
                MessageBox.Show($"问题采购单号{purchaseOrderId} {ex.Message}", "导入1688采购单");
            }

        }

        /// <summary>
        /// 导入京东销售订单
        /// </summary>
        private void ImportJDShopOrder()
        {
            var importResult = ImportAuditFile(AuditFileType.销售订单);
            if (!string.IsNullOrEmpty(importResult.ErrorMessage))
            {
                MessageBox.Show(importResult.ErrorMessage, "导入京东销售订单");
                return;
            }
            if (importResult.Lines == null || importResult.Lines.Count() == 0)
                return;

            //去掉列名
            importResult.Lines.RemoveAt(0);
            var orderId = "";
            try
            {
                foreach (var line in importResult.Lines)
                {
                    var array = line.CSVstrToArry();
                    orderId = array[0].FormatString();
                    if (string.IsNullOrEmpty(orderId) || AuditShopOrderList.Any(p => p.OrderId == orderId))
                        continue;
                    var order = new AuditShopOrder()
                    {
                        OrderId = orderId,
                        Platform = Platform.京东,
                        BelongFileName = importResult.FileName,
                        Quantity = int.Parse(array[3].FormatString()),
                        CreateTime = DateTime.Parse(array[5].FormatString()),
                        PayAmount = decimal.Parse(array[10].FormatString()),
                        ContactName = array[14].FormatString(),
                        Address = array[15].FormatString(),
                        Phone = array[16].FormatString(),
                        ProductName = array[2].FormatString(),
                        VenderRemark = array[27].FormatString()
                    };
                    AuditShopOrderList.Add(order);
                    if (!string.IsNullOrEmpty(array[30]))
                        order.PayTime = DateTime.Parse(array[30].FormatString());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"问题销售订单号{orderId} {ex.Message}", "导入京东销售订单");
            }
        }

        /// <summary>
        /// 采购审计文件对象改变事件
        /// </summary>
        private void OnSelectAuditFileChanged()
        {
            if (SelectAuditFile == null)
                return;
            if (SelectAuditFile.AuditFileType == AuditFileType.账单)
            {
                IsShowPayBillPanel = true;
                ShowAuditPayBillList.Clear();
                var where = AuditPayBillList.Where(b => b.BelongFileName == SelectAuditFile.FileName);
                if (OnlyException)
                    where = where.Where(b => !string.IsNullOrEmpty(b.ErrorMessage));
                var list = where.ToList();
                foreach (var b in list)
                    ShowAuditPayBillList.Add(b);
            }
            else if (SelectAuditFile.AuditFileType == AuditFileType.采购单)
            {
                IsShowPurchaseOrderPanel = true;
                ShowAuditPurchaseOrderList.Clear();
                var where = AuditPurchaseOrderList.Where(p => p.BelongFileName == SelectAuditFile.FileName);
                if (OnlyException)
                    where = where.Where(p => !string.IsNullOrEmpty(p.ErrorMessage));
                var list = where.ToList();
                foreach (var p in list)
                    ShowAuditPurchaseOrderList.Add(p);
            }
            else if (SelectAuditFile.AuditFileType == AuditFileType.销售订单)
            {

            }
        }

        private void OnOnlyExceptionChanged()
        {
            if (SelectAuditFile == null || AuditFileList.Count() == 0)
                return;
            var f = SelectAuditFile;
            SelectAuditFile = null;
            SelectAuditFile = f;
            //SelectAuditFile = AuditFileList.FirstOrDefault(f => f.AuditFileType == AuditFileType.账单);
        }
    }
}