package com.kxs.stat.biz.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kxs.common.core.util.AssertUtil;
import com.kxs.common.core.util.R;
import com.kxs.product.api.model.KxsBrand;
import com.kxs.stat.api.dto.statUser.GetActivityStatByIdAndTimeDTO;
import com.kxs.stat.api.vo.GetActivityStatByIdAndTimeVO;
import com.kxs.stat.api.vo.myUser.TrendVO;
import com.kxs.stat.api.vo.statUser.*;
import com.kxs.stat.biz.constant.enums.TotalTypeEnum;
import com.kxs.stat.biz.mapper.KxsLkbActTradeMapper;
import com.kxs.stat.biz.mapper.KxsUserActTradeMapper;
import com.kxs.stat.api.model.KxsUserActTrade;
import com.kxs.stat.biz.service.KxsUserActTradeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 创客激活统计表(KxsUserActTrade)表服务实现类
 *
 * @author 系统
 * @since 2024-05-07 17:25:06
 */
@Service("kxsUserActTradeService")
@RequiredArgsConstructor
public class KxsUserActTradeServiceImpl extends ServiceImpl<KxsUserActTradeMapper, KxsUserActTrade> implements KxsUserActTradeService {

    private final KxsLkbActTradeMapper lkbActTradeMapper;

    @Override
    public List<GetActivityStatByIdAndTimeVO> getActivityStatByIdAndTime(List<GetActivityStatByIdAndTimeDTO> param) {
        ArrayList<GetActivityStatByIdAndTimeVO> getActivityStatByIdAndTimeVOS = new ArrayList<>();
        for (GetActivityStatByIdAndTimeDTO getActivityStatByIdAndTimeDTO : param) {
            Long userId = getActivityStatByIdAndTimeDTO.getUserId();
            List<String> times = getActivityStatByIdAndTimeDTO.getTimes();
//            //查询pos激活  不再查询
//            Integer posNumber = baseMapper.getActivityStatByGdOrPos(userId,times,1);
//            //查询广电激活  不再查询
//            Integer gdNumber = baseMapper.getActivityStatByGdOrPos(userId,times,2);
            //查询来客吧激活
            Integer lkbNumber = lkbActTradeMapper.getActivityStatByLkb(userId,times);
            GetActivityStatByIdAndTimeVO getActivityStatByIdAndTimeVO = new GetActivityStatByIdAndTimeVO();
            getActivityStatByIdAndTimeVO.setUserId(userId);
//            getActivityStatByIdAndTimeVO.setPosActivityNumber(posNumber);
//            getActivityStatByIdAndTimeVO.setGdActivityNumber(gdNumber);
            getActivityStatByIdAndTimeVO.setLkbActivityNumber(lkbNumber);
            getActivityStatByIdAndTimeVOS.add(getActivityStatByIdAndTimeVO);
        }
        return getActivityStatByIdAndTimeVOS;
    }

    @Override
    public R getActivateMerchantList(Integer totalType,Long userId,String month) {
        LocalDate now = LocalDate.now();
        List<Integer> times = new ArrayList<>();
        int type;
        if (month.equals("0")){
            type = 2;
            //查询近半年
            //近半年
            for (int i = 0; i < 6; i++) {
                // 计算过去半年每月月份
                LocalDate currentDay = now.minusMonths(i);
                // 将LocalDate转换为字符串
                String currentDateString = LocalDateTimeUtil.format(currentDay, DatePattern.SIMPLE_MONTH_PATTERN);
                times.add(Integer.valueOf(currentDateString));
            }
        }else {
            type = 1;
            //校验时间格式是yyyyMM
            AssertUtil.isyyyyMM(month);
            //判断month是否是本月  否则获取月份中全部日日期
            int year = Integer.parseInt(month.substring(0, 4));
            int monthOfYear = Integer.parseInt(month.substring(4, 6));
            // 判断给定的月份字符串是否表示当前月份
            boolean isCurrentMonth = year == now.getYear() && monthOfYear == now.getMonthValue();
            // 如果是当前月份，则生成本月到今天的日期字符串
            if (isCurrentMonth) {
                LocalDate firstDayOfMonth = now.withDayOfMonth(1);
                for (LocalDate date = firstDayOfMonth; !date.isAfter(now); date = date.plusDays(1)) {
                    times.add(Integer.valueOf(date.format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
                }
            } else {
                // 如果不是当前月份，则生成整个月的日期字符串
                LocalDate firstDayOfMonth = LocalDate.of(year, monthOfYear, 1);
                int daysInMonth = firstDayOfMonth.lengthOfMonth();
                for (int day = 1; day <= daysInMonth; day++) {
                    LocalDate date = firstDayOfMonth.withDayOfMonth(day);
                    times.add(Integer.valueOf(date.format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
                }
            }
        }
        //获取全部激活并构造为TimeVo格式
        ArrayList<TimeVO> timeVOArrayList = getTimeVOArrayList(totalType,userId, times, type);
        return R.ok(timeVOArrayList);
    }

    @Override
    public List<TrendVO> getAddActMchTrend(Long userId, List<Integer> times, Integer dateType, Integer totalType, Map<Integer, KxsBrand> brandMap) {

        List<TrendVO> trendVOList = new ArrayList<>();

        List<TrendTimesVO> trendTimesVOList = baseMapper.getAddActMchTrend(userId, times, dateType, totalType);

        Map<Integer, List<TrendTimesVO>> tradeTrendMap =  trendTimesVOList.stream().collect(Collectors.groupingBy(TrendTimesVO::getTime));

        LinkedHashMap<Integer, List<TrendTimesVO>> tradeTrend = new LinkedHashMap<>();
        for (Integer time : times) {
            if(tradeTrendMap.containsKey(time)){
                tradeTrend.put(time, tradeTrendMap.get(time));
            }else{
                tradeTrend.put(time, new ArrayList<>());
            }
        }

        //全部交易额
        TrendVO trendVO = new TrendVO();
        trendVO.setName("全部");
        LinkedList<Map<String, Object>> allActNum = new LinkedList<>();
        for (Integer date : tradeTrend.keySet()) {
            List<TrendTimesVO> trendTimesList = tradeTrend.get(date);
            //当前月份的所有总和
            int actNum = trendTimesList.stream().mapToInt(TrendTimesVO::getTotal).sum();
            allActNum.addFirst(MapUtil.<String, Object>builder().put("time", date).put("actNum", actNum).build());
        }
        trendVO.setTimes(allActNum);
        trendVOList.add(trendVO);
        //各品牌交易额
        for (Integer brandId : brandMap.keySet()) {
            TrendVO trendBrandVO = new TrendVO();
            trendBrandVO.setName(brandMap.get(brandId).getName());
            LinkedList<Map<String, Object>> brandActNum = new LinkedList<>();
            for (Integer date : tradeTrend.keySet()) {
                List<TrendTimesVO> trendTimesList = tradeTrend.get(date);
                int actNum = trendTimesList.stream().filter(item -> Objects.equals(brandId, item.getBrandId())).mapToInt(TrendTimesVO::getTotal).sum();
                brandActNum.addFirst(MapUtil.<String, Object>builder().put("time", date).put("actNum", actNum).build());
            }
            trendBrandVO.setTimes(brandActNum);
            trendVOList.add(trendBrandVO);
        }
        return trendVOList;
    }

    private ArrayList<TimeVO> getTimeVOArrayList(Integer totalType,Long userId, List<Integer> times, int type) {
        //构造数据
        //将全部激活量  或   品牌激活量  构造进入map  key为品牌id  或  all  或来客吧码牌
        Map<Integer,List<ActivityAddVO>> timeActivityMap = new HashMap<>();
        //查询来客吧码牌激活
        List<TrendTimesVO> trendTimesVOLkbList = lkbActTradeMapper.getActivityStatByLkbList(userId, times, totalType);
        //来客吧码牌不再品牌列表中 同all 需要做特殊处理
        for (TrendTimesVO trendTimesVO : trendTimesVOLkbList) {
            ArrayList<ActivityAddVO> activityAddVOS = new ArrayList<>();
            Integer time = trendTimesVO.getTime();
            Integer total = trendTimesVO.getTotal();
            ActivityAddVO activityAddVO = new ActivityAddVO();
            activityAddVO.setName("来客吧码牌");
            activityAddVO.setTotal(total);
            activityAddVOS.add(activityAddVO);
            //将该来客吧码牌构造成时间为key的map
            timeActivityMap.put(time,activityAddVOS);
        }
        //查询全部激活
        List<TrendTimesVO> trendTimesVOS = baseMapper.getUserActListByDayOrMonth(times, userId,null, type,totalType);
        //遍历全部激活集合  注  该集合全部不包含来客吧码牌
        for (TrendTimesVO trendTimesVO : trendTimesVOS) {
            //先查询map中是否包含有改时间日期的来客吧码牌激活数据
            Integer total = trendTimesVO.getTotal();
            Integer time = trendTimesVO.getTime();
            List<ActivityAddVO> activityAddVOList = timeActivityMap.get(time);
            if (activityAddVOList == null){
                //当前全部的时间点不存在码牌激活数据时,走正常逻辑构造map
                //将全部激活集合全部构造成ActivityAddVO放入hashMap中,
                ArrayList<ActivityAddVO> activityAddVOS = new ArrayList<>();
                ActivityAddVO activityAddVO = new ActivityAddVO();
                activityAddVO.setName("all");
                activityAddVO.setTotal(total);
                activityAddVOS.add(activityAddVO);
                //key为时间,值为其ActivityAddVO本身
                timeActivityMap.put(time,activityAddVOS);
            }else {
                //存在数据时,我们需要将码牌数量添加到总激活中
                for (ActivityAddVO activityAddVO : activityAddVOList) {
                    //激活总量加上码牌激活量
                    total += activityAddVO.getTotal();
                }
                //再将全部激活集合全部构造成ActivityAddVO放入hashMap中,
                ActivityAddVO activityAddVO = new ActivityAddVO();
                activityAddVO.setName("all");
                activityAddVO.setTotal(total);
                //将构造的数据添加到我们从map中拿出的List中
                activityAddVOList.add(activityAddVO);
            }
        }
        //查询激活, 根据品牌分组
        List<TrendTimesVO> trendTimesVOListBrand = baseMapper.getUserActListByDayOrMonth(times, userId, 1, type,totalType);
        //遍历品牌激活
        for (TrendTimesVO trendTimesVO : trendTimesVOListBrand) {
            //查找map获取当前品牌激活统计的时间点
            List<ActivityAddVO> activityAddVOList = timeActivityMap.get(trendTimesVO.getTime());
            //在逻辑上,该activityAddVOList不可能为null,但添加校验防止脏数据导致报错
            if (activityAddVOList != null){
                //将当前品牌的激活数量构造成activityAddVO 添加入map中去
                ActivityAddVO activityAddVO = new ActivityAddVO();
                activityAddVO.setName(trendTimesVO.getBrandId().toString());
                activityAddVO.setTotal(trendTimesVO.getTotal());
                activityAddVOList.add(activityAddVO);
            }
        }

        //此时我们的hashmap格式已为TimeVO类格式
        //将map转换为返回实体类
        ArrayList<TimeVO> timeVOS = new ArrayList<>();
        //根据我们传入的时间进行写入
        for (Integer time : times) {
            List<ActivityAddVO> activityAddVOList = timeActivityMap.get(time);
            //存在数据则开始构造TimeVO
            if (activityAddVOList != null){
                TimeVO timeVO = new TimeVO();
                timeVO.setDate(time);
                timeVO.setActivityAdd(activityAddVOList);
                timeVOS.add(timeVO);
            }else {
                //不存在则填充空数据
                ArrayList<ActivityAddVO> activityAddVOS = new ArrayList<>();
                ActivityAddVO activityAddVO = new ActivityAddVO();
                activityAddVO.setName("all");
                activityAddVO.setTotal(0);
                activityAddVOS.add(activityAddVO);
                TimeVO timeVO = new TimeVO();
                timeVO.setDate(time);
                timeVO.setActivityAdd(activityAddVOS);
                timeVOS.add(timeVO);
            }
        }
        return timeVOS;
    }
}

