package com.iformall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.common.ResultData;
import com.iformall.domain.dto.WxCUserBasicInfoDto;
import com.iformall.domain.po.*;
import com.iformall.domain.vo.WxBillAll;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.*;
import com.iformall.service.DataTowerService;
import com.iformall.utils.DateUtils;
import com.iformall.utils.WiwideUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author gongbiao
 */
@Service
public class DataTowerServiceImpl implements DataTowerService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WxShopMapper wxShopMapper;

    @Autowired
    WxMerchantMapper wxMerchantMapper;

    @Autowired
    WxMerchantTradeDailyMapper wxMerchantTradeDailyMapper;

    @Autowired
    WxCarCmdLogMapper wxCarCmdLogMapper;

    @Autowired
    WxWiwideInfoMapper wxWiwideInfoMapper;

    @Autowired
    WxBillRentMapper wxBillRentMapper;

    @Autowired
    WxCouponOrderMapper wxCouponOrderMapper;

    @Autowired
    WxCouponChannelMapper wxCouponChannelMapper;

    @Autowired
    WxRentContractMapper wxRentContractMapper;

    @Autowired
    WxBillAllMapper wxBillAllMapper;

    @Autowired
    WxMsgConfigMapper wxMsgConfigMapper;

    @Autowired
    WxCUserCarMapper wxCUserCarMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    //出租与未出租***********************************************
    private Map<String, Object> shopRunning(String tenantId) {

        WxShop wxShop = new WxShop();
        wxShop.setTenantId(tenantId);
        wxShop.setStatus(EnumShopStatus.RENT.getCode());
        List<WxShop> rentedList = wxShopMapper.findList(wxShop);
        wxShop.setStatus(EnumShopStatus.NOT_RENT.getCode());
        List<WxShop> unrentedList = wxShopMapper.findList(wxShop);

        HashMap<String, Object> shopMap = new HashMap<>();
        int rentedCount = rentedList.size();
        int unrentedCount = unrentedList.size();
        int total = rentedCount + unrentedCount;
        if (total == 0) {
            shopMap.put("rentedCount", 0);
            shopMap.put("unrentedCount", 0);
            shopMap.put("rentedPercent", "--");
            shopMap.put("unrentedPercent", "--");
        } else {
            shopMap.put("rentedCount", rentedCount);
            shopMap.put("unrentedCount", unrentedCount);
            double rentedPercent = new BigDecimal(((double) rentedCount / total) * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double unrentedPercent = new BigDecimal(((double) unrentedCount / total) * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            shopMap.put("rentedPercent", rentedPercent + "%");
            shopMap.put("unrentedPercent", unrentedPercent + "%");
        }
        return shopMap;
    }

    //租金***********************************************
    private Map<String, Object> rentRunning(String tenantId) {

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

        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DAY_OF_YEAR, 1);
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        String startdate = DateUtils.date2String(instance);
        instance.clear();
        String enddate = DateUtils.getSystemTime("yyyy-MM-dd HH:mm:ss");
        params.put("startdate", startdate);
        params.put("enddate", enddate);
        Map<String, Object> payinfo = wxBillRentMapper.queryPayInfo(params);
        if (payinfo != null) {
            BigDecimal receivableAmount = (BigDecimal) payinfo.get("receivepay");
            BigDecimal receivedAmount = (BigDecimal) payinfo.get("pay");
            if (receivableAmount.longValue() > 0) {
                BigDecimal divide = receivedAmount.divide(receivableAmount, 2, BigDecimal.ROUND_HALF_UP);
                double receivedPercent = divide.multiply(new BigDecimal(100)).doubleValue();
                rentMap.put("receivedPercent", receivedPercent + "%");
            } else {
                rentMap.put("receivedPercent", "--");
            }
            rentMap.put("receivableAmount", receivableAmount.longValue());
            rentMap.put("receivedAmount", receivedAmount.longValue());
            rentMap.put("arrearsAmount", receivedAmount.longValue()>receivableAmount.longValue()?0:receivableAmount.subtract(receivedAmount).longValue());
        } else {
            rentMap.put("receivableAmount", 0);
            rentMap.put("receivedAmount", 0);
            rentMap.put("arrearsAmount", 0);
            rentMap.put("receivedPercent", "--");
        }
        return rentMap;
    }

    //上报解单***********************************************
    private Map<String, Object> reportRunning(String tenantId) {

        HashMap<String, Object> reportMap = new HashMap<>();
        WxMerchant wxMerchant = new WxMerchant();
        wxMerchant.setTenantId(tenantId);
        wxMerchant.setStatus(EnumMerchantStatus.VALID.getCode());
        List<WxMerchant> merchants = wxMerchantMapper.findList(wxMerchant);

        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();
        wxMerchantTradeDaily.setTenantId(tenantId);
        String reportDate = DateUtils.getTimeBefore(1, new Date());
        wxMerchantTradeDaily.setReportDate(reportDate);
        List<WxMerchantTradeDaily> tradeList = wxMerchantTradeDailyMapper.findList(wxMerchantTradeDaily);
        int merchantCount = merchants.size();
        int tradeCount = tradeList.size();
        if (merchantCount > 0 && tradeCount > 0) {
            double reportPercent = new BigDecimal(((double) tradeCount / merchantCount) * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            reportMap.put("reportPercent", reportPercent + "%");
        } else {
            reportMap.put("reportPercent", "--");
        }
        reportMap.put("reportCount", tradeCount);
        reportMap.put("silenceCount", merchantCount - tradeCount);
        int reportTotal = tradeList.stream().mapToInt(WxMerchantTradeDaily::getTradeAmtInteger).sum();
        reportMap.put("reportTotal", reportTotal);

        return reportMap;
    }


    //今日车流量***********************************************
    private Map<String, Object> carRunning(String tenantId) {
        HashMap<String, Object> carMap = new HashMap<>();
        HashMap<String, Object> paramsCar = new HashMap<>();
        paramsCar.put("tenantId", tenantId);
        paramsCar.put("cmdType", EnumCarCmd.CAR_ETCP_CALLBACK_PARK_IN.getCode());
        String startdate = DateUtils.getTimeBefore(30, new Date());
        String systemTime = DateUtils.getSystemTime("yyyy-MM-dd");

        List<String> tjTimeList = DateUtils.getTjTimeList(startdate, systemTime, "0");

        paramsCar.put("startdate", startdate + " 00:00:00");
        paramsCar.put("enddate", systemTime + " 23:59:59");

        List<Map<String, Object>> historylist = wxCarCmdLogMapper.queryHistory(paramsCar);

        Map<Object, Object> collect = historylist.stream().collect(Collectors.toMap(m -> {
            return m.get("create_date");
        }, m -> {
            return m.get("carcount");
        }));

        TreeMap<Object, Object> historymap = new TreeMap<>();
        for (String date : tjTimeList) {
            Object o = collect.get(date);
            if (o == null) {
                historymap.put(date.substring(5).replace("-", "/"), 0L);
            } else {
                historymap.put(date.substring(5).replace("-", "/"), o);
            }
        }

        long todaycar = (long) historymap.get(DateUtils.getSystemTime("MM/dd"));
        carMap.put("carCount", todaycar);

        //环比
        String yesterday = DateUtils.getTimeBefore(1, new Date());
        long yesterdaycar = (long) historymap.get(yesterday.substring(5).replace("-", "/"));
        if (yesterdaycar > 0) {
            double hbd = (double) (todaycar - yesterdaycar) / yesterdaycar * 100;
            double hb = new BigDecimal(hbd).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            carMap.put("increasedPercent", hb+"%");
        } else {
            carMap.put("increasedPercent", "--");
        }

        //上周同期
        String lastweek = DateUtils.getTimeBefore(7, new Date());
        long last = (long) historymap.get(lastweek.substring(5).replace("-", "/"));
        if (last > 0) {
            double lasthbd = (double) (todaycar - last) / last * 100;
            double lasthb = new BigDecimal(lasthbd).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            carMap.put("increasedPercentWeek", lasthb+"%");
        } else {
            carMap.put("increasedPercentWeek", "--");
        }

        return carMap;
    }

    //今日券数据***********************************************
    private Map<String, Object> couponRunning(String tenantId) {

        HashMap<String, Object> couponMap = new HashMap<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date startTime = cal.getTime();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        Date endTime = cal.getTime();

        WxCouponOrder wxCouponOrder = new WxCouponOrder();
        wxCouponOrder.setTenantId(tenantId);
        wxCouponOrder.setStartTime(startTime);
        wxCouponOrder.setEndTime(endTime);
        long orderedCount = wxCouponOrderMapper.findCount(wxCouponOrder);
        wxCouponOrder.setCouponOrderStatus(EnumCouponOrderStatus.COUPON_ORDER_USED.getCode());
        long verifiedCount = wxCouponOrderMapper.findCount(wxCouponOrder);
        couponMap.put("verifiedCount", verifiedCount);
        couponMap.put("orderedCount", orderedCount);
        WxCouponChannel wxCouponChannel = new WxCouponChannel();
        wxCouponChannel.setTenantId(tenantId);
        wxCouponChannel.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode());
        long couponCount = wxCouponChannelMapper.countCoupon(wxCouponChannel);
        couponMap.put("couponCount", couponCount);

        return couponMap;
    }

    //今日客流***********************************************
    private Map<String, Object> visitorRunning(String tenantId) {
        HashMap<String, Object> visitorMap = new HashMap<>();
        visitorMap.put("todayCount", "--");
        visitorMap.put("increasedPercent", "--");
        visitorMap.put("increasedPercentWeek", "--");
        return visitorMap;
    }

    //合同***********************************************
    private Map<String, Object> contractRunning(String tenantId) {

        Map<String, Object> contractMap = new HashMap();
        WxRentContract wxRentContract = new WxRentContract();
        wxRentContract.setTenantId(tenantId);

        //待签约
        wxRentContract.setStatus(EnumRentContractStatus.WAIT_SIGN.getCode());
        int waitSignCount = wxRentContractMapper.queryRentContractWaitSignStatus(wxRentContract);
        contractMap.put("waitSignCount", waitSignCount);

        //计租中
        wxRentContract.setStatus(EnumRentContractStatus.RENT_PAID.getCode());
        int rendPaidCount = wxRentContractMapper.queryRentContractPaidStatus(wxRentContract);
        contractMap.put("rendPaidCount", rendPaidCount);

        //将到期
        wxRentContract.setStatus(EnumRentContractStatus.CONTRACT_END_SOON.getCode());
        int endSoonCount = wxRentContractMapper.queryRentContractEndSoonStatus(wxRentContract);
        contractMap.put("endSoonCount", endSoonCount);

        //到期
        wxRentContract.setStatus(EnumRentContractStatus.CONTRACT_END.getCode());
        int endCount = wxRentContractMapper.queryRentContractEndStatus(wxRentContract);
        contractMap.put("endCount", endCount);

        return contractMap;
    }

    //短信***********************************************
    private Map<String, Object> messageRunning(String tenantId) {
        HashMap<String, Object> messageMap = new HashMap<>();

        WxMsgConfig wxMsgConfig = new WxMsgConfig();
        wxMsgConfig.setTenantId(wxMsgConfig.getTenantId());
        List<WxMsgConfig> wxMsgConfigs = wxMsgConfigMapper.findList(wxMsgConfig);

        long usedCount = 0;
        long remainsCount = 0;
        long totalCount = 0;
        if (wxMsgConfigs.size() > 0) {
            wxMsgConfig = wxMsgConfigs.get(0);
            totalCount = wxMsgConfig.getTotal();
            remainsCount = wxMsgConfig.getRemains();
            usedCount = totalCount - remainsCount;
        }

        messageMap.put("usedCount", usedCount);
        messageMap.put("totalCount", totalCount);
        messageMap.put("remainsCount", remainsCount);

        return messageMap;
    }

    //账单***********************************************
    private Map<String, Object> billRunning(String tenantId) {
        HashMap<String, Object> billMap = new HashMap<>();
        WxBillAll record = new WxBillAll();
        record.setTenantId(tenantId);
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DAY_OF_YEAR, 1);
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        String startdate = DateUtils.date2String(instance);
        instance.clear();
        String enddate = DateUtils.getSystemTime("yyyy-MM-dd HH:mm:ss");
        record.setStarttime(startdate);
        record.setEndtime(enddate);
        record.setStatus(EnumBillRentStatus.NOT_PAID.getCode());
        Map<String, Object> oweInfo = wxBillAllMapper.queryOweInfo(record);
        record.setStatus(EnumBillRentStatus.PAID.getCode());
        Map<String, Object> paidInfo = wxBillAllMapper.queryPaidInfo(record);

        billMap.putAll(oweInfo);
        billMap.putAll(paidInfo);
        return billMap;
    }

    //移动端首页
    @Override
    public Map<String, Object> queryRunningMobile(String tenantId) {

        HashMap<String, Object> dataMap = new HashMap<>();
        dataMap.put("shop", shopRunning(tenantId));
        dataMap.put("rent", rentRunning(tenantId));
        dataMap.put("report", reportRunning(tenantId));
        dataMap.put("car", carRunning(tenantId));
        dataMap.put("coupon", couponRunning(tenantId));
        dataMap.put("visitor", visitorRunning(tenantId));

        return dataMap;
    }

    //登陆页数据快速概览
    @Override
    public Map<String, Object> queryRunningPotal(String tenantId) {

        HashMap<String, Object> dataMap = new HashMap<>();
        dataMap.put("shop", shopRunning(tenantId));
        dataMap.put("rent", rentRunning(tenantId));
        dataMap.put("report", reportRunning(tenantId));
        dataMap.put("car", carRunning(tenantId));
        dataMap.put("coupon", couponRunning(tenantId));
        dataMap.put("visitor", visitorRunning(tenantId));
        dataMap.put("contract", contractRunning(tenantId));
        dataMap.put("message", messageRunning(tenantId));
        dataMap.put("bill", billRunning(tenantId));
        return dataMap;
    }


    @Override
    public Map<String, Object> queryRunning(String tenantId) {
        WxShop wxShop = new WxShop();
        wxShop.setTenantId(tenantId);
        wxShop.setStatus(EnumShopStatus.RENT.getCode());
        List<WxShop> yczlist = wxShopMapper.findList(wxShop);
        wxShop.setStatus(EnumShopStatus.NOT_RENT.getCode());
        List<WxShop> wczlist = wxShopMapper.findList(wxShop);

        //出租与未出租
        HashMap<String, Object> datamap = new HashMap<>();
        int yczsize = yczlist.size();
        int wczsize = wczlist.size();
        int size = yczsize + wczsize;
        if (size == 0) {
            datamap.put("yczsl", 0);
            datamap.put("wczsl", 0);
            datamap.put("yczl", 0);
            datamap.put("wczl", 0);
        } else {
            datamap.put("yczsl", yczsize);
            datamap.put("wczsl", wczsize);
            double yczld = ((double) yczsize / size) * 100;
            double dczl = new BigDecimal(yczld).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double wczld = ((double) wczsize / size) * 100;
            double wczl = new BigDecimal(wczld).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            datamap.put("yczl", dczl);
            datamap.put("wczl", wczl);
        }

        //租金
        Map<String, Object> params = new HashMap<>();
        params.put("tenantId", tenantId);
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DAY_OF_YEAR, 1);
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        String startdate = DateUtils.date2String(instance);
        instance.clear();
        String enddate = DateUtils.getSystemTime("yyyy-MM-dd HH:mm:ss");
        params.put("startdate", startdate);
        params.put("enddate", enddate);
        Map<String, Object> payinfo = wxBillRentMapper.queryPayInfo(params);
        if (payinfo != null) {
            BigDecimal receivepay = (BigDecimal) payinfo.get("receivepay");
            BigDecimal pay = (BigDecimal) payinfo.get("pay");
            if (receivepay.doubleValue() > 0) {
                BigDecimal divide = pay.divide(receivepay, 2, BigDecimal.ROUND_HALF_UP);
                double zjcjl = divide.multiply(new BigDecimal(100)).doubleValue();
                datamap.put("ysje", receivepay);
                datamap.put("ssje", pay);
                datamap.put("zjsjl", zjcjl);
            } else {
                datamap.put("ysje", 0);
                datamap.put("ssje", 0);
                datamap.put("zjsjl", 0);
            }
        } else {
            datamap.put("ysje", 0);
            datamap.put("ssje", 0);
            datamap.put("zjsjl", 0);
        }

        //上报
        WxMerchant wxMerchant = new WxMerchant();
        wxMerchant.setTenantId(tenantId);
        wxMerchant.setStatus(1);
        List<WxMerchant> merchants = wxMerchantMapper.findList(wxMerchant);

        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();
        wxMerchantTradeDaily.setTenantId(tenantId);
        String reportdate = DateUtils.getTimeBefore(1, new Date());
        wxMerchantTradeDaily.setReportDate(reportdate);
        List<WxMerchantTradeDaily> tradelist = wxMerchantTradeDailyMapper.findList(wxMerchantTradeDaily);
        int merchantsize = merchants.size();
        int tradesize = tradelist.size();
        if (merchantsize > 0 && tradesize > 0) {
            double shsbld = ((double) tradesize / merchantsize) * 100;
            double shsbl = new BigDecimal(shsbld).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            datamap.put("shsbl", shsbl);
        } else {
            datamap.put("shsbl", 0);
        }

        int shsbjg = tradelist.stream().mapToInt(WxMerchantTradeDaily::getTradeAmtInteger).sum();
        datamap.put("shsbjg", shsbjg);

        return datamap;
    }

    @Override
    public Map<String, Object> queryCar(String tenantId) {
        logger.info("停车-月统计-开始");
        HashMap<String, Object> params = new HashMap<>();
        params.put("tenantId", tenantId);
        params.put("cmdType", EnumCarCmd.CAR_ETCP_CALLBACK_PARK_IN.getCode());
        String startdate = DateUtils.getTimeBefore(30, new Date());
        String systemTime = DateUtils.getSystemTime("yyyy-MM-dd");

        List<String> tjTimeList = DateUtils.getTjTimeList(startdate, systemTime, "0");

        params.put("startdate", startdate + " 00:00:00");
        params.put("enddate", systemTime + " 23:59:59");

        List<Map<String, Object>> historylist = wxCarCmdLogMapper.queryHistory(params);

        Map<Object, Object> collect = historylist.stream().collect(Collectors.toMap(m -> {
            return m.get("create_date");
        }, m -> {
            return m.get("carcount");
        }));

        Map<Object, Object> historymap = new LinkedHashMap<>();
        for (String date : tjTimeList) {
            Object o = collect.get(date);
            if (o == null) {
                historymap.put(date.substring(5).replace("-", "/"), 0L);
            } else {
                historymap.put(date.substring(5).replace("-", "/"), o);
            }
        }
        Map<String, Object> datamap = new HashMap<>();
        datamap.put("history", historymap);
        logger.info("停车-月统计-结束");

        // 查询近一周的缴费车辆----start------
        logger.info("停车-查询近一周的缴费车辆-开始");
        HashMap<String, Object> weekParams = new HashMap<>();
        weekParams.put("tenantId", tenantId);
        String oneWeekStartdate = DateUtils.getTimeBefore(7, new Date());
        String oneWeekEndDate = DateUtils.getTimeBefore(1, new Date());
        weekParams.put("startdate", oneWeekStartdate + " 00:00:00");
        weekParams.put("enddate", oneWeekEndDate + " 23:59:59");
        weekParams.put("cmdType", EnumCarCmd.CAR_ETCP_CALLBACK_PAY_MANUAL.getCode());

        datamap.put("oneWeekCarPayCount",wxCarCmdLogMapper.queryWeekCarPayCount(weekParams));
        logger.info("停车-查询近一周的缴费车辆-结束");

        // 近一周缴费金额
        logger.info("停车-查询近一周的缴费金额-开始");
        weekParams.put("cmdType", EnumCarCmd.CAR_ETCP_CALLBACK_PAY_MANUAL.getCode());
        List<Map<String, Object>> weekCarPayHistoryList = wxCarCmdLogMapper.queryWeekCarPay(weekParams);
        Map<String, Object> weekCollect = weekCarPayHistoryList.stream().collect(Collectors.toMap(m -> {
            return (String)m.get("create_time");
        }, m -> {
            return m.get("fee");
        }));
        List<String> days = DateUtils.getTjTimeList(oneWeekStartdate, oneWeekEndDate, "0");

        TreeMap<String, Object> weekMap = new TreeMap<>();
        for (String date:days) {
            String dateStr = date.substring(5,date.length()).replace("-","/");
            Object o = weekCollect.get(dateStr);
            if(o == null) {
                weekMap.put(dateStr,"0");
            } else {
                weekMap.put(dateStr,o.toString());
            }
        }
        datamap.put("oneWeekCarPayFeeCount",weekMap);
        logger.info("停车-查询近一周的缴费金额-结束");

        // 近一周新增会员历史
        logger.info("停车-近一周新增会员历史-开始");
        List<Map<String, Object>> carCountHistory  = wxCUserCarMapper.queryCarCountHistory(weekParams);
        Map<String, Object> weekCarCollect = carCountHistory.stream().collect(Collectors.toMap(m -> {
            return (String)m.get("create_time");
        }, m -> {
            return m.get("count");
        }));
        TreeMap<String, Object> weekCarMap = new TreeMap<>();
        for (String date:days) {
            String dateStr = date.substring(5,date.length()).replace("-","/");
            Object o = weekCarCollect.get(dateStr);
            if(o == null) {
                weekCarMap.put(dateStr, "0");
            } else {
                weekCarMap.put(dateStr, o.toString());
            }
        }
        datamap.put("oneWeekNewCarUserHistory",weekCarMap);
        logger.info("停车-近一周新增会员历史-结束");

        //近一周新增停车会员数
        logger.info("停车-近一周新增停车会员数-开始");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        WxCUserBasicInfoDto wxCUserBasicInfoDto = new WxCUserBasicInfoDto();
        wxCUserBasicInfoDto.setTenantId(tenantId);
        try {
            wxCUserBasicInfoDto.setStartTime(sdf.parse(oneWeekStartdate+ " 00:00:00"));
            wxCUserBasicInfoDto.setEndTime(sdf.parse(oneWeekEndDate+ " 23:59:59"));
        }catch (Exception e){
            e.printStackTrace();
        }
        datamap.put("oneWeekNewCarUserCount",wxCUserCarMapper.countUser(wxCUserBasicInfoDto));
        logger.info("停车-近一周新增停车会员数-结束");
        //停车会员总数
        logger.info("停车-停车会员总数-开始");
        wxCUserBasicInfoDto = new WxCUserBasicInfoDto();
        wxCUserBasicInfoDto.setTenantId(tenantId);
        datamap.put("newCarUserSumCount",wxCUserCarMapper.countUser(wxCUserBasicInfoDto));
        logger.info("停车-停车会员总数-结束");

        // 查询近一周的缴费车辆----end------

        //今日车流量
        logger.info("停车-今日车流量-开始");
        long todaycar = (long) historymap.get(DateUtils.getSystemTime("MM/dd"));
        datamap.put("todaycar", todaycar);
        //环比
        String yesterday = DateUtils.getTimeBefore(1, new Date());
        long yesterdaycar = (long) historymap.get(yesterday.substring(5).replace("-", "/"));
        if (yesterdaycar > 0) {
            double hbd = (double) (todaycar - yesterdaycar) / yesterdaycar * 100;
            double hb = new BigDecimal(hbd).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            datamap.put("hb", hb + "%");
        } else {
            datamap.put("hb", "--");
        }
        logger.info("停车-今日车流量-结束");

        //上周同期
        logger.info("停车-上周同期-开始");
        String lastweek = DateUtils.getTimeBefore(7, new Date());
        long last = (long) historymap.get(lastweek.substring(5).replace("-", "/"));
        if (last > 0) {
            double lasthbd = (double) (todaycar - last) / last * 100;
            double lasthb = new BigDecimal(lasthbd).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            datamap.put("lasthb", lasthb + "%");
        } else {
            datamap.put("lasthb", "--");
        }
        logger.info("停车-上周同期-结束");

        // 今日
        logger.info("停车-今日停车数据-开始");
        params.put("startdate", systemTime + " 05:00:00");
        params.put("enddate", DateUtils.getSystemTime("yyyy-MM-dd HH:mm:ss"));

        List<Map<String, Object>> todayCarlist = wxCarCmdLogMapper.queryTodayCar(params);
        Map<Object, Object> todaycollect = todayCarlist.stream().collect(Collectors.toMap(m -> {
            return m.get("create_time");
        }, m -> {
            return m.get("carcount");
        }));

        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.HOUR_OF_DAY, 1);
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        TreeMap<Object, Object> hourMap = new TreeMap<>();
        int startHour = 6;
        int endHour = 24;
        for (int i = startHour; i < endHour; i++) {
            if (i <= hour) {
                hourMap.put(i < 10 ? "0" + i + ":00" : i + ":00", 0);
            } else {
                hourMap.put(i < 10 ? "0" + i + ":00" : i + ":00", "");
            }
        }
        hourMap.putAll(todaycollect);

        datamap.put("todaycardata", hourMap);
        logger.info("停车-今日停车数据-结束");

        // 昨日
        logger.info("停车-昨日停车数据-开始");
        params.put("startdate", yesterday + " 05:00:00");
        params.put("enddate", yesterday + " 22:59:59");
        List<Map<String, Object>> yesterdayCarlist = wxCarCmdLogMapper.queryTodayCar(params);
        Map<Object, Object> yesterdaycollect = yesterdayCarlist.stream().collect(Collectors.toMap(m -> {
            return m.get("create_time");
        }, m -> {
            return m.get("carcount");
        }));
        TreeMap yesterdaytreemap = getTimeTreeMap();
        yesterdaytreemap.putAll(yesterdaycollect);

        datamap.put("yesterdaycardata", yesterdaytreemap);
        logger.info("停车-昨日停车数据-结束");

        // 上周同期
        logger.info("停车-上周同期停车数据-开始");
        params.put("startdate", lastweek + " 05:00:00");
        params.put("enddate", lastweek + " 22:59:59");
        List<Map<String, Object>> lastweekCarlist = wxCarCmdLogMapper.queryTodayCar(params);
        Map<Object, Object> lastweekcollect = lastweekCarlist.stream().collect(Collectors.toMap(m -> {
            return m.get("create_time");
        }, m -> {
            return m.get("carcount");
        }));
        TreeMap lastweektreemap = getTimeTreeMap();
        lastweektreemap.putAll(lastweekcollect);
        datamap.put("lastdaycardata", lastweektreemap);
        logger.info("停车-上周同期停车数据-结束");

        //绑定车牌
        logger.info("停车-绑定车牌-开始");
        Map<String,Object> carParams=new HashMap<>();
        carParams.put("tenantId",tenantId);
        carParams.put("startdate",DateUtils.getSystemTime("yyyy-MM-dd 00:00:00"));
        carParams.put("enddate",DateUtils.getSystemTime("yyyy-MM-dd HH:mm:ss"));
        long todaybindcar = wxCUserCarMapper.queryCarCount(carParams);
        carParams.put("startdate",yesterday+" 00:00:00");
        carParams.put("enddate",yesterday+" 23:59:59");
        long yesterdaybindcar = wxCUserCarMapper.queryCarCount(carParams);
        carParams.put("startdate",lastweek+" 00:00:00");
        carParams.put("enddate",lastweek+" 23:59:59");
        long lastweekbindcar = wxCUserCarMapper.queryCarCount(carParams);
        datamap.put("todaybindcar",todaybindcar);

        if (yesterdaybindcar > 0) {
            double yesterdaybinddhb = (double) (todaybindcar - yesterdaybindcar) / yesterdaybindcar * 100;
            double yesterdaybindhb = new BigDecimal(yesterdaybinddhb).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            datamap.put("yesterdaybindhb", yesterdaybindhb+"%");
        } else {
            datamap.put("yesterdaybindhb", "--");
        }

        if (lastweekbindcar > 0) {
            double lastweekbinddhb = (double) (todaybindcar - lastweekbindcar) / lastweekbindcar * 100;
            double lastweekbindhb = new BigDecimal(lastweekbinddhb).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            datamap.put("lastweekbindhb", lastweekbindhb+"%");
        } else {
            datamap.put("lastweekbindhb", "--");
        }
        logger.info("停车-绑定车牌-结束");

        return datamap;

    }

    @Override
    public Map<String, Object> queryCustomer(String tenantId) {
        WxWiWideInfo wiWideInfo = new WxWiWideInfo();
        wiWideInfo.setTenantId(tenantId);
        List<WxWiWideInfo> list = wxWiwideInfoMapper.findList(wiWideInfo);
        Map<String, Object> datamap = new HashMap<>(2);
        if(list.size()>0){
            wiWideInfo = list.get(0);
            String wiwideUrl = wiWideInfo.getWiwideUrl();
            datamap.put("token", getWiwideToken(wiWideInfo));
            datamap.put("url", wiwideUrl);
            datamap.put("capability", wiWideInfo.getCapability());
        }
        return datamap;
    }

    private void updateToken(WxWiWideInfo wiWideInfo, String token) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MINUTE, 45);
        logger.info("数据表中的数据："+JSONObject.toJSONString(wiWideInfo));
        WxWiWideInfo record = new WxWiWideInfo();
        record.setId(wiWideInfo.getId());
        record.setToken(token);
        record.setExpiredTime(instance.getTime());
        try {
            logger.info("要更新的数据before>>>>>>>>>>"+JSONObject.toJSONString(record));
            wxWiwideInfoMapper.updateToken(record);
            logger.info("要更新的数据after>>>>>>>>>>"+JSONObject.toJSONString(record));
        } catch (MallinkException e) {
            logger.info("更新TOKEN失败：商场" + wiWideInfo.getTenantId());
        }
    }

    private String getWiwideToken(WxWiWideInfo wiWideInfo) {
        Date expiredTime = wiWideInfo.getExpiredTime();
        String token = wiWideInfo.getToken();
        logger.info("wiwideinfo:"+JSONObject.toJSONString(wiWideInfo));
        if (StringUtils.isEmpty(token) || expiredTime == null || expiredTime.before(new Date())) {
            String data = WiwideUtil.queryToken(wiWideInfo);
            logger.info("bid:"+wiWideInfo.getWiwideId()+",newdata:"+data);
            if (data == null)
                return null;
            token = (String) JSONObject.parseObject(data).get("data");
            updateToken(wiWideInfo, token);
        }
        logger.info("返回的token:"+token);
        return token;
    }

    @Override
    public ResultData queryCustomerData(String tenantId, Map<String, String> params) {
        WxWiWideInfo wiWideInfo = new WxWiWideInfo();
        wiWideInfo.setTenantId(tenantId);
        List<WxWiWideInfo> list = wxWiwideInfoMapper.findList(wiWideInfo);
        if (list.isEmpty()){
            return new ResultData(ErrorCode.WIWIDE_INFO_NOT_FOUND);
        }
        wiWideInfo = list.get(0);
        List<Integer> cap = JSONArray.parseArray(wiWideInfo.getCapability(), Integer.class);
        Integer dataType;
        try {
            dataType = Integer.valueOf(params.get("dataType"));
            params.remove("dataType");
        }catch (Exception e){
            return new ResultData(ErrorCode.WIWIDE_INFO_NOT_FOUND);
        }

        if (cap == null || !cap.stream().anyMatch(c->c.equals(dataType))) {
            return new ResultData(ErrorCode.WIWIDE_INFO_NOT_FOUND);
        }
        logger.info("迈外迪访问接口参数：" + params);
        String res = WiwideUtil.queryData(wiWideInfo, getWiwideToken(wiWideInfo), params);
        logger.info("迈外迪访问接口结果：" + res);
        JSONObject result = JSONObject.parseObject(res);
        if (result == null)
            return new ResultData(ErrorCode.WIWIDE_INFO_NOT_READY);
        if (result.getInteger("result") == 200){
            return new ResultData(result.getInteger("result"),result.getString("msg"),
                    result.getJSONObject("data"));
        } else{
            return new ResultData(result.getInteger("result"),result.getString("msg"));
        }
    }

    public TreeMap getTimeTreeMap() {
        TreeMap<Object, Object> timemap = new TreeMap();
        timemap.put("06:00", 0);
        timemap.put("07:00", 0);
        timemap.put("08:00", 0);
        timemap.put("09:00", 0);
        timemap.put("10:00", 0);
        timemap.put("11:00", 0);
        timemap.put("12:00", 0);
        timemap.put("13:00", 0);
        timemap.put("14:00", 0);
        timemap.put("15:00", 0);
        timemap.put("16:00", 0);
        timemap.put("17:00", 0);
        timemap.put("18:00", 0);
        timemap.put("19:00", 0);
        timemap.put("20:00", 0);
        timemap.put("21:00", 0);
        timemap.put("22:00", 0);
        timemap.put("23:00", 0);
        return timemap;
    }



}
