package com.ag.account.detail.impl;

import cn.hutool.core.util.ObjectUtil;
import com.ag.account.detail.AccountDetail;
import com.ag.account.feeUtil.BulkTonUtil;
import com.ag.account.feeUtil.MultiStepUtil;
import com.ag.account.feeUtil.ReductionUtil;
import com.ag.entity.account.FeeDetail;
import com.ag.entity.account.vo.BizVO;
import com.ag.entity.fee.ContractItem;
import com.ag.entity.fee.face.ICondition;
import com.ag.entity.fee.face.SourceProperty;
import com.ag.util.StrUtil;
import com.ag.util.TimeUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 计费吨*天
 */
public class BulkStoreDetail extends AccountDetail {

    /**
     * 计价单位=计费吨，子类获取数量属性的方法重写
     * @param property
     * @param contractItem
     * @return
     */
    protected Double getQuantity(JSONObject property, ContractItem contractItem){
        Assert.notNull(property.get(ICondition.weight), "重量不允许为空");
        Double ton = BulkTonUtil.calcTon(property, contractItem);
        return BulkTonUtil.roundTon(ton, contractItem);
    }

    /**
     * 重写优惠减免
     */
    @Override
    protected void calcByDiscount(BizVO bizVO, SourceProperty source, FeeDetail detail) {
        ReductionUtil.calcByDerateDay(source, detail);//减免天后的金额
        //ReductionUtil.calcByDiscount(source.getProperty(), detail);//优惠金额和折扣
    }

    @Override
    protected void calcBefore(BizVO bizVO, SourceProperty source){
        JSONObject popMap = source.getProperty();
        if (!StrUtil.isEmpty(ICondition.TIME_ON)) {
            bizVO.setStartDate(TimeUtil.getTimestamp(popMap.getString(ICondition.TIME_ON)));
        }
        if (!StrUtil.isEmpty(ICondition.TIME_END)) {
            bizVO.setEndDate(TimeUtil.getTimestamp(popMap.getString(ICondition.TIME_END)));
        }
    }

    /**
     * 重写结算天
     */
    @Override
    protected Integer getSettleDays(BizVO bizVO){
        return TimeUtil.compareDaysLimit(bizVO.getStartDate(), bizVO.getEndDate(), true) + 1;
    }

    /**
     * 按吨*天计费
     */
    @Override
    protected void calcByUnit(BizVO bizVO, SourceProperty source, FeeDetail detail){
        detail.setSettleTimeOn(bizVO.getStartDate());
        detail.setSettleTimeEnd(bizVO.getEndDate());
        detail.setCalcDays(detail.getSettleDays());//计费天
        ContractItem contractItem = source.getContractItem();
        //是否按阶梯生成费率明细 !=2 合计金额（单条明细），
        if (!ObjectUtil.equal(contractItem.getByagent(), 2)) {
            MultiStepUtil.calcAmount(source.getTariffVO(), detail);//计算堆存金额
            detail.setStMoney(detail.getCalcMoney());//标准金额
            detail.setFinalMoney(detail.getCalcMoney());//最终金额
            return;
        }
        //是否按阶梯生成费率明细 =2 阶梯金额（多条明细）
        List<FeeDetail> feeDetails = MultiStepUtil.calcAmountForList(source.getTariffVO(), detail);
        /**
         * 根据入场时间 -- 最近结算日期，计算已结算金额。
         */
        JSONObject popMap = source.getProperty();
        if (!StrUtil.isEmpty(popMap.getString(ICondition.LAST_ACCOUNT_ON))) {
            Date lastAccountOn = TimeUtil.getTimestamp(popMap.getString(ICondition.LAST_ACCOUNT_ON));
            bizVO.setEndDate(lastAccountOn);
            //入场时间 》= 最后结算日期，不需要计算已结算金额。
            if (getSettleDays(bizVO) <= 1){
                bizVO.setEndDate(TimeUtil.getTimestamp(popMap.getString(ICondition.TIME_END)));
            } else {
                detail.setSettleTimeEnd(lastAccountOn);
                detail.setSettleDays(getSettleDays(bizVO));//已结算计费天
                detail.setCalcDays(detail.getSettleDays());//已结算计费天
                List<FeeDetail> accountDetails = MultiStepUtil.calcAmountForList(source.getTariffVO(), detail);
                for (FeeDetail account : accountDetails) {
                    account.setCalcMoney(-account.getCalcMoney());
                    account.setCalcDays(-account.getCalcDays());
                }
                for (FeeDetail target : feeDetails){
                    for (FeeDetail accountDetail : accountDetails){
                        if (Objects.equals(target.getActualRate(), accountDetail.getActualRate())){
                            target.setCalcMoney(target.getCalcMoney() + accountDetail.getCalcMoney());
                            target.setCalcDays(target.getCalcDays() + accountDetail.getCalcDays());
                            break;
                        }
                    }
                }
            }
        }
        bizVO.getDetails().remove(detail);
        bizVO.getDetails().addAll(feeDetails);
        for (FeeDetail detail1 : feeDetails){
            detail1.setStMoney(detail1.getCalcMoney());//标准金额
            detail1.setFinalMoney(detail1.getCalcMoney());//最终金额
        }
    }

}
