using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Linq;
using System.Threading.Tasks;
using XYY.Core.Standard.ExcelHelper;
using XYY.Data.Standard.Finance;
using XYY.Model.Standard;
using XYY.Model.Standard.Finance;

namespace XYY.Service.Standard.Finance
{
    public interface ICustomerLadingBillCostService
    {
        Task<byte[]> DownloadLadingBillCost(CustomerLadingBillSearchParam param);
        Task<byte[]> DownloadLadingBillDetailCost(string billNumber);
    }

    public class CustomerLadingBillCostService : ICustomerLadingBillCostService
    {
        private IVCustomerLadingBillCostRepository _costRepository;
        private IView_Finance_Logistics_LadingBill_DetailRepository _detailRepository;

        private IUser_BusinessDivisionRepository _businessDivisionRepository;
        public CustomerLadingBillCostService(IVCustomerLadingBillCostRepository costRepository,
            IView_Finance_Logistics_LadingBill_DetailRepository detailRepository,
            IUser_BusinessDivisionRepository businessDivisionRepository)
        {
            _costRepository = costRepository;
            _detailRepository = detailRepository;
            _businessDivisionRepository = businessDivisionRepository;
        }

        public async Task<byte[]> DownloadLadingBillDetailCost(string billNumber)
        {
            var list = (await _detailRepository.QueryAsync(x => x.LadingBillNumber == billNumber)).ToList();
            IWorkbook wk = new XSSFWorkbook();
            ISheet sheet = wk.CreateSheet("提单信息");

            OPNPOIRow<View_Finance_Logistics_LadingBill_Detail> row = new OPNPOIRow<View_Finance_Logistics_LadingBill_Detail>(new View_Finance_Logistics_LadingBill_Detail(), sheet.CreateRow(0));
            row.CellWithName(x => x.DepartTime, "时间")
            .CellWithName(x => x.LadingBillNumber, "提单号")
            .CellWithName(x => x.ServiceName, "服务商")
            .CellWithName(x => x.PublicName, "渠道")
            .CellWithName(x => x.SystemNo, "订单号")
            .CellWithName(x => x.TrackingNumber, "跟踪号")
            .CellWithName(x => x._Destination, "始发地")
            .CellWithName(x => x.Departure, "目的港")
            .CellWithName(x => x.OPWeight, "称重重量")
            .CellWithName(x => x.OPCFreight, "预计收入")
            .CellWithName(x => x.SumCost, "预计总成本")
            .CellWithName(x => x.FristFee, "空运成本")
            .CellWithName(x => x.ClareFee, "清关成本")
            .CellWithName(x => x.OPSFreight, "派送成本")
            .CellWithName(x => x.Profit, "预计毛利")
            .CellWithName(x => x.ProfitRate, "预计毛利率");

            for (int j = 0; j < list.Count; j++)
            {
                var item = list[j];
                row.Serialize(item, sheet.CreateRow(j + 1));
            }

            var content = row.WBToByte(wk);
            return content;
        }

        public async Task<byte[]> DownloadLadingBillCost(CustomerLadingBillSearchParam param)
        {
            if (param?.LaddingBills == null || param.LaddingBills.Length == 0)
                throw new Exception("提单参数不能为空");

            var list = await _costRepository.QueryLadingBillCosts(param.LaddingBills.ToList());

            IWorkbook wk = new XSSFWorkbook();
            ISheet sheet = wk.CreateSheet("提单信息");

            OPNPOIRow<LadingBillFinanceDto> row = new OPNPOIRow<LadingBillFinanceDto>(new LadingBillFinanceDto(), sheet.CreateRow(0));
            row.CellWithName(x => x.LadingBillNumber, "提单号")
            .CellWithName(x => x.OrderQty, "订单数")
            .CellWithName(x => x.TotalWeight, "净重总和")
            .CellWithName(x => x.SettlementCompanyName, "所属")
            .CellWithName(x => x.CustomerCompany, "客户名")
            .CellWithName(x => x.CWFee, "均摊成本（重量）")
            .CellWithName(x => x.CQFee, "均摊成本（订单）")
            .CellWithName(x => x.WeighRatePercent, "均摊占比（重量）%")
            .CellWithName(x => x.QtyRagePercent, "均摊占比（订单）%")
            .CellWithName(x => x.BillTime, "帐单日期");

            var bulids = await _businessDivisionRepository.QueryAsync();

            var type = param.Type;
            for (int j = 0; j < list.Count; j++)
            {
                var item = list[j];
                var billTime = GetBillTime(param.Type, item);
                LadingBillFinanceDto dto = new LadingBillFinanceDto
                {
                    LadingBillNumber = item.BillNumber,
                    BillTime = billTime,
                    CQFee = GetCQFee(param.Type, item),
                    CWFee = GetCWFee(param.Type, item),
                    CustomerCompany = item.CompanyName,
                    OrderQty = item.CusetomerQty,
                    QtyRage = item.qtyRage,
                    SettlementCompanyName = bulids.Where(y => y.Id == item.SettlementCompany).FirstOrDefault()?.Name,
                    TotalWeight = item.CustomerWeight,
                    WeighRate = item.weighRate
                };
                row.Serialize(dto, sheet.CreateRow(j + 1));
            }

            var content = row.WBToByte(wk);
            return content;
        }

        private DateTime? GetBillTime(FinanceIncidentalTypeEnum type, View_Customer_LadingBill_Cost item)
        {
            switch (type)
            {
                case FinanceIncidentalTypeEnum.头程杂费: return item.FristBillTime;
                case FinanceIncidentalTypeEnum.国内清关杂费: return item.DomesticClearBillTime;
                case FinanceIncidentalTypeEnum.国外清关杂费: return item.OverseasClearBillTime;
                default: return null;
            }
        }

        private decimal GetCQFee(FinanceIncidentalTypeEnum type, View_Customer_LadingBill_Cost item)
        {
            switch (type)
            {
                case FinanceIncidentalTypeEnum.头程杂费: return item.CQFristFee;
                case FinanceIncidentalTypeEnum.国内清关杂费: return item.CQDomesticClearFee;
                case FinanceIncidentalTypeEnum.国外清关杂费: return item.CQOverseasClearFee;
                default: return 0;
            }
        }

        private decimal GetCWFee(FinanceIncidentalTypeEnum type, View_Customer_LadingBill_Cost item)
        {
            switch (type)
            {
                case FinanceIncidentalTypeEnum.头程杂费: return item.CWFristFee;
                case FinanceIncidentalTypeEnum.国内清关杂费: return item.CWDomesticClearFee;
                case FinanceIncidentalTypeEnum.国外清关杂费: return item.CWOverseasClearFee;
                default: return 0;
            }
        }
    }

    public class CustomerLadingBillSearchParam
    {
        public FinanceIncidentalTypeEnum Type
        {
            get; set;
        }

        public string[] LaddingBills
        {
            get; set;
        }
    }

    public class LadingBillFinanceDto
    {
        public string LadingBillNumber { get; set; }
        public int OrderQty { get; set; }
        public decimal TotalWeight { get; set; }

        public SettlementCompany SettlementCompany
        {
            get; set;
        }

        public string SettlementCompanyName
        {
            get; set;
        }
        public string CustomerCompany { get; set; }
        public decimal CWFee { get; set; }
        public decimal CQFee { get; set; }
        public decimal WeighRate
        {
            get; set;
        }
        public string WeighRatePercent
        {
            get
            {
                return (WeighRate * 100).ToString("F2");
            }
        }

        public decimal QtyRage
        {
            get; set;
        }
        public string QtyRagePercent
        {
            get
            {
                return (QtyRage * 100).ToString("F2");
            }
        }
        public DateTime? BillTime { get; set; }
    }
}
