package com.testor.module.train.project.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.dict.data.controller.SysDictDataController;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataResponse;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.biz.sys.user.service.SysUserService;
import com.testor.common.core.utils.StringUtils;
import com.testor.common.util.DateUtil;
import com.testor.module.aptitude.model.domain.TPersonAptitude;
import com.testor.module.aptitude.service.TPersonAptitudeService;
import com.testor.module.notice.service.TSysFileService;
import com.testor.module.sys.model.domian.NewSysOrg;
import com.testor.module.sys.service.NewSysOrgService;
import com.testor.module.train.course.dao.TTrainSmallNodeDao;
import com.testor.module.train.course.model.domain.TTrainSection;
import com.testor.module.train.course.model.domain.TTrainSmallNode;
import com.testor.module.train.course.service.TTrainSectionService;
import com.testor.module.train.myManagement.dao.TTrainMyManagementDao;
import com.testor.module.train.myManagement.model.domain.TTrainMyManagementRead;
import com.testor.module.train.myManagement.model.dto.TTrainMyManagementParam;
import com.testor.module.train.myManagement.model.dto.TrainMyManagementStatVo;
import com.testor.module.train.myManagement.service.TTrainMyManagementReadService;
import com.testor.module.train.project.dao.ProfessionalIndicatorScoreDao;
import com.testor.module.train.project.dao.TTrainProjectDao;
import com.testor.module.train.project.model.domain.ProfessionalIndicatorScore;
import com.testor.module.train.project.model.enums.ProfessionalIndicatorScoreEnum;
import com.testor.module.train.project.model.stat.*;
import com.testor.module.train.project.service.ProfessionalIndicatorScoreService;
import com.testor.module.train.project.service.TrainProjectUserService;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author caq
 * @date 2024/9/7
 * @description 个人培训档案
 */
@Service
public class TrainProjectUserServiceImpl implements TrainProjectUserService {

    @Autowired
    private ProfessionalIndicatorScoreDao professionalIndicatorScoreDao;
    @Autowired
    private TTrainMyManagementDao trainMyManagementDao;
    @Autowired
    private TTrainSmallNodeDao tTrainSmallNodeDao;
    @Autowired
    private TTrainProjectDao tTrainProjectDao;

    @Autowired
    private NewSysOrgService newSysOrgService;
    @Autowired
    private SysDictDataController sysDictDataController;
    @Autowired
    private TTrainMyManagementReadService tTrainMyManagementReadService;
    @Autowired
    private TTrainSectionService tTrainSectionService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TPersonAptitudeService tPersonAptitudeService;
    @Autowired
    private TSysFileService tSysFileService;
    @Autowired
    private ProfessionalIndicatorScoreService professionalIndicatorScoreService;


    @Override
    public Map<String, List<JSONObject>> professionalIndicatorScoreSelect() {
        Map<String, List<JSONObject>> groupedEnums = new HashMap<>();

        for (ProfessionalIndicatorScoreEnum enumValue : ProfessionalIndicatorScoreEnum.values()) {

            String category = enumValue.getType();
            groupedEnums.putIfAbsent(category, new ArrayList<>());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("name", enumValue.getName());
            jsonObject.put("code", enumValue.getCode());
            jsonObject.put("score", enumValue.getScore());
            groupedEnums.get(category).add(jsonObject);
        }

        return groupedEnums;
    }

    @Override
    public BaseResponseList<TrainProjectUserListVo> findProjectUserPageList(TrainProjectUserPara para) {
        List<String> orgIdList = para.getOrgIdList();
        if (CollectionUtils.isEmpty(orgIdList)) {
            List<NewSysOrg> sysOrgList = newSysOrgService.getChildrenById(para.getOrgId());
            orgIdList = sysOrgList.stream().map(NewSysOrg::getOrgId).collect(Collectors.toList());
        }

        List<String> userIdList = findUserIdList(orgIdList);

        Page<ProfessionalIndicatorScore> resultPage = new Page<>(Integer.parseInt(para.getPage()), Integer.parseInt(para.getLimit()));
        IPage<TrainProjectUserListVo> page = professionalIndicatorScoreDao.findProjectUserPageList(resultPage, para, userIdList);
        BaseResponseList<TrainProjectUserListVo> responseList = new BaseResponseList<>();
        responseList.setTotal(page.getTotal());
        List<TrainProjectUserListVo> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return responseList;
        }
        for (TrainProjectUserListVo record : records) {
            NewSysOrg sysOrg = newSysOrgService.getById(record.getDeptId());
            if (ObjectHelper.isNotEmpty(sysOrg)) {
                record.setDeptName(sysOrg.getOrgName());
            }
            SysDictDataResponse materials2 = sysDictDataController.getDictTypeDetail("", "EXAM_TYPE", record.getUserTypeCode()).getData();
            if (ObjectHelper.isNotEmpty(materials2)) {
                String dictValue = materials2.getDictValue();
                record.setUserTypeName(dictValue);
            }
        }
        responseList.setData(records);
        return responseList;
    }

    private List<String> findUserIdList(List<String> orgIdList) {
        if (CollectionUtils.isEmpty(orgIdList)) {
            return new ArrayList<>();
        }
        //通过组织结构id查询所有下级组织结构的用户
        List<SysUser> list = sysUserService.lambdaQuery().in(SysUser::getOrgId, orgIdList).list();
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<String> loginNameList = list.stream().map(SysUser::getLoginName).collect(Collectors.toList());
        List<SysUser> sysUserList = sysUserService.lambdaQuery().in(SysUser::getLoginName, loginNameList).list();
        return sysUserList.stream().map(SysUser::getUserId).collect(Collectors.toList());
    }


    @Override
    public TrainProjectUserStat findProjectUserStat(String userId) {
        SysUser sysUser = sysUserService.getById(userId);
        String loginName = sysUser.getLoginName();

        //完成数
        AtomicInteger countComplicated = new AtomicInteger(0);
        int total = 0;
        List<TrainMyManagementStatVo> voList = trainMyManagementDao.findStateCourseByUserId(loginName);
        long trainTimeSum = 0L;
        if (CollectionUtils.isNotEmpty(voList)) {
            total = voList.size();
            for (TrainMyManagementStatVo item : voList) {
                LocalDateTime visitStartTime = DateUtil.dateToLocalDateTime(item.getVisitStartTime());
                LocalDateTime visitEndTime = DateUtil.dateToLocalDateTime(item.getVisitEndTime());
                Duration duration = Duration.between(visitStartTime, visitEndTime);
                // 获取小时数
                long hours = duration.toHours();
                trainTimeSum = trainTimeSum + hours;
                String personId = item.getPersonId();
                String myManagementId = item.getId();
                String courseId = item.getCourseId();
                int read = tTrainMyManagementReadService.count(new QueryWrapper<TTrainMyManagementRead>().eq("learner", personId).eq("management_id", myManagementId));
                //获取所有章节id
                if (StringUtils.isBlank(courseId)){
                    continue;
                }
                List<String> courseIdList = Arrays.asList(courseId.split(","));
                List<Object> sectionIds = tTrainSectionService.listObjs(new QueryWrapper<TTrainSection>().select("id").in("course_id",courseIdList ).eq("status", "0"));
                //获取所有小节
                Integer node = 0;
                if (sectionIds != null && sectionIds.size() > 0) {
                    node = tTrainSmallNodeDao.selectCount(new QueryWrapper<TTrainSmallNode>().in("section_id", sectionIds));
                    if (read == node) {
                        countComplicated.getAndIncrement();
                    }
                }
            }
        }

        String chapterProgress = "0";
        if (total != 0) {
            int percentage = (int) Math.round((double) countComplicated.get() / total * 100);
            chapterProgress = percentage + "%";
        }
        TrainProjectUserStat trainProjectUserStat = new TrainProjectUserStat();
        trainProjectUserStat.setTrainCompletedRate(chapterProgress);
        trainProjectUserStat.setTrainNum(String.valueOf(total));

        trainProjectUserStat.setTrainTimesNum(String.valueOf(trainTimeSum));
        TrainProjectUserStat stateExamByUserId = trainMyManagementDao.findStateExamByUserId(loginName);
        if (stateExamByUserId != null) {
            trainProjectUserStat.setExamNum(stateExamByUserId.getExamNum());
            trainProjectUserStat.setExamAvgScore(stateExamByUserId.getExamAvgScore());
        }
        return trainProjectUserStat;
    }

    @Override
    public ProjectUserInfo findProjectUserInfo(String userId) {
        ProjectUserInfo projectUserInfo = new ProjectUserInfo();
        SysUser sysUser = sysUserService.getById(userId);
        if (sysUser != null) {
            projectUserInfo.setUserName(sysUser.getUserName());
            projectUserInfo.setLoginName(sysUser.getLoginName());
            projectUserInfo.setPhone(sysUser.getPhoneNo());
            projectUserInfo.setEmail(sysUser.getEmail());
            if (sysUser.getDeptId() != null) {
                projectUserInfo.setDeptName(newSysOrgService.getById(sysUser.getDeptId()).getOrgName());
            }
            if (sysUser.getOrgId() != null) {
                projectUserInfo.setOrgName(newSysOrgService.getById(sysUser.getOrgId()).getOrgName());
            }
            //人员资质
            List<TPersonAptitude> aptitudeList = tPersonAptitudeService.lambdaQuery().eq(TPersonAptitude::getPersonId, userId).list();
            projectUserInfo.setAptitudeDtos(aptitudeList);
            //专业指数化评分
            ProfessionalIndicatorScore indicatorScore = professionalIndicatorScoreService.lambdaQuery().eq(ProfessionalIndicatorScore::getUserId, userId).last("limit 1").one();
            if (indicatorScore != null) {
                projectUserInfo.setIndicatorScore(indicatorScore.getTotalScore());
                projectUserInfo.setIndicatorScoreDes(indicatorScore.getTotalScoreDes());
            }
        }
        return projectUserInfo;
    }

    @Override
    public List<TrainProjectUserDetailStat> findTrainList(TTrainMyManagementParam param) {
        List<TrainProjectUserDetailStat> trainListState = trainMyManagementDao.findTrainListState(param.getUserId(), param.getTabStatus());
        return trainListState;
    }
}
