package com.ruoyi.frequency.workstype.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.DictConstant;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.controller.req.StorePageReq;
import com.ruoyi.controller.resp.StorePageResp;
import com.ruoyi.enums.user.UserEnums;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.works.service.WorksService;
import com.ruoyi.frequency.workstype.entity.WorksType;
import com.ruoyi.frequency.workstype.mapper.WorksTypeMapper;
import com.ruoyi.frequency.workstype.service.WorksTypeService;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.BusinessUtil;
import com.ruoyi.vo.UserInfo;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

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

/**
 * 作品类型Service业务层处理
 *
 * @author zj
 * @date 2023-09-22
 */
@Service
public class WorksTypeServiceImpl extends ServiceImpl<WorksTypeMapper, WorksType> implements WorksTypeService {
    @Autowired
    private WorksTypeMapper worksTypeMapper;

    /**
     * 查询作品类型
     *
     * @param id 作品类型主键
     * @return 作品类型
     */
    @Override
    public WorksType selectWorksTypeById(Long id) {
        return worksTypeMapper.selectWorksTypeById(id);
    }

    /**
     * 查询作品类型列表
     *
     * @param worksType 作品类型
     * @return 作品类型
     */
    @Override
    public List<WorksType> selectWorksTypeList(WorksType worksType) {
        List<WorksType> worksTypes = worksTypeMapper.selectWorksTypeList(worksType);

        if (worksTypes.size() > 0) {
            Map<Long, List<WorksType>> workTypeMap = getWorkTypeMap();
            worksTypes.forEach(s -> {
                s.setChildList(getChildList(workTypeMap, s.getId()));
            });
        }

        return worksTypes;
    }

    /**
     * 新增作品类型
     *
     * @param worksType 作品类型
     * @return 结果
     */
    @Override
    public int insertWorksType(WorksType worksType) {

//        checkParam(worksType,false);

        if (ObjectUtil.isEmpty(worksType.getPid()) || worksType.getPid() == 0L) {
            worksType.setPid(0L);
            worksType.setLevel(1);
        } else {
            WorksType parent = worksTypeMapper.selectById(worksType.getPid());
            worksType.setLevel(parent.getLevel() + 1);
        }

        return worksTypeMapper.insert(worksType);
    }

    /**
     * 校验参数，检查是否存在重复的编码或者名称，
     *
     * @param worksType
     * @param isUpdate  是否排除当前添加的这条记录
     */
    private void checkParam(WorksType worksType, boolean isUpdate) {

        //编码不能为空
        if (StringUtils.isEmpty(worksType.getCode())) {
            throw new ServiceException("编码不能为空");
        }

        WorksType worksTypeExist = new WorksType();
        worksTypeExist.setCode(worksType.getCode());
        if (isUpdate) {
            worksTypeExist.setCode(worksType.getCode());
        }
        List<WorksType> list = worksTypeMapper.selectWorksTypeList(worksTypeExist);
        if (list != null && list.size() > 0) {
            throw new ServiceException("字典编码重复");
        }
    }

    /**
     * 修改作品类型
     *
     * @param worksType 作品类型
     * @return 结果
     */
    @Override
    public int updateWorksType(WorksType worksType) {

//        checkParam(worksType,true);

        if (ObjectUtil.isEmpty(worksType.getPid()) || worksType.getPid() == 0L) {
            worksType.setPid(0L);
            worksType.setLevel(1);
        } else {
            WorksType parent = worksTypeMapper.selectById(worksType.getPid());
            worksType.setLevel(parent.getLevel() + 1);
        }

        worksType.setUpdateData();
        return worksTypeMapper.updateById(worksType);
    }

    @Autowired
    private WorksService worksService;

    /**
     * 批量删除作品类型
     *
     * @param ids 需要删除的作品类型主键
     * @return 结果
     */
    @Override
    public int deleteWorksTypeByIds(Long[] ids, Integer delFlag) {
        this.lambdaUpdate().set(WorksType::getDelFlag, delFlag).in(WorksType::getId, ids).update();
        return ids.length;
    }

    /**
     * 删除作品类型信息
     *
     * @param id 作品类型主键
     * @return 结果
     */
    @Override
    public int deleteWorksTypeById(Long id) {
        return worksTypeMapper.deleteWorksTypeById(id);
    }

    @Override
    public AjaxResult twoLevelList() {
        //查询分类
        Map<Long, List<WorksType>> map = getWorkTypeMap();

        List<WorksType> worksTypes = map.get(0L);

        if (worksTypes != null) {
            worksTypes.stream().forEach(s -> {
                s.setChildList(map.get(s.getId()));
            });
        }
        return AjaxResult.success(worksTypes);
    }


    @Override
    public List<WorksType> worksTypeList() {
        //查询分类
        Map<Long, List<WorksType>> map = getWorkTypeMap();

        List<WorksType> worksTypes = map.get(0L);

        List<WorksType> worksTypeList = new ArrayList<>();

        worksTypes.stream().forEach(s -> {
            List<WorksType> typeList = map.get(s.getId());
            if (typeList == null || typeList.size() == 0) {
                return;
            }
            s.setChildList(typeList);
            worksTypeList.add(s);
        });

        return worksTypeList;
    }

    @Override
    public List<Long> getIdsByTypeId(Long typeId) {

        //查询分类
        Map<Long, List<WorksType>> map = getWorkTypeMap();

        List<Long> ids = new ArrayList<>();

        WorksType worksType = this.getById(typeId);

        if (worksType.getLevel() == 2) {
            ids.add(typeId);
            return ids;
        }

        return getThreeIdList(map, typeId, ids);
    }

    @Autowired
    private BusinessUtil businessUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisService redisService;

    @Override
    public ResponseData<PageResult<Page<StorePageResp>>> storePage(StorePageReq req, UserVo userVo) {


        //筛去拉黑与被拉黑用户
        List<UserVo> blockUserList = userService.blockUserList(userVo);
        req.setBlockUserList(blockUserList);

        //筛去屏蔽用户
        List<UserVo> shieldUserList = userService.shieldUserList(userVo);
        req.setShieldUserList(shieldUserList);

        if (req.getType() == 1) {
            //拼接排序
            List<SysDictData> dictList = businessUtil.getDictList(DictConstant.技术列表排序权重);

            dictList = dictList.stream().sorted(Comparator.comparing(SysDictData::getDictValue)).collect(Collectors.toList());

            String sortSql = "";

            if (dictList != null && dictList.size() > 0) {

                for (SysDictData dictData : dictList) {
                    if (dictData.getCode().equals(DictConstant.TechnologySort.在线时长)) {
                        sortSql = sortSql.concat(" tt.online_duration DESC,");
                    } else if (dictData.getCode().equals(DictConstant.TechnologySort.订单数量)) {
                        sortSql = sortSql.concat(" tt.orderNum DESC,");
                    } else if (dictData.getCode().equals(DictConstant.TechnologySort.订单金额)) {
                        sortSql = sortSql.concat(" tt.orderAmount DESC,");
                    } else if (dictData.getCode().equals(DictConstant.TechnologySort.好评率)) {
                        sortSql = sortSql.concat(" tt.star DESC");
                    }
                }
                req.setSortSql(sortSql);
            }
        }

        //从业年限筛选
        if (ObjectUtil.isNotEmpty(req.getYearRange())) {
            String[] split = req.getYearRange().split("-");
            if (split.length == 1) {
                req.setMaxYear(Integer.valueOf(split[0]));
            }
            if (split.length == 2) {
                req.setMinYear(Integer.valueOf(split[0]));
                req.setMaxYear(Integer.valueOf(split[1]));
            }
        }

        //在线状态筛选;1:在线,2离线
        if (ObjectUtil.isNotEmpty(req.getOnlineStatus())) {

            Integer userType = 2;
            if (req.getIsWorkingDrawing() == 2) {
                userType = 4;
            }
            //上次调用此接口的时间
            String last_time_map_key = "last_time_" + userType;

            List<Long> userIds = new ArrayList<>();

            if (redisTemplate.hasKey(last_time_map_key)) {

                Map<String, Object> cacheMap = redisService.getCacheMap(last_time_map_key);

                cacheMap.forEach((key, value) -> {

                    long lastTimes = Long.valueOf(value.toString());

                    if (System.currentTimeMillis() - lastTimes < (6 * 60 * 1000)) {
                        userIds.add(Long.valueOf(key));
                    }
                });

                //userIds为空 直接返回
                if (userIds.size() == 0) {
                    if (ObjectUtil.equal(1, req.getOnlineStatus())) {
                        return ResponseData.success(new PageResult<>(new Page<>(req.getPageNo(), req.getPageSize())));
                    } else {
                        req.setOnlineStatus(null);
                    }
                } else {
                    req.setUserIds(userIds);
                }

            } else {
                if (ObjectUtil.equal(1, req.getOnlineStatus())) {
                    return ResponseData.success(new PageResult<>(new Page<>(req.getPageNo(), req.getPageSize())));
                } else {
                    req.setOnlineStatus(null);
                }
            }


        }


        Page<StorePageResp> page = worksTypeMapper.storePage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);

        if (!page.getRecords().isEmpty()) {

            //累计服务金额基数
            BigDecimal orderAmount = new BigDecimal(businessUtil.getDict(DictConstant.OrderDict.累计服务金额基数).getDictValue());

            //当月服务单数基数
            Integer orderMonthNum = Integer.valueOf(businessUtil.getDict(DictConstant.OrderDict.当月服务单数基数).getDictValue());

            //累计服务单数基数
            Integer orderNum = Integer.valueOf(businessUtil.getDict(DictConstant.OrderDict.累计服务单数基数).getDictValue());

            Integer userType = 2;
            if (req.getIsWorkingDrawing() == 2) {
                userType = 4;
            }
            //上次调用此接口的时间
            String last_time_map_key = "last_time_" + userType;

            //用户id
            Set<UserVo> userVoSet = page.getRecords().stream().map(s -> new UserVo(s.getUserType(), s.getId())).collect(Collectors.toSet());

            //获取用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            page.getRecords().stream().forEach(s -> {

                //获取在线状态
                Integer onlineStatus = businessUtil.getOnlineStatus(req.getIsWorkingDrawing() == 2 ? s.getBindEnterpriseId() : s.getId(), last_time_map_key);
                s.setOnlineStatus(onlineStatus);

                if (req.getIsWorkingDrawing() == 2) {
                    s.setUserType(UserEnums.enterprise.getCode());
                }

                //isWorkingDrawing 是否是企业: 1不是 2是
                if (req.getIsWorkingDrawing() == 1) {
                    //累计服务金额基数
                    s.setOrderAmount(orderAmount.add(s.getOrderAmount()));

                    //当月服务单数基数
                    s.setOrderMonthNum(orderMonthNum + s.getOrderMonthNum());

                    //累计服务单数基数
                    s.setOrderNum(orderNum + s.getOrderNum());
                }
                s.setUserInfo(userMap.get(new UserVo(s.getUserType(), s.getId())));
            });
        }

        return ResponseData.success(new PageResult<>(page));
    }


    private Map<Long, List<WorksType>> getWorkTypeMap() {
        List<WorksType> list = this.list(new QueryWrapper<WorksType>().lambda()
                .eq(WorksType::getDelFlag, PublicCommon.启用)
                .orderByAsc(WorksType::getSort)
        );

        Map<Long, List<WorksType>> map = new HashMap<>();

        list.stream().forEach(worksType -> {
            if (!map.containsKey(worksType.getPid())) {
                map.put(worksType.getPid(), new ArrayList<>());
            }
            map.get(worksType.getPid()).add(worksType);
        });
        return map;
    }

    private List<WorksType> getChildList(Map<Long, List<WorksType>> map, Long pid) {

        if (!map.containsKey(pid)) {
            return new ArrayList<>();
        }

        List<WorksType> worksTypes = map.get(pid);

        worksTypes.stream().forEach(worksType -> {
            List<WorksType> list = map.get(worksType.getId());
            worksType.setChildList(list);
        });

        return worksTypes;
    }


    private List<Long> getThreeIdList(Map<Long, List<WorksType>> map, Long pid, List<Long> ids) {

        if (!map.containsKey(pid)) {
            return ids;
        }

        List<WorksType> worksTypes = map.get(pid);

        worksTypes.stream().forEach(worksType -> {
            if (worksType.getLevel() == 2) {
                ids.add(worksType.getId());
            } else {
                getThreeIdList(map, worksType.getId(), ids);
            }
        });

        return ids;
    }
}
