package shop.alien.store.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import shop.alien.entity.store.*;
import shop.alien.entity.store.vo.ExpertGoodsTypeVo;
import shop.alien.entity.store.vo.LifeUserExpertOrderVo;
import shop.alien.entity.store.vo.LifeUserExpertVo;
import shop.alien.mapper.LifeNoticeMapper;
import shop.alien.mapper.LifeUserExpertMapper;
import shop.alien.mapper.LifeUserExpertOrderMapper;
import shop.alien.mapper.LifeUserExpertWorksMapper;
import shop.alien.store.service.LifeUserExpertOrderService;
import shop.alien.store.service.LifeUserExpertService;
import shop.alien.util.type.LifeNoticeUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户达人表 服务实现类
 * </p>
 *
 * @author ssk
 * @since 2025-02-19
 */
@Service
@RequiredArgsConstructor
public class LifeUserExpertServiceImpl extends ServiceImpl<LifeUserExpertMapper, LifeUserExpert> implements LifeUserExpertService {

    private final LifeUserExpertMapper lifeUserExpertMapper;

    private final LifeUserExpertWorksMapper lifeUserExpertWorksMapper;
    private final LifeUserExpertOrderService lifeUserExpertOrderService;
    private final LifeUserExpertOrderMapper lifeUserExpertOrderMapper;
    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;

    @Override
    public IPage<LifeUserExpertVo> getUserExpertList(int page, int size, String userName, String expertCode, Integer userId) {
        QueryWrapper<LifeUserExpertVo> wrapper = new QueryWrapper<>();
        wrapper.eq("expert.delete_flag", 0);
        wrapper.eq("user.delete_flag", 0);
        wrapper.eq(userId != null, "user.id", userId);
        wrapper.like(StringUtils.isNotEmpty(userName), "user.user_name", userName);
        wrapper.like(StringUtils.isNotEmpty(expertCode), "expert.expert_code", expertCode);
        wrapper.orderByDesc("accountMoney");
        return lifeUserExpertMapper.getUserExpertList(new Page<>(page, size), wrapper);
    }

    @Override
    public IPage<LifeUserExpertOrderVo> getExpertOrderList(int page, int size, Integer expertId, String orderNo, String storeName, Integer storeId) {
        QueryWrapper<LifeUserExpertOrderVo> wrapper = new QueryWrapper<>();
        wrapper.eq("orders.delete_flag", 0);
        wrapper.like(expertId != null, "orders.expert_id", expertId);
        wrapper.like(StringUtils.isNotEmpty(orderNo), "orders.orderNo", orderNo);
        wrapper.like(StringUtils.isNotEmpty(storeName), "store.store_name", storeName);
        wrapper.eq(storeId != null && storeId != 0, "store.id", storeId);
        wrapper.orderByDesc("actualPlayCount");
//        wrapper.orderByDesc("actual_gmv");
        return lifeUserExpertMapper.getExpertOrderList(new Page<>(page, size), wrapper);
    }

    @Override
    public boolean becomeExpert(Integer id, String userPhone ,String comment ,Integer expertStatus) {
        LambdaQueryWrapper<LifeUserExpert> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LifeUserExpert::getId, id);
        wrapper.eq(LifeUserExpert::getDeleteFlag, 1);
        LifeUserExpert lifeUserExpert = lifeUserExpertMapper.selectIsExpert(id);
        if (lifeUserExpert != null) {
            lifeUserExpert.setDeleteFlag(0);
            lifeUserExpert.setExpertStatus(expertStatus);
            return lifeUserExpertMapper.updateExpert(lifeUserExpert);
        }
        LifeUserExpert expert = new LifeUserExpert();
        expert.setId(id);
        expert.setExpertStatus(expertStatus);
        if (expertStatus == 0){
            expert.setExpertCode(setExpertCode());
        } else if(expertStatus == 2){
            expert.setExpertCode(null);
            expert.setDeleteFlag(1);
        }
        LifeNotice lifeMessage = new LifeNotice();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDate = LocalDateTime.now().format(formatter);
        if (expertStatus == 0){
            String text = "您在"+formattedDate+"提交的信息已经通过审核。恭喜您成为达人。";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("message", text);
            lifeMessage.setReceiverId("user_"+userPhone);
            lifeMessage.setTitle("审核通过通知");
            lifeMessage.setContext(jsonObject.toJSONString());
            lifeMessage.setNoticeType(1);
            lifeMessage.setIsRead(0);
            lifeMessage.setDeleteFlag(0);
            lifeMessage.setSenderId("system");
            lifeNoticeUtil.fillUserTypeAndRefId(lifeMessage);
            lifeNoticeMapper.insert(lifeMessage);
        } else if (expertStatus == 2) {
            String text = "您在"+formattedDate+"提交的信息未通过审核，拒绝原因："+comment+"。请您重新填写信息后再次提交至平台审核。";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("message", text);
            lifeMessage.setReceiverId("user_"+userPhone);
            lifeMessage.setTitle("审核失败通知");
            lifeMessage.setContext(jsonObject.toJSONString());
            lifeMessage.setNoticeType(1);
            lifeMessage.setIsRead(0);
            lifeMessage.setDeleteFlag(0);
            lifeMessage.setSenderId("system");
            lifeNoticeUtil.fillUserTypeAndRefId(lifeMessage);
            lifeNoticeMapper.insert(lifeMessage);
        }
        return lifeUserExpertMapper.updateExpert(expert);
    }

    public Integer setExpertCode() {
        Random random = new Random();
        // 生成 10000000 到 99999999 之间的随机数
        int number = 10000000 + random.nextInt(90000000);
        boolean isHave = true;
        while (isHave) {
            LifeUserExpert lifeUserExpert = this.getOne(new LambdaQueryWrapper<LifeUserExpert>().eq(LifeUserExpert::getExpertCode, number));
            if (lifeUserExpert == null) {
                isHave = false;
            } else {
                number = 10000000 + random.nextInt(90000000);
            }
        }
        return number;
    }

    @Override
    public boolean cancelExpert(Integer id) {
        LambdaQueryWrapper<LifeUserExpertOrder> expertOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        expertOrderLambdaQueryWrapper.eq(LifeUserExpertOrder::getExpertId, id);
        List<LifeUserExpertOrder> lifeUserExpertOrders = lifeUserExpertOrderMapper.selectList(expertOrderLambdaQueryWrapper);
        for (LifeUserExpertOrder lifeUserExpertOrder : lifeUserExpertOrders) {
            lifeUserExpertOrder.setDeleteFlag(1);
            lifeUserExpertOrderMapper.updateById(lifeUserExpertOrder);
        }
        return this.removeById(id);
    }

    @Override
    public LifeUserExpertVo getPercentageInfo() {
        List<LifeUserExpertVo> expertInfoList = lifeUserExpertMapper.getExpertInfoList();

        // 省---------------------------------------------------------------------------------------------------------------------------------------------
        List<Map<String, String>> provincePercentage = new ArrayList<>();
        List<LifeUserExpertVo> provinceList = expertInfoList.stream().filter(item -> StringUtils.isNotEmpty(item.getProvince())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(provinceList)) {
            Map<String, Double> provincePercentageMap = provinceList.stream()
                    .collect(Collectors.groupingBy(LifeUserExpertVo::getProvince, Collectors.collectingAndThen(
                            Collectors.counting(), // 统计每个省份的数量
                            count -> (double) count / provinceList.size() * 100 // 计算占比
                    )));

            // 按占比排序
            List<Map.Entry<String, Double>> provincePercentageList = provincePercentageMap.entrySet().stream()
                    .sorted(Map.Entry.<String, Double>comparingByValue().reversed()) // 按占比降序排序
                    .collect(Collectors.toList());

            // 转化为map
            provincePercentage = provincePercentageList.stream()
                    .map(entry -> {
                        Map<String, String> map = new HashMap<>();
                        map.put("province", entry.getKey());
                        map.put("percentage", String.valueOf(entry.getValue()));
                        return map;
                    })
                    .collect(Collectors.toList());
        }
        // 省---------------------------------------------------------------------------------------------------------------------------------------------

        // 市---------------------------------------------------------------------------------------------------------------------------------------------
        List<Map<String, String>> cityPercentage = new ArrayList<>();
        List<LifeUserExpertVo> cityList = expertInfoList.stream().filter(item -> StringUtils.isNotEmpty(item.getCity())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(cityList)) {
            Map<String, Double> cityPercentageMap = cityList.stream()
                    .collect(Collectors.groupingBy(LifeUserExpertVo::getCity, Collectors.collectingAndThen(
                            Collectors.counting(), // 统计每个市的数量
                            count -> (double) count / cityList.size() * 100 // 计算占比
                    )));

            // 按占比排序
            List<Map.Entry<String, Double>> cityPercentageList = cityPercentageMap.entrySet().stream()
                    .sorted(Map.Entry.<String, Double>comparingByValue().reversed()) // 按占比降序排序
                    .collect(Collectors.toList());

            // 转化为map
            cityPercentage = cityPercentageList.stream()
                    .map(entry -> {
                        Map<String, String> map = new HashMap<>();
                        map.put("city", entry.getKey());
                        map.put("percentage", String.valueOf(entry.getValue()));
                        return map;
                    })
                    .collect(Collectors.toList());
        }
        // 市---------------------------------------------------------------------------------------------------------------------------------------------

        // 年龄--------------------------------------------------------------------------------------------------------------------------------------------
        Map<String, Double> agePercentageMap = new HashMap<>();
        List<LifeUserExpertVo> ageInfoList = expertInfoList.stream().filter(item -> null != item.getUserBrithday()).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(ageInfoList)) {
            List<String> ageList = ageInfoList.stream().map(item -> {
                LocalDate brithDay = item.getUserBrithday().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                Period period = Period.between(brithDay, LocalDate.now());
                String flag = "";
                if (period.getYears() < 12) {
                    flag = "12以下";
                } else if (period.getYears() < 23) {
                    flag = "12-22";
                } else if (period.getYears() < 33) {
                    flag = "23-32";
                } else if (period.getYears() < 43) {
                    flag = "33-42";
                } else if (period.getYears() < 53) {
                    flag = "43-52";
                } else {
                    flag = "53以上";
                }
                return flag;
            }).collect(Collectors.toList());

            agePercentageMap = ageList.stream()
                    .collect(Collectors.groupingBy(String::toString, Collectors.collectingAndThen(
                            Collectors.counting(),
                            count -> (double) count / ageList.size() * 100 // 计算占比
                    )));
        }

        // 转化为map
        List<String> ageFlagList = Arrays.asList("12以下", "12-22", "23-32", "33-42", "43-52", "53以上");
        List<Map<String, String>> agePercentage = new ArrayList<>();
        for (String flag : ageFlagList) {
            Map<String, String> map = new HashMap<>();
            map.put("age", flag);
            map.put("percentage", String.valueOf(agePercentageMap.getOrDefault(flag, 0.0)));
            agePercentage.add(map);
        }
        // 年龄--------------------------------------------------------------------------------------------------------------------------------------------

        // 性别--------------------------------------------------------------------------------------------------------------------------------------------
        double manPercentage = 0;
        List<LifeUserExpertVo> sexList = expertInfoList.stream().filter(item -> StringUtils.isNotEmpty(item.getUserSex())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(sexList)) {
            double manCount = (double) sexList.stream().filter(item -> "男".equals(item.getUserSex())).count();
            manPercentage = manCount / sexList.size() * 100; // 计算占比
        }

        List<Map<String, String>> sexPercentage = new ArrayList<>();
        Map<String, String> manMap = new HashMap<>();
        manMap.put("sex", "男");
        manMap.put("percentage", String.valueOf(manPercentage));
        sexPercentage.add(manMap);
        Map<String, String> womanMap = new HashMap<>();
        womanMap.put("sex", "女");
        womanMap.put("percentage", CollectionUtils.isNotEmpty(sexList) ? String.valueOf(100 - manPercentage) : "0");
        sexPercentage.add(womanMap);
        // 性别--------------------------------------------------------------------------------------------------------------------------------------------

        LifeUserExpertVo expertVo = new LifeUserExpertVo();
        expertVo.setProvincePercentageList(provincePercentage);
        expertVo.setCityPercentageList(cityPercentage);
        expertVo.setAgePercentageList(agePercentage);
        expertVo.setSexPercentageList(sexPercentage);
        return expertVo;
    }

    @Override
    public LifeUserExpertVo getWorksInfo(Integer expertId) {
        LifeUserExpertVo expertVo = new LifeUserExpertVo();
        LambdaQueryWrapper<LifeUserExpertWorks> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LifeUserExpertWorks::getExpertId, expertId);
        List<LifeUserExpertWorks> worksList = lifeUserExpertWorksMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(worksList)) {
            // 处理播放量，将可能的null转换为0
            int playCount = worksList.stream()
                    .map(LifeUserExpertWorks::getPlayCount)
                    .mapToInt(p -> p == null ? 0 : p)
                    .sum();
            // 处理点赞量，将可能的null转换为0
            int likeCount = worksList.stream()
                    .map(LifeUserExpertWorks::getLikeCount)
                    .mapToInt(l -> l == null ? 0 : l)
                    .sum();
            // 处理评论量，将可能的null转换为0
            int commentCount = worksList.stream()
                    .map(LifeUserExpertWorks::getCommentCount)
                    .mapToInt(c -> c == null ? 0 : c)
                    .sum();
            // 处理分享量，将可能的null转换为0
            int shareCount = worksList.stream()
                    .map(LifeUserExpertWorks::getShareCount)
                    .mapToInt(s -> s == null ? 0 : s)
                    .sum();
            expertVo.setAveragePlayNum(new BigDecimal(playCount).divide(new BigDecimal(worksList.size()), 0, RoundingMode.HALF_UP).intValue());
            expertVo.setAverageLikeNum(new BigDecimal(likeCount).divide(new BigDecimal(worksList.size()), 0, RoundingMode.HALF_UP).intValue());
            expertVo.setAverageCommentCount(new BigDecimal(commentCount).divide(new BigDecimal(worksList.size()), 0, RoundingMode.HALF_UP).intValue());
            expertVo.setAverageShareCount(new BigDecimal(shareCount).divide(new BigDecimal(worksList.size()), 0, RoundingMode.HALF_UP).intValue());
        }
        return expertVo;
    }

    @Override
    public List<LifeUserExpertOrderVo> getCooperateStore(Integer expertId) {
        return lifeUserExpertMapper.getCooperateStore(expertId);
    }

    /**
     * 优势带货品类
     *
     * @param expertId 达人id
     * @return List<Map < String, Object>>
     */
    @Override
    public List<ExpertGoodsTypeVo> greatGoodsType(Integer expertId) {
        List<ExpertGoodsTypeVo> expertGoodsTypeVoList = lifeUserExpertMapper.greatGoodsType(expertId);
        Integer allCount = 0;
        for (ExpertGoodsTypeVo expertGoodsTypeVo : expertGoodsTypeVoList) {
            allCount += expertGoodsTypeVo.getTypeCount();
        }
        for (ExpertGoodsTypeVo expertGoodsTypeVo : expertGoodsTypeVoList) {
            BigDecimal oneCount = BigDecimal.valueOf(expertGoodsTypeVo.getTypeCount());
            BigDecimal allCountBigDecimal = BigDecimal.valueOf(allCount);
            BigDecimal percent = oneCount.divide(BigDecimal.valueOf(allCount), 2, RoundingMode.HALF_UP);
            expertGoodsTypeVo.setPercent(percent.multiply(BigDecimal.valueOf(100)) + "%");
        }
        return expertGoodsTypeVoList.stream()
                .sorted(Comparator.comparing(ExpertGoodsTypeVo::getTypeCount).reversed())
                .collect(Collectors.toList());
    }

    @Override
    public IPage<LifeUserExpertVo> getApplicationExpertList(int page, int size, String userName, String expertCode, Integer userId) {
        QueryWrapper<LifeUserExpertVo> wrapper = new QueryWrapper<>();
        wrapper.eq("expert.delete_flag", 0);
        wrapper.eq("user.delete_flag", 0);
        wrapper.eq(userId != null, "user.id", userId);
        wrapper.eq( "expert.expert_status", 1);
        wrapper.like(StringUtils.isNotEmpty(userName), "user.user_name", userName);
        wrapper.like(StringUtils.isNotEmpty(expertCode), "expert.expert_code", expertCode);
        wrapper.orderByDesc("accountMoney");
        return lifeUserExpertMapper.getApplicationExpertList(new Page<>(page, size), wrapper);
    }

}
