package com.xxfc.platform.order.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.xxfc.platform.order.entity.DailyVehicleOrderStatistics;
import com.xxfc.platform.order.entity.OrderStatistics;
import com.xxfc.platform.order.mapper.DailyVehicleOrderStatisticsMapper;
import com.xxfc.platform.order.pojo.DedDetailDTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.*;

/**
 * 每日租车订单统计
 *
 * @author Administrator
 */
@Service
public class DailyVehicleOrderStatisticsBiz extends BaseBiz<DailyVehicleOrderStatisticsMapper, DailyVehicleOrderStatistics> {

    private final Integer TYPE_DEFERRED = 1;
    private final Integer TYPE_DAMAGE = 2;
    private final Integer TYPE_OTHER = 3;

    @Value("${order.day}")
    private Integer day;

    @Transactional(rollbackFor = Exception.class)
    public boolean StatisticsOfCarRentalOrders() {

        try {

            ArrayList<DailyVehicleOrderStatistics> result = new ArrayList<>();

//        获取每日租车订单成交金和押金总额
            List<DailyVehicleOrderStatistics> gmvAndMarginTotal = mapper.getGmvAndMarginTotal(day);
            result.addAll(gmvAndMarginTotal);

//        获取取消订单扣款总额
            List<DailyVehicleOrderStatistics> penalSum = mapper.getPenalSum(day);
            result.addAll(penalSum);

//        获取订单退还押金总额
            List<DailyVehicleOrderStatistics> refundSecurityDeposit = mapper.getRefundSecurityDeposit(day);
            result.addAll(refundSecurityDeposit);

//        获取违章查询总和
            List<DailyVehicleOrderStatistics> violationMoney = mapper.getViolationMoney(day);
            result.addAll(violationMoney);

//        获取赔偿和延期JSON字符串
            List<Map> compensationAndPostpone = mapper.getCompensationAndPostpone(day);
//        获取赔偿和延期JSON字符串转换为map
            List<DailyVehicleOrderStatistics> compensationAndPostpones = getCompensationAndPostpones(compensationAndPostpone);
            result.addAll(compensationAndPostpones);

            InsertByList(result);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }

    }

    private void InsertByList(ArrayList<DailyVehicleOrderStatistics> result) throws Exception {

        if(CollectionUtils.isNotEmpty(result)) {
            Map<Integer, DailyVehicleOrderStatistics> map = new HashMap<>();

            for (DailyVehicleOrderStatistics value : result) {
                Integer branchCompanyId = value.getBranchCompanyId();
                DailyVehicleOrderStatistics statistics = map.get(branchCompanyId);

                if (statistics == null) {
                    statistics = new DailyVehicleOrderStatistics();
                    map.put(branchCompanyId, statistics);
                }
                BeanUtil.copyProperties(
                        value,
                        statistics,
                        CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));

            }

            for (Map.Entry<Integer, DailyVehicleOrderStatistics> entry : map.entrySet()) {
                insertSelectiveRe(entry.getValue());
            }
        }

    }


    /**
     * 获取赔偿总额和延期总额
     */
    private List<DailyVehicleOrderStatistics> getCompensationAndPostpones(List<Map> list) {

        if (CollectionUtils.isNotEmpty(list)) {
            //获取分公全部赔偿和延期DedDetailDTO
            HashMap<Integer, List<DedDetailDTO>> map = new HashMap<>();

            for (Map value : list) {
                if (value != null) {

                    //获取分公司id
                    Integer branchCompanyId = (Integer) value.get("branchCompanyId");
                    List<DedDetailDTO> strings = map.get(branchCompanyId);
                    if (strings == null) {
                        strings = new ArrayList<DedDetailDTO>();
                        map.put(branchCompanyId, strings);
                    }

                    String str = (String) value.get("dedDetail");

                    if (StringUtils.isNotBlank(str)) {
                        List<DedDetailDTO> dedDetailDTOS = JSON.parseArray(str, DedDetailDTO.class);
                        if (CollectionUtils.isNotEmpty(dedDetailDTOS)) {
                            strings.addAll(dedDetailDTOS);
                        }
                    }
                }

            }


            List<DailyVehicleOrderStatistics> result = new ArrayList<>();

            if (!map.isEmpty()) {

                //获取分工对象集合
                for (Map.Entry<Integer, List<DedDetailDTO>> entry : map.entrySet()) {
                    DailyVehicleOrderStatistics statistics = new DailyVehicleOrderStatistics();
                    //公司id添加到对象当中
                    statistics.setBranchCompanyId(entry.getKey());

                    //获取公司的JSON字符串
                    List<DedDetailDTO> sumDedDetailDTOs = entry.getValue();

//            获取赔偿金额总和
                    BigDecimal compensation = get(sumDedDetailDTOs, TYPE_DAMAGE);
                    statistics.setCompensation(compensation);
//            获取延期金额总和
                    BigDecimal postpone = get(sumDedDetailDTOs, TYPE_DEFERRED);
                    statistics.setPostpone(postpone);
////            其他款项总金额
//                    BigDecimal other = get(sumDedDetailDTOs, TYPE_OTHER);

                    result.add(statistics);
                }

            }


            return result;
        }
        return new ArrayList<>();
    }


    /**
     * 根据type获取对应的金额总和
     *
     * @param sumDedDetailDTOs
     * @param type             金额类型
     * @return
     */
    private BigDecimal get(List<DedDetailDTO> sumDedDetailDTOs, Integer type) {
        if (CollectionUtils.isNotEmpty(sumDedDetailDTOs)) {
            BigDecimal aggregateAmount = sumDedDetailDTOs.stream()
                    .filter(d -> type.equals(d.getType()))
                    .map(DedDetailDTO::getCost)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            return aggregateAmount;
        }
        return BigDecimal.ZERO;
    }


    @Override
    public int insertSelectiveRe(DailyVehicleOrderStatistics entity) {
        entity.setCrtTime(new Date());
        return mapper.insertSelective(entity);
    }

    public OrderStatistics findAll(Integer companyId) {
        return mapper.monthOrderTotal(companyId);
    }
}
