package com.iformall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.domain.dto.MarkingCouponDataReportDto;
import com.iformall.domain.dto.WxOrderReportDto;
import com.iformall.domain.po.WxCoupon;
import com.iformall.domain.po.WxCouponOrder;
import com.iformall.domain.vo.*;
import com.iformall.enums.EnumCarCmd;
import com.iformall.enums.EnumCouponSendSendType;
import com.iformall.enums.EnumCouponType;
import com.iformall.enums.EnumOrderType;
import com.iformall.mapper.*;
import com.iformall.service.ExcelService;
import com.iformall.service.MarkingDataReportService;
import com.iformall.utils.DateUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by syf on 2018/8/28.
 */
@Service
public class MarkingDataReportServiceImpl implements MarkingDataReportService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxCouponOrderMapper wxCouponOrderMapper;
    @Autowired
    private WxCouponActionLogMapper wxCouponActionLogMapper;
    @Autowired
    private WxCarCmdLogMapper wxCarCmdLogMapper;
    @Autowired
    private WxUserVisitMapper wxUserVisitMapper;
    @Autowired
    private WxCouponMapper wxCouponMapper;
    @Autowired
    private WxOrderMapper wxOrderMapper;
    @Autowired
    private ExcelService excelService;

    private Date addDay(int addDayAmount) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, addDayAmount);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        Date date = c.getTime();
        return date;
    }


    private Date convertDateAndAdd(Date date, int addDayAmount) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, addDayAmount);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        Date result = c.getTime();
        return result;
    }

    //取的当月券数据
    @Override
    public Map<String, Object> getCouponData(String tenantId) {
        //今日领取券数
        //查询coupon order表
        WxCouponOrder wxCouponOrder = new WxCouponOrder();
        wxCouponOrder.setTenantId(tenantId);
        wxCouponOrder.setStartTime(addDay(0));
        wxCouponOrder.setEndTime(addDay(1));
        int todayCouponCount = wxCouponOrderMapper.findCount(wxCouponOrder);
        wxCouponOrder.setStartTime(addDay(-1));
        wxCouponOrder.setEndTime(addDay(0));
        int yesterdayCount = wxCouponOrderMapper.findCount(wxCouponOrder);
        wxCouponOrder.setStartTime(addDay(-7));
        wxCouponOrder.setEndTime(addDay(-6));
        int lastWeekCount = wxCouponOrderMapper.findCount(wxCouponOrder);

        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(2);//控制保留小数点后几位，2：表示保留2位小数点
        String couponUpDay = "--";
        if (yesterdayCount != 0) {
            couponUpDay = nf.format((todayCouponCount - yesterdayCount) / (float) yesterdayCount);
        }
        String couponUpWeek = "--";
        if (lastWeekCount != 0) {
            couponUpWeek = nf.format((todayCouponCount - lastWeekCount) / (float) lastWeekCount);
        }

        //couponData
        HashMap<String, Object> params = new HashMap<>();
        params.put("tenantId", tenantId);
        params.put("startTime", addDay(-30));
        params.put("endTime", addDay(1));
        List<MarkingCouponDataReportVo> couponDatalist = wxCouponOrderMapper.couponDataMap(params);
        //查询券领取人数

        String startdate = DateUtils.getTimeBefore(30, new Date());
        String enddate = DateUtils.getTimeBefore(1,new Date());
        List<String> tjTimeList = DateUtils.getTjTimeList(startdate, enddate, "0");
        List<String> tjList = tjTimeList.stream().map(d -> d.substring(5).replace("-", "/")).collect(Collectors.toList());
        List<MarkingCouponDataReportVo> couponTempDatalist =new LinkedList<>();

        for(String tj:tjList){
            Optional<MarkingCouponDataReportVo> first = couponDatalist.stream().filter(c -> c.getCreateTime().equals(tj)).findFirst();
            if(!first.isPresent()){
                MarkingCouponDataReportVo markingCouponDataReportVo = new MarkingCouponDataReportVo();
                markingCouponDataReportVo.setCreateTime(tj);
                markingCouponDataReportVo.setCouponCount(0);
                markingCouponDataReportVo.setCouponUserCount(0);
                markingCouponDataReportVo.setVerifyCount(0);
                markingCouponDataReportVo.setVerifyUserCount(0);
                couponTempDatalist.add(markingCouponDataReportVo);
                continue;
            }
            couponTempDatalist.add(first.get());
        }


        HashMap<String, Object> returnMap = new HashMap<>();
        returnMap.put("couponUpDay", couponUpDay);//比昨日提升
        returnMap.put("couponUpWeek", couponUpWeek);//比上周提升
        returnMap.put("todayCouponCount", todayCouponCount);//今日领取数
        returnMap.put("couponDataMap", couponTempDatalist);
        return returnMap;
    }


    @Override
    public Map<String, Object> getSceneData(String tenantId) {
        //今日营销投放券数
        int todaySceneCount = wxCouponActionLogMapper.getCountByDateLimit(tenantId, addDay(0), addDay(1));
        int yesterdayCount = wxCouponActionLogMapper.getCountByDateLimit(tenantId, addDay(-1), addDay(0));
        int lastWeekCount = wxCouponActionLogMapper.getCountByDateLimit(tenantId, addDay(-7), addDay(-6));

        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(2);//控制保留小数点后几位，2：表示保留2位小数点
        String sceneDownDay = "--";
        if (yesterdayCount != 0) {
            sceneDownDay = nf.format((yesterdayCount - todaySceneCount) / (float) yesterdayCount);
        }
        String sceneUpWeek = "--";
        if (lastWeekCount != 0) {
            sceneUpWeek = nf.format((todaySceneCount - lastWeekCount) / (float) lastWeekCount);
        }

        HashMap<String, Object> params = new HashMap<>();
        params.put("tenantId", tenantId);
        params.put("startTime", addDay(-30));
        params.put("endTime", addDay(1));
        //停车发券数 停车发券被核销数  核销发券数 核销发券被核销数
        wxCouponActionLogMapper.updateCreateTimeMd(params);
        List<MarkingSceneDataReportTVo> sceneList = wxCouponActionLogMapper.getSceneDataMap(params);

        //停车发券被核销数
        HashMap<String, Object> params1 = new HashMap<>();
        params1.put("tenantId", tenantId);
        params1.put("startTime", addDay(-30));
        params1.put("endTime", addDay(1));
        params1.put("channelType", EnumCouponSendSendType.CAR_STOP.getCode());//停车
        List<MarkingSceneDataReportVo> list1 = wxCouponActionLogMapper.sceneDataMapJoinCouponOrder(params1);
        Map<String, Integer> parkCountMap = list1.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));

        //核销发券被核销数
        HashMap<String, Object> params2 = new HashMap<>();
        params2.put("tenantId", tenantId);
        params2.put("startTime", addDay(-30));
        params2.put("endTime", addDay(1));
        params2.put("channelType", EnumCouponSendSendType.COUPON_VERIFY.getCode());//核销
        List<MarkingSceneDataReportVo> list2 = wxCouponActionLogMapper.sceneDataMapJoinCouponOrder(params2);
        Map<String, Integer> verifyCountMap = list2.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));

        // B端刷卡支付被核销数
        HashMap<String, Object> params3 = new HashMap<>();
        params3.put("tenantId", tenantId);
        params3.put("startTime", addDay(-30));
        params3.put("endTime", addDay(1));
        params3.put("channelType", EnumCouponSendSendType.B_MICROPAY.getCode());//B端刷卡支付
        List<MarkingSceneDataReportVo> list3 = wxCouponActionLogMapper.sceneDataMapJoinCouponOrder(params3);
        Map<String, Integer> microPayCountMap = list3.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));

        // 购买发券被核销数
        HashMap<String, Object> params4 = new HashMap<>();
        params4.put("tenantId", tenantId);
        params4.put("startTime", addDay(-30));
        params4.put("endTime", addDay(1));
        params4.put("channelType", EnumCouponSendSendType.C_ORDER.getCode());//买券
        List<MarkingSceneDataReportVo> list4 = wxCouponActionLogMapper.sceneDataMapJoinCouponOrder(params4);
        Map<String, Integer> OrderCountMap = list4.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));

        String startdate = DateUtils.getTimeBefore(30, new Date());
        String enddate = DateUtils.getTimeBefore(1,new Date());
        List<String> tjTimeList = DateUtils.getTjTimeList(startdate, enddate, "0");
        List<String> tjList = tjTimeList.stream().map(d -> d.substring(5).replace("-", "/")).collect(Collectors.toList());
        List<MarkingSceneDataReportVo> tempDatalist =new LinkedList<>();

        for(String tj:tjList){
            MarkingSceneDataReportVo msdVo = new MarkingSceneDataReportVo();
            msdVo.setXTime(tj);
            Optional<MarkingSceneDataReportTVo> carStop = sceneList.stream().filter(c -> c.getXTime().equals(tj) && c.getChannelType() == EnumCouponSendSendType.CAR_STOP.getCode()).findFirst();
            if (!carStop.isPresent()) {
                msdVo.setParkSendCount(0);
            } else {
                MarkingSceneDataReportTVo tvo = carStop.get();
                msdVo.setParkSendCount(tvo.getCount());
            }
            Optional<MarkingSceneDataReportTVo> couponVerify = sceneList.stream().filter(c -> c.getXTime().equals(tj) && c.getChannelType() == EnumCouponSendSendType.COUPON_VERIFY.getCode()).findFirst();
            if(!couponVerify.isPresent()) {
                msdVo.setVerifySendCount(0);
            } else {
                MarkingSceneDataReportTVo  tvo = couponVerify.get();
                msdVo.setVerifySendCount(tvo.getCount());
            }

            Optional<MarkingSceneDataReportTVo> microPay = sceneList.stream().filter(c -> c.getXTime().equals(tj) && c.getChannelType() == EnumCouponSendSendType.B_MICROPAY.getCode()).findFirst();
            if(!microPay.isPresent()) {
                msdVo.setMicroPaySendCount(0);
            } else {
                MarkingSceneDataReportTVo  tvo = microPay.get();
                msdVo.setMicroPaySendCount(tvo.getCount());
            }

            Optional<MarkingSceneDataReportTVo> orderSend = sceneList.stream().filter(c -> c.getXTime().equals(tj) && c.getChannelType() == EnumCouponSendSendType.C_ORDER.getCode()).findFirst();
            if(!orderSend.isPresent()) {
                msdVo.setOrderSendCount(0);
            } else {
                MarkingSceneDataReportTVo  tvo = orderSend.get();
                msdVo.setOrderSendCount(tvo.getCount());
            }

            msdVo.setTotal(msdVo.getParkSendCount() +
                    msdVo.getVerifySendCount() +
                    msdVo.getMicroPaySendCount() +
                    msdVo.getOrderSendCount());

            tempDatalist.add(msdVo);
        }


        HashMap<String, Object> returnMap = new HashMap<>();
        returnMap.put("sceneDownDay", sceneDownDay);//比昨日下降
        returnMap.put("sceneUpWeek", sceneUpWeek);//比上周提升
        returnMap.put("todaySceneCount", todaySceneCount);//今日领取数
        returnMap.put("sceneDataMap", tempDatalist);
        return returnMap;
    }

    @Override
    public PageInfo<MarkingCouponDataReportVo> getCouponDataList(String tenantId, MarkingCouponDataReportDto markingCouponDataReportDto, Integer pageIndex, Integer pageSize) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("tenantId", tenantId);
        if (markingCouponDataReportDto.getStartTime() != null)
            params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(), 0));
        if (markingCouponDataReportDto.getEndTime() != null)
            params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
        if(markingCouponDataReportDto.getCouponType()!=null){
            params.put("couponType", markingCouponDataReportDto.getCouponType());
        }
        if(StringUtils.isNotBlank(markingCouponDataReportDto.getCouponTitle())){
            params.put("couponTitle", markingCouponDataReportDto.getCouponTitle());
        }

        PageHelper.startPage(pageIndex, pageSize);
        List<MarkingCouponDataReportVo> couponDatalist = wxCouponOrderMapper.couponDataList(params);
        if(couponDatalist.isEmpty()){
            return new PageInfo<>(couponDatalist);
        }
        List<Long> couponIds = couponDatalist.stream().map(p->p.getCouponId()).distinct().collect(Collectors.toList());
        WxCoupon wxCoupon = new WxCoupon();
        wxCoupon.setTenantId(tenantId);
        wxCoupon.setIds(couponIds);
        List<WxCoupon> wxCoupons = wxCouponMapper.findList(wxCoupon);
        Map<Long,WxCoupon> map = wxCoupons.stream().collect(Collectors.toMap(WxCoupon::getId, p -> p));
        for (MarkingCouponDataReportVo temp:couponDatalist) {
            if(map.get(temp.getCouponId())!=null){
                temp.setTitle(map.get(temp.getCouponId()).getTitle());
                String typeName = EnumCouponType.getEnum(map.get(temp.getCouponId()).getType()).getMessage();
                temp.setType(typeName);
            }
        }

        return new PageInfo<>(couponDatalist);
    }

    @Override
    public PageInfo<MarkingSceneDataVo> getSceneDataList(String tenantId, MarkingCouponDataReportDto markingCouponDataReportDto, Integer pageIndex, Integer pageSize) {
        MarkingCouponDataReportDto queryDto = new MarkingCouponDataReportDto();
        org.springframework.beans.BeanUtils.copyProperties(markingCouponDataReportDto, queryDto);
        queryDto.setTenantId(tenantId);

        HashMap<String, Object> params = new HashMap<>();
        params.put("tenantId", tenantId);

        if (markingCouponDataReportDto.getStartTime() != null) {
            params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(), 0));
            queryDto.setStartTime(convertDateAndAdd(markingCouponDataReportDto.getStartTime(), 0));
        }
        if (markingCouponDataReportDto.getEndTime() != null) {
            params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            queryDto.setEndTime(convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
        }

        //TODO 商户发券数据，下个版本需求
        if(Objects.equals(markingCouponDataReportDto.getType(),EnumCouponSendSendType.MERCHANT.getCode())) {
            markingCouponDataReportDto.setType(null);
        }
        //停车发券数 停车发券被核销数,  核销发券数 核销发券被核销数, B端刷卡支付发券数 刷卡支付发券被核销数
        PageHelper.startPage(pageIndex, pageSize);
        List<MarkingSceneDataVo> list;

        if(markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.CAR_STOP.getCode())) {
            queryDto.setChannelType(EnumCouponSendSendType.CAR_STOP.getCode());
            list = wxCouponActionLogMapper.sceneDataList(queryDto);
        }else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.B_MICROPAY.getCode())) {
            queryDto.setChannelType(EnumCouponSendSendType.B_MICROPAY.getCode());
            list = wxCouponActionLogMapper.sceneDataList(queryDto);
        }else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.COUPON_VERIFY.getCode())){
            queryDto.setChannelType(EnumCouponSendSendType.COUPON_VERIFY.getCode());
            list = wxCouponActionLogMapper.sceneDataList(queryDto);
        }else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.C_ORDER.getCode())){
            queryDto.setChannelType(EnumCouponSendSendType.C_ORDER.getCode());
            list = wxCouponActionLogMapper.sceneDataList(queryDto);
        }else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.MERCHANT.getCode())){
            queryDto.setChannelType(markingCouponDataReportDto.getType());
            list = wxCouponActionLogMapper.sceneDataList(queryDto);
        }else{
            PageHelper.clearPage();
            list = new ArrayList<>();
        }

        Map<String, Integer> countMap = new HashMap<>();

        if(markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.CAR_STOP.getCode())){ //停车
            //停车发券被核销数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            params.put("channelType", EnumCouponSendSendType.CAR_STOP.getCode());
            List<MarkingSceneDataReportVo> list1 = wxCouponActionLogMapper.sceneDataJoinCouponOrderList(params);
            countMap = list1.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));
        } else if(markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.B_MICROPAY.getCode())){ // B端刷卡支付
            //B端刷卡发券 被核销数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            params.put("channelType", EnumCouponSendSendType.B_MICROPAY.getCode());
            List<MarkingSceneDataReportVo> list2 = wxCouponActionLogMapper.sceneDataJoinCouponOrderList(params);
            countMap = list2.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));
        } else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.COUPON_VERIFY.getCode())){
            //核销发券被核销数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            params.put("channelType", EnumCouponSendSendType.COUPON_VERIFY.getCode());
            List<MarkingSceneDataReportVo> list3 = wxCouponActionLogMapper.sceneDataJoinCouponOrderList(params);
            countMap = list3.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));
        } else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.C_ORDER.getCode())){
            //购买发数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            params.put("channelType", EnumCouponSendSendType.C_ORDER.getCode());
            List<MarkingSceneDataReportVo> list4 = wxCouponActionLogMapper.sceneDataJoinCouponOrderList(params);
            countMap = list4.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));
        } else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.MERCHANT.getCode())){
            //购买发数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            params.put("channelType", markingCouponDataReportDto.getType());
            List<MarkingSceneDataReportVo> list5 = wxCouponActionLogMapper.sceneDataJoinCouponOrderList(params);
            countMap = list5.stream().collect(Collectors.toMap(MarkingSceneDataReportVo::getXTime, p -> p.getTempCount()));
        }

        Map<String, Integer> triggerCountMap = new HashMap<>();

        if(markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.CAR_STOP.getCode())){ //停车
            //获取车辆进场数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            params.put("cmdType", EnumCarCmd.CAR_ETCP_CALLBACK_PARK_IN.getCode());
            List<MarkingSceneDataVo> markingSceneDataVos = wxCarCmdLogMapper.queryForSceneRepotyHistoryCar(params);

            triggerCountMap = markingSceneDataVos.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getTriggerCount()));
        } else if(markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.B_MICROPAY.getCode())){ // B端刷卡支付发券
            //获取B端刷卡数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            params.put("type", EnumOrderType.MICROPAY.getCode());
            List<MarkingSceneDataVo> markingSceneDataVos = wxOrderMapper.queryForSceneRepotyHistory(params);
            triggerCountMap = markingSceneDataVos.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getTriggerCount()));
        } else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.COUPON_VERIFY.getCode())) {
            //获取核销数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            List<MarkingSceneDataVo> markingSceneDataVos = wxCouponOrderMapper.queryForSceneRepotyHistoryVerified(params);
            triggerCountMap = markingSceneDataVos.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getTriggerCount()));
        }else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.C_ORDER.getCode())) {
            //购买发券数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
            List<MarkingSceneDataVo> markingSceneDataVos = wxCouponOrderMapper.queryForSceneRepotyHistoryOrdered(params);
            triggerCountMap = markingSceneDataVos.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getTriggerCount()));
        }else if (markingCouponDataReportDto.getType().equals(EnumCouponSendSendType.MERCHANT.getCode())) {
            //购买发券数
            params.clear();
            params.put("tenantId", tenantId);
            if (markingCouponDataReportDto.getStartTime() != null)
                params.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
            if (markingCouponDataReportDto.getEndTime() != null)
                params.put("endTime", convertDateAndAdd(markingCouponDataReportDto.getEndTime(), 1));
                params.put("channelType", markingCouponDataReportDto.getType());
            List<MarkingSceneDataVo> markingSceneDataVos = wxCouponOrderMapper.queryForSceneRepotyMechantHistoryOrdered(params);
            triggerCountMap = markingSceneDataVos.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getTriggerCount()));
        }
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(2);
        for (MarkingSceneDataVo vo : list) {
            vo.setVerifiedCount(countMap.get(vo.getXtime()) == null ? 0 : countMap.get(vo.getXtime()));
            vo.setTriggerCount(triggerCountMap.get(vo.getXtime()) == null ? 0 : triggerCountMap.get(vo.getXtime()));
            if(vo.getSendCount()==0){
                vo.setVerifiedPercent("--");
            }else {
                vo.setVerifiedPercent(nf.format(new Double(vo.getVerifiedCount()) / new Double(vo.getSendCount())));
            }
        }
        return new PageInfo<>(list);
    }

    @Override
    public Map<String, Object> getSceneDataHistory(String tenantId,String startDate, String endDate) {
        Map<String ,Object> result = new HashedMap();

        MarkingCouponDataReportDto markingCouponDataReportDto = new MarkingCouponDataReportDto();
        markingCouponDataReportDto.setTenantId(tenantId);

        Date starttime = DateUtils.stringToDate(startDate);
        markingCouponDataReportDto.setStartTime(starttime);
        Date endtime = DateUtils.stringToDate(endDate, "yyyy-MM-dd 23:59:59");
        markingCouponDataReportDto.setEndTime(endtime);

        List<String> days = DateUtils.getTjTimeList(startDate.substring(0,10),endDate.substring(0,10),"0");
        TreeMap<String, Object> historyMap = new TreeMap<>();

        //停车发券
        markingCouponDataReportDto.setChannelType(EnumCouponSendSendType.CAR_STOP.getCode());
        List<MarkingSceneDataVo> carStopList = wxCouponActionLogMapper.sceneDataList(markingCouponDataReportDto);
        Map<String, Integer> countMap = carStopList.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getSendCount()));
        for (String date:days) {
            historyMap.put(date.substring(5,date.length()).replace("-","/"),"0");
        }
        for (String key : countMap.keySet()) {
            String keySub = key.substring(5,key.length()).replace("-","/");
            historyMap.put(keySub,countMap.get(key));
        }
        result.put("carStopHistory",historyMap);

        //核销发券
        markingCouponDataReportDto.setChannelType(EnumCouponSendSendType.COUPON_VERIFY.getCode());
        List<MarkingSceneDataVo> couponVerifyList = wxCouponActionLogMapper.sceneDataList(markingCouponDataReportDto);
        countMap = couponVerifyList.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getSendCount()));
        historyMap = new TreeMap<>();
        for (String date:days) {
            historyMap.put(date.substring(5,date.length()).replace("-","/"),"0");
        }
        for (String key : countMap.keySet()) {
            String keySub = key.substring(5,key.length()).replace("-","/");
            historyMap.put(keySub,countMap.get(key));
        }
        result.put("couponVerifyHistory",historyMap);

        //交易发券
        markingCouponDataReportDto.setChannelType(EnumCouponSendSendType.C_ORDER.getCode());
        List<MarkingSceneDataVo> orderList = wxCouponActionLogMapper.sceneDataList(markingCouponDataReportDto);
        countMap = orderList.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getSendCount()));
        historyMap = new TreeMap<>();
        for (String date:days) {
            historyMap.put(date.substring(5,date.length()).replace("-","/"),"0");
        }
        for (String key : countMap.keySet()) {
            String keySub = key.substring(5,key.length()).replace("-","/");
            historyMap.put(keySub,countMap.get(key));
        }
        result.put("orderHistory",historyMap);

        //收银台发券
        markingCouponDataReportDto.setChannelType(EnumCouponSendSendType.B_MICROPAY.getCode());
        List<MarkingSceneDataVo> micropayList = wxCouponActionLogMapper.sceneDataList(markingCouponDataReportDto);
        countMap = micropayList.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getSendCount()));
        historyMap = new TreeMap<>();
        for (String date:days) {
            historyMap.put(date.substring(5,date.length()).replace("-","/"),"0");
        }
        for (String key : countMap.keySet()) {
            String keySub = key.substring(5,key.length()).replace("-","/");
            historyMap.put(keySub,countMap.get(key));
        }
        result.put("micropayHistory",historyMap);

        //商户发券
        markingCouponDataReportDto.setChannelType(EnumCouponSendSendType.MERCHANT.getCode());
        List<MarkingSceneDataVo> merchantList = wxCouponActionLogMapper.sceneDataList(markingCouponDataReportDto);
        countMap = merchantList.stream().collect(Collectors.toMap(MarkingSceneDataVo::getXtime, p -> p.getSendCount()));
        historyMap = new TreeMap<>();
        for (String date:days) {
            historyMap.put(date.substring(5).replace("-","/"),"0");
        }
        for (String key : countMap.keySet()) {
            String keySub = key.substring(5).replace("-","/");
            historyMap.put(keySub,countMap.get(key));
        }
        result.put("merchantHistory",historyMap);

        return result;
    }


    @Override
    public Map<String, Object> listOrderReportByDate(WxOrderReportDto wxOrderReportDto) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("tenantId", wxOrderReportDto.getTenantId());
        if (wxOrderReportDto.getStartTime() != null) {
            params.put("startTime", convertDateAndAdd(wxOrderReportDto.getStartTime(), 0));
        } else {
            params.put("startTime", addDay(-30));
        }
        if (wxOrderReportDto.getEndTime() != null) {
            params.put("endTime", convertDateAndAdd(wxOrderReportDto.getStartTime(), 0));
        } else {
            params.put("endTime", addDay(1));
        }
        params.put("type", wxOrderReportDto.getType());
        params.put("orderStatus", wxOrderReportDto.getOrderStatus());
        List<WxOrderReportVo> list = wxOrderMapper.listOrderReportByDate(params);

        String startdate = DateUtils.getTimeBefore(30, new Date());
        String enddate = DateUtils.getTimeBefore(0,new Date());
        List<String> tjTimeList = DateUtils.getTjTimeList(startdate, enddate, "0");
        List<WxOrderReportVo> wxOrderReportVoList = new ArrayList<WxOrderReportVo>();

        int todayCount = 0;
        int todayAmount = 0;
        int yesterdayCount = 0;
        int yesterdayAmount = 0;
        int lastWeekCount = 0;
        int lastWeekAmount = 0;

        for(String tj:tjTimeList){
            Optional<WxOrderReportVo> first = list.stream().filter(c -> c.getXTime().equals(tj)).findFirst();
            if(!first.isPresent()){
                WxOrderReportVo orderReportVo = new WxOrderReportVo();
                orderReportVo.setAmount(0);
                orderReportVo.setCount(0);
                first = Optional.of(orderReportVo);
            }
            first.get().setXTime(tj.substring(5).replace("-", "/"));
            wxOrderReportVoList.add(first.get());
            if (LocalDate.now().equals(tj)){
                todayCount = first.get().getCount();
                todayAmount = first.get().getAmount();
            }
            if (LocalDate.now().minusDays(1).equals(tj)){
                yesterdayCount = first.get().getCount();
                yesterdayAmount = first.get().getAmount();
            }
            if (LocalDate.now().minusDays(7).equals(tj)){
                lastWeekCount = first.get().getCount();
                lastWeekAmount= first.get().getAmount();
            }

        }

        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(2);//控制保留小数点后几位，2：表示保留2位小数点
        String dayCountRate = "--";
        if (yesterdayCount != 0) {
            dayCountRate = nf.format((todayCount - yesterdayCount) / (float) yesterdayCount);
        }
        String weekCountRate = "--";
        if (lastWeekCount != 0) {
            weekCountRate = nf.format((todayCount - lastWeekCount) / (float) lastWeekCount);
        }

        String dayAmountRate = "--";
        if (yesterdayAmount != 0) {
            dayAmountRate = nf.format((todayAmount - yesterdayAmount) / (float) yesterdayAmount);
        }

        String weekAmountRate = "--";
        if (lastWeekAmount != 0) {
            weekAmountRate = nf.format((todayAmount - lastWeekAmount) / (float) lastWeekAmount);
        }

        HashMap<String, Object> returnMap = new HashMap<>();
        returnMap.put("microPayList",wxOrderReportVoList);
        returnMap.put("todayCount",todayCount);
        returnMap.put("dayCountRate",dayCountRate);
        returnMap.put("weekCountRate",weekCountRate);
        returnMap.put("todayAmount",todayAmount);
        returnMap.put("dayAmountRate",dayAmountRate);
        returnMap.put("weekAmountRate",weekAmountRate);

        return returnMap;
    }

    @Override
    public List<WxOrderReportVo> listMicroPayOrderReportByDateAndMerchant(WxOrderReportDto wxOrderReportDto) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("merchantId", wxOrderReportDto.getMerchantId());
        if (wxOrderReportDto.getStartTime() != null) {
            params.put("startTime", convertDateAndAdd(wxOrderReportDto.getStartTime(), 0));
        } else {
            params.put("startTime", addDay(-30));
        }
        if (wxOrderReportDto.getEndTime() != null) {
            params.put("endTime", convertDateAndAdd(wxOrderReportDto.getStartTime(), 0));
        } else {
            params.put("endTime", addDay(1));
        }
        List<WxOrderReportVo> list = wxOrderMapper.listMicroPayOrderReportByDateAndMerchant(params);

        String startdate = DateUtils.getTimeBefore(30, new Date());
        String enddate = DateUtils.getTimeBefore(0,new Date());
        List<String> tjTimeList = DateUtils.getTjTimeList(startdate, enddate, "0");
        List<WxOrderReportVo> wxOrderReportVoList = new ArrayList<WxOrderReportVo>();

        for(String tj:tjTimeList){
            Optional<WxOrderReportVo> first = list.stream().filter(c -> c.getXTime().equals(tj)).findFirst();
            if(!first.isPresent()){
                WxOrderReportVo orderReportVo = new WxOrderReportVo();
                orderReportVo.setAmount(0);
                orderReportVo.setCount(0);
                first = Optional.of(orderReportVo);
            }
            first.get().setXTime(tj.substring(5).replace("-", "/"));
            wxOrderReportVoList.add(first.get());
        }
        return wxOrderReportVoList;
    }

    @Override
    public PageInfo<WxMerchantMicroPayVo> listMerchantMicroPayOrderReportByDate(WxOrderReportDto wxOrderReportDto,Integer pageIndex, Integer pageSize) {
        if (wxOrderReportDto.getStartTime() != null) {
            wxOrderReportDto.setStartTime(convertDateAndAdd(wxOrderReportDto.getStartTime(), 0));
        } else {
            wxOrderReportDto.setStartTime(addDay(-1));
        }
        if (wxOrderReportDto.getEndTime() != null) {
            wxOrderReportDto.setEndTime(convertDateAndAdd(wxOrderReportDto.getStartTime(), 0));
        } else {
            wxOrderReportDto.setEndTime(addDay(0));
        }
        PageHelper.startPage(pageIndex, pageSize);
        List<WxMerchantMicroPayVo> list = wxOrderMapper.findListOfMerchantMicroPayOrderByDate(wxOrderReportDto);

        return new PageInfo<>(list);
    }

    @Override
    public void exportTouchUsersData(HttpServletRequest request, HttpServletResponse response, MarkingCouponDataReportDto markingCouponDataReportDto) {
        if (markingCouponDataReportDto.getStartTime() != null) {
            markingCouponDataReportDto.setStartTime(convertDateAndAdd(markingCouponDataReportDto.getStartTime(), 0));
        }
        if (markingCouponDataReportDto.getEndTime() != null) {
            markingCouponDataReportDto.setEndTime(markingCouponDataReportDto.getEndTime());
        }
        HashMap<String, Object> params2 = new HashMap<>();
        params2.put("tenantId", markingCouponDataReportDto.getTenantId());
        if (markingCouponDataReportDto.getStartTime() != null)
            params2.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(), 0));
        if (markingCouponDataReportDto.getEndTime() != null)
            params2.put("endTime", markingCouponDataReportDto.getEndTime());
        List<TouchUsersReportVo> wxUserVisitList = wxCouponOrderMapper.touchUsersReportList(params2);
        excelService.exportExcel(wxUserVisitList, null, "触达用户数", TouchUsersReportVo.class, "触达用户数" + ".xlsx", response, false);
    }


    @Override
    public PageInfo<TouchUsersReportVo> getTouchUsersReportList(String tenantId, MarkingCouponDataReportDto markingCouponDataReportDto, Integer pageIndex, Integer pageSize) {
        //查询UV PV
        markingCouponDataReportDto.setTenantId(tenantId);
        if (markingCouponDataReportDto.getStartTime() != null)
            markingCouponDataReportDto.setStartTime(convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
        if (markingCouponDataReportDto.getEndTime() != null)
            markingCouponDataReportDto.setEndTime(markingCouponDataReportDto.getEndTime());
        PageHelper.startPage(pageIndex, pageSize);


        //获取领取人数
        //获取领取量
        //获取核销人数
        //核销量
        HashMap<String, Object> params2 = new HashMap<>();
        params2.put("tenantId", tenantId);
        if (markingCouponDataReportDto.getStartTime() != null)
            params2.put("startTime", convertDateAndAdd(markingCouponDataReportDto.getStartTime(),0));
        if (markingCouponDataReportDto.getEndTime() != null)
            params2.put("endTime", markingCouponDataReportDto.getEndTime());
        List<TouchUsersReportVo> wxUserVisitList = wxCouponOrderMapper.touchUsersReportList(params2);
        return new PageInfo<>(wxUserVisitList);
    }

    @Override
    public List<TouchUsersReportVo> getTouchUsersReportData(String tenantId){
        //查询UV PV
        HashMap<String, Object> params = new HashMap<>();
        params.put("tenantId", tenantId);
        params.put("startTime", addDay(-30));
        params.put("endTime", addDay(1));
        List<TouchUsersReportVo> wxUserVisitList = wxUserVisitMapper.touchUsersReportData(params);

        String startdate = DateUtils.getTimeBefore(30, new Date());
        String enddate = DateUtils.getTimeBefore(1,new Date());
        List<String> tjTimeList = DateUtils.getTjTimeList(startdate, enddate, "0");
        List<String> tjList = tjTimeList.stream().map(d -> d.substring(5).replace("-", "/")).collect(Collectors.toList());
        List<TouchUsersReportVo> tempDatalist =new LinkedList<>();

        for(String tj:tjList){
            Optional<TouchUsersReportVo> first = wxUserVisitList.stream().filter(c -> c.getXTime().equals(tj)).findFirst();
            if(!first.isPresent()){
                TouchUsersReportVo touchUsersReportVo = new TouchUsersReportVo();
                touchUsersReportVo.setPv(0);
                touchUsersReportVo.setUv(0);
                touchUsersReportVo.setCouponCount(0);
                touchUsersReportVo.setUserCount(0);
                touchUsersReportVo.setVerifyCount(0);
                touchUsersReportVo.setVerifyUserCount(0);
                touchUsersReportVo.setXTime(tj);
                tempDatalist.add(touchUsersReportVo);
                continue;
            }
            tempDatalist.add(first.get());
        }

        return tempDatalist;

    }

}

