package com.xjrsoft.module.base.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.utils.RedisUtil;
import com.xjrsoft.module.base.dto.WhitelistManagementPageDto;
import com.xjrsoft.module.base.entity.TreeNode;
import com.xjrsoft.module.base.entity.WhiteBaseClass;
import com.xjrsoft.module.base.entity.WhiteBaseGrade;
import com.xjrsoft.module.base.entity.WhitelistManagement;
import com.xjrsoft.module.base.mapper.WhitelistManagementMapper;
import com.xjrsoft.module.base.service.IWhitelistManagementService;
import com.xjrsoft.module.base.vo.WhitelistManagementPageVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
* @title: 白名单管理
* @Author brealinxx
* @Date: 2024-06-24
* @Version 1.0
*/
@Slf4j
@Service
@AllArgsConstructor
public class WhitelistManagementServiceImpl extends MPJBaseServiceImpl<WhitelistManagementMapper, WhitelistManagement> implements IWhitelistManagementService {
    private final WhitelistManagementMapper whitelistManagementMapper;

    private RedisUtil redisUtil;

    @Override
    public Page<WhitelistManagementPageVo> getPage(Page<Object> objectPage, WhitelistManagementPageDto dto) {
        return whitelistManagementMapper.getPage(objectPage, dto);
    }

    @Override
    public String GetName(String name) {
        return whitelistManagementMapper.getName(name);
    }

    @Override
    public String GetCredentialNumber(String credentialNumber) {
        return whitelistManagementMapper.getCredentialNumber(credentialNumber);
    }

    @Override
    public String GetPhone(String phone) {
        return whitelistManagementMapper.getPhone(phone);
    }

    @Override
    public Long getUserId(String credentialNumber) {
        return whitelistManagementMapper.getUserId(credentialNumber);
    }

    @Override
    public boolean checkExist(String credentialNumber) {
        return whitelistManagementMapper.checkExits(credentialNumber);
    }

    @Override
    public List<TreeNode> getTreeStructure() {
        List<WhiteBaseGrade> grades = whitelistManagementMapper.getAllGrades();
        List<TreeNode> treeNodes = new ArrayList<>();

        for (WhiteBaseGrade grade : grades) {
            TreeNode gradeNode = new TreeNode();
            gradeNode.setId(grade.getId());
            gradeNode.setName(grade.getName());

            List<WhiteBaseClass> classes = whitelistManagementMapper.getClassesByGradeId(grade.getId());
            List<TreeNode> classNodes = new ArrayList<>();

            for (WhiteBaseClass clazz : classes) {
                TreeNode classNode = new TreeNode();
                classNode.setId(clazz.getId());
                classNode.setName(clazz.getName());
                classNodes.add(classNode);
            }

            gradeNode.setChildren(classNodes);
            treeNodes.add(gradeNode);
        }

        return treeNodes;
    }

    /**
     * 所有学生电信开卡用户缓存
     */
    @Async
    public void loadCaches() {
        log.info("XJRSOFT: 加载所有学生电信开卡用户缓存开始");
        List<WhitelistManagement> list = whitelistManagementMapper.selectList(Wrappers.<WhitelistManagement>query().lambda().select(WhitelistManagement::getUserId));
        Map<Long, Long> map = list.stream().collect(Collectors.toMap(WhitelistManagement::getUserId, WhitelistManagement::getUserId));
        redisUtil.set(GlobalConstant.WHITE_MANAGEMENT_CACHE_KEY, map);
        log.info("XJRSOFT: 加载所有学生电信开卡用户缓存结束");
    }

    @Override
    public List<Map<Integer, Object>> importData(List<Map<Integer, Object>> savedDataList) {
        List<Map<Integer, Object>> errorList = new ArrayList<>();

        List<WhitelistManagement> whitelistManagements = new ArrayList<>();
        List<String> errorLogs = new ArrayList<>();

        for (Map<Integer, Object> vo : savedDataList) {
            if(vo.get(0) == null || vo.get(1) == null || vo.get(2) == null){
                errorList.add(vo);
                continue;
            }
            if (this.checkExist(vo.get(1).toString())) {
                continue;
            }

            String name = vo.get(0).toString();
            String credentialNumber = vo.get(1).toString();
            Long userId = this.getUserId(credentialNumber);
            String phone = vo.get(2).toString();

            if (!name.isEmpty() && !credentialNumber.isEmpty() && !phone.isEmpty()) {
                WhitelistManagement whitelistManagement = new WhitelistManagement();
                whitelistManagement.setCreateDate(new Date());
                whitelistManagement.setDeleteMark(0);
                whitelistManagement.setEnabledMark(0);
                whitelistManagement.setUserId(userId);
                whitelistManagement.setName(name);
                whitelistManagement.setCredentialNumber(credentialNumber);
                whitelistManagement.setPhone(phone);
                whitelistManagements.add(whitelistManagement);
            }
        }

        Boolean result = this.saveBatch(whitelistManagements);
        if(result){
            CompletableFuture.runAsync(() -> {
                this.loadCaches();
            });
        }
        if (!errorLogs.isEmpty()) {
            String detailedMessage = String.format("[导入完成但存在问题（检查输入的是否正确且存在，输入错误可能返回 null）] ", String.join("; ", errorLogs));
            throw new MyException(detailedMessage);
        }

        return errorList;
    }
}