package com.vote.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vctgo.common.core.text.Convert;
import com.vctgo.common.core.utils.ServletUtils;
import com.vctgo.common.mybatisplus.constant.MybatisPageConstants;
import com.vctgo.system.api.RemoteBranchKindergartenService;
import com.vctgo.system.api.RemotePlatformUserService;
import com.vctgo.system.api.RemoteSysProvinceService;
import com.vctgo.system.api.domain.SysPlatformUser;
import com.vctgo.system.api.domain.SysProvince;
import com.vctgo.system.api.domain.dto.SysBranchKindergartenDto;
import com.vote.system.domain.*;
import com.vote.system.domain.dto.VoteEvaluationTasksDto;
import com.vote.system.domain.vo.*;
import com.vote.system.mapper.*;
import com.vote.system.service.VoteAppraiseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author feng
 * @date 2024/8/26
 */
@Service
public class VoteAppraiseServiceImpl implements VoteAppraiseService {


    @Autowired
    private VoteEventWorkSettingsMapper voteEventWorkSettingsMapper;

    @Autowired
    private VoteEventsMapper voteEventsMapper;

    @Autowired
    private VoteWorkTypesMapper voteWorkTypesMapper;

    @Autowired
    private VoteEventEvaluationRoundsMapper voteEventEvaluationRoundsMapper;

    @Autowired
    private VoteSubmissionMapper voteSubmissionMapper;

    @Autowired
    private VoteEventCompetitionZonesMapper voteEventCompetitionZonesMapper;

    @Autowired
    private VoteEvaluationTasksMapper voteEvaluationTasksMapper;

    @Autowired
    private RemoteBranchKindergartenService remoteBranchKindergartenService;

    @Autowired
    private RemotePlatformUserService remotePlatformUserService;


    /**
     * 获取作品品评选
     */
    @Override
    public VoteAppraiseVo getVoteAppraiseByEventId(Long eventId) {
        VoteAppraiseVo vo = new VoteAppraiseVo();
        VoteEvents voteEvents = voteEventsMapper.selectById(eventId);
        vo.setEventsName(voteEvents.getName());
        //获取类型
        List<VoteEventWorkSettings> settings = getWorkSettings(eventId);
        if (!settings.isEmpty()) {
            List<VoteWorkTypeVo> workTypeVos = settings.stream()
                    .map(setting -> createWorkTypeVo(setting, eventId))
                    .collect(Collectors.toList());
            vo.setWorkTypes(workTypeVos);
        }

        return vo;
    }

    /**
     * 专家列表
     */
    @Override
    public List<Map<String, String>> getJudgesList(VoteEvaluationTasksDto voteEvaluationTasksDto) {
        // 查询现有专家
        VoteEventEvaluationRounds evaluationRounds = voteEventEvaluationRoundsMapper.selectById(voteEvaluationTasksDto.getRoundId());

        // 获取现有专家集合
        Set<String> judgeIds = new HashSet<>(Arrays.asList(evaluationRounds.getJudges().split(",")));

        // 远程调用 获取全部专家
        List<SysPlatformUser> experts = remotePlatformUserService.processExpertList().getData();

        // 返回现有专家信息
        return experts.stream()
                .filter(expert -> judgeIds.contains(expert.getUserId().toString()))
                .map(expert -> {
                    Map<String, String> judgeMap = new HashMap<>();
                    judgeMap.put("judgeId", expert.getUserId().toString());
                    judgeMap.put("name", expert.getNickName());
                    return judgeMap;
                })
                .collect(Collectors.toList());
    }


    @Override
    public IPage<VoteSubmissionVo> getSubmissionList(VoteEvaluationTasksDto voteEvaluationTasksDto) {
        // 构建分页参数
        long pageNum = Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_NUM), 1L);
        long pageSize = Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_SIZE), 10L);

        LambdaQueryWrapper<VoteSubmission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VoteSubmission::getEventId, voteEvaluationTasksDto.getEventId())
                .eq(VoteSubmission::getWorkSettingsId, voteEvaluationTasksDto.getWorkSettingsId())
                .eq(VoteSubmission::getRoundId, voteEvaluationTasksDto.getRoundId())
                .orderByDesc(VoteSubmission::getCreateAt);
        List<VoteSubmission> voteSubmissions = voteSubmissionMapper.selectList(wrapper);
        //获取工作类型数据
        Map<Long, VoteEventWorkSettings> workSettingsMap = voteEventWorkSettingsMapper.selectList(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.toMap(VoteEventWorkSettings::getId, Function.identity()));
        // 构建返回的VO列表
        List<VoteSubmissionVo> voList = voteSubmissions.stream()
                .map(item -> {
                    VoteSubmissionVo vo = new VoteSubmissionVo();
                    vo.setId(item.getId());
                    vo.setName(item.getName());
                    vo.setCommitName(item.getCommitName());
                    vo.setCommitTime(item.getCreateAt());
                    vo.setPhone(item.getPhone());
                    vo.setStatus(item.getStatus());
                    //设置类型名称
                    VoteEventWorkSettings workSettings = workSettingsMap.get(item.getWorkSettingsId());
                    VoteWorkTypes workTypes = voteWorkTypesMapper.selectById(workSettings.getWorkTypeId());
                    vo.setWorkTypeName(workTypes != null ? workTypes.getName() : "暂未设置类型");
                    SysBranchKindergartenDto data = remoteBranchKindergartenService.getById(item.getLocationId()).getData();
                    vo.setLocationName(data.getKindergartenName());
                    return vo;
                }).collect(Collectors.toList());
        Page<VoteSubmissionVo> page = new Page<>(pageNum, pageSize);
        page.setRecords(voList);
        page.setTotal(voList.size());
        return page;
    }

    //抽取方法 根据活动取活动设置
    private List<VoteEventWorkSettings> getWorkSettings(Long eventId) {
        LambdaQueryWrapper<VoteEventWorkSettings> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VoteEventWorkSettings::getEventId, eventId);
        return voteEventWorkSettingsMapper.selectList(wrapper);
    }

    //封装活动设置参数
    private VoteWorkTypeVo createWorkTypeVo(VoteEventWorkSettings setting, Long eventId) {
        VoteWorkTypeVo typeVo = new VoteWorkTypeVo();
        typeVo.setWorkSettingsId(setting.getId());
        typeVo.setAlias(setting.getAlias());
        typeVo.setSubmissionEndDate(setting.getSubmissionEndDate());
        typeVo.setSubmissionStaDate(setting.getSubmissionStartDate());

        VoteWorkTypes workTypes = voteWorkTypesMapper.selectById(setting.getWorkTypeId());
        typeVo.setWorkTypeName(workTypes.getName());

        List<VoteEvaluationRoundVo> rounds = Arrays.stream(setting.getRoundsId().split(","))
                .map(roundId -> createEvaluationRoundVo(roundId, setting, eventId))
                .collect(Collectors.toList());
        typeVo.setEvaluationRounds(rounds);

        return typeVo;
    }

    //封装评选轮次参数
    private VoteEvaluationRoundVo createEvaluationRoundVo(String roundId, VoteEventWorkSettings setting, Long eventId) {
        VoteEventEvaluationRounds evaluationRounds = voteEventEvaluationRoundsMapper.selectById(roundId);
        VoteEvaluationRoundVo roundVo = new VoteEvaluationRoundVo();
        roundVo.setRoundId(evaluationRounds.getId());
        roundVo.setType(evaluationRounds.getType());
        roundVo.setStartDate(evaluationRounds.getStartDate());
        roundVo.setEndDate(evaluationRounds.getEndDate());
        //判断是否为评奖论
        if (evaluationRounds.getType().equals("award")) {
            roundVo.setAwardCount(calculateAwardCount(roundId, setting, eventId));
        }

        String[] judges = evaluationRounds.getJudges().split(",");
        roundVo.setJudgedCount(judges.length);//专家数

        roundVo.setZonesCount(getZonesCount(eventId, setting.getId()));//赛区数
        List<VoteSubmission> voteSubmissions = getVoteSubmissions(eventId, setting.getId(), evaluationRounds.getId());
        roundVo.setParticipateCount(voteSubmissions.size());//作品数

        roundVo.setDoneJudgedCount(calculateTaskCount(voteSubmissions, judges, true));
        roundVo.setDoneSubmissionCount(calculateTaskCount(voteSubmissions, judges, false));

        return roundVo;
    }

    private int calculateAwardCount(String roundId, VoteEventWorkSettings setting, Long eventId) {
        LambdaQueryWrapper<VoteSubmission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VoteSubmission::getRoundId, roundId)
                .eq(VoteSubmission::getEventId, eventId)
                .eq(VoteSubmission::getWorkSettingsId, setting)
                .ne(VoteSubmission::getAward, 0);
        return voteSubmissionMapper.selectList(wrapper).size();
    }

    //赛区数
    private Long getZonesCount(Long eventId, Long workSettingsId) {
        LambdaQueryWrapper<VoteEventCompetitionZones> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VoteEventCompetitionZones::getEventId, eventId)
                .eq(VoteEventCompetitionZones::getWorkSettingsId, workSettingsId);
        return voteEventCompetitionZonesMapper.selectCount(queryWrapper);
    }

    //作品数
    private List<VoteSubmission> getVoteSubmissions(Long eventId, Long workSettingsId, Long roundId) {
        LambdaQueryWrapper<VoteSubmission> submissionWrapper = new LambdaQueryWrapper<>();
        submissionWrapper.eq(VoteSubmission::getEventId, eventId)
                .eq(VoteSubmission::getWorkSettingsId, workSettingsId)
                .eq(VoteSubmission::getRoundId, roundId);
        return voteSubmissionMapper.selectList(submissionWrapper);
    }

    //已完成任务数 和 评选完成作品数 通过 includeJudgeCondition 参数控制
    private int calculateTaskCount(List<VoteSubmission> voteSubmissions, String[] judges, boolean includeJudgeCondition) {
        AtomicInteger taskCount = new AtomicInteger(0);
        List<String> judgesIds = Arrays.asList(judges);
        for (VoteSubmission submission : voteSubmissions) {
            LambdaQueryWrapper<VoteEvaluationTasks> taskQueryWrapper = new LambdaQueryWrapper<>();
            taskQueryWrapper.eq(VoteEvaluationTasks::getSubmissionId, submission.getId())
                    .eq(VoteEvaluationTasks::getStatus, 1); // 状态为1

            if (includeJudgeCondition) {
                taskQueryWrapper.in(VoteEvaluationTasks::getJudgeId, judgesIds);
            }

            Long count = voteEvaluationTasksMapper.selectCount(taskQueryWrapper);
            taskCount.addAndGet(Math.toIntExact(count));
        }

        return taskCount.get();
    }


}
