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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.RemoteFileService;
import com.vctgo.system.api.RemotePlatformUserService;
import com.vctgo.system.api.domain.FileInfo;
import com.vctgo.system.api.domain.SysPlatformUser;
import com.vctgo.system.api.domain.dto.SysBranchKindergartenDto;
import com.vctgo.system.api.domain.vo.VoteFileVo;
import com.vote.system.domain.*;
import com.vote.system.domain.dto.VoteSubmissionDto;
import com.vote.system.domain.dto.VoteSubmissionItemDto;
import com.vote.system.domain.vo.VoteSubmissionCountVo;
import com.vote.system.domain.vo.VoteSubmissionItemVo;
import com.vote.system.domain.vo.VoteSubmissionVo;
import com.vote.system.mapper.*;
import com.vote.system.service.VoteSubmissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.vote.system.util.ConstantUtils.*;

/**
 * @author MacBook
 * @description 针对表【vote_submission】的数据库操作Service实现
 * @createDate 2024-08-20 15:39:44
 */
@Service
public class VoteSubmissionServiceImpl extends ServiceImpl<VoteSubmissionMapper, VoteSubmission>
        implements VoteSubmissionService {

    @Autowired
    private VoteSubmissionMapper voteSubmissionMapper;

    @Autowired
    private VoteWorkTypesMapper voteWorkTypesMapper;

    @Autowired
    private VoteEventWorkSettingsMapper voteEventWorkSettingsMapper;

    @Autowired
    private VoteEvaluationTasksMapper voteEvaluationTasksMapper;

    @Autowired
    private VoteEventEvaluationRoundsMapper voteEventEvaluationRoundsMapper;

    @Autowired
    private VoteEventAwardsMapper voteEventAwardsMapper;

    @Autowired
    private VoteRegistrationsMapper voteRegistrationsMapper;

    @Autowired
    private VoteRuleMapper voteRuleMapper;

    @Autowired
    private VoteScoringItemMapper voteScoringItemMapper;

    @Autowired
    private VoteSubmissionItemMapper voteSubmissionItemMapper;


    @Autowired
    private RemoteFileService remoteFileService;

    @Autowired
    private RemoteBranchKindergartenService remoteBranchKindergartenService;

    @Autowired
    private RemotePlatformUserService remotePlatformUserService;

    @Autowired
    private VoteEventRegistrationWorkScoresMapper voteEventRegistrationWorkScoresMapper;


    /**
     * 分页查询 参赛作品列表
     *
     * @param voteSubmissionDto
     * @return
     */
    @Override
    public IPage<VoteSubmissionVo> selectPage(VoteSubmissionDto voteSubmissionDto) {
        long pageNum = Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_NUM), 1L);
        long pageSize = Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_SIZE), 10L);
        Page<VoteSubmissionVo> page = new Page<>(pageNum, pageSize);
        List<VoteSubmission> voteSubmissions = getVoteSubmissions(voteSubmissionDto);
        if (voteSubmissions.isEmpty()) {
            page.setRecords(Collections.emptyList());
            page.setTotal(voteSubmissions.size());
            return page;
        }

        //获取工作类型数据
        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 = getSysBranchKindergartenDto(item);
                    vo.setLocationName(data.getKindergartenName());
                    return vo;
                }).collect(Collectors.toList());
        page.setRecords(voList);
        page.setTotal(voList.size());
        return page;
    }

    //获取园所名称
    private SysBranchKindergartenDto getSysBranchKindergartenDto(VoteSubmission item) {
        return remoteBranchKindergartenService.getById(item.getLocationId()).getData();
    }


    //构建查询条件方法
    private List<VoteSubmission> getVoteSubmissions(VoteSubmissionDto voteSubmissionDto) {
        List<Long> userIds = new ArrayList<>();
        boolean locationFilterApplied = false;
        LambdaQueryWrapper<VoteRegistrations> queryWrapper = new LambdaQueryWrapper<>();
        if (voteSubmissionDto.getProvinceId() != null) {
            queryWrapper.eq(VoteRegistrations::getProvinceId, voteSubmissionDto.getProvinceId());
            if (voteSubmissionDto.getCityId() != null) {
                queryWrapper.eq(VoteRegistrations::getCityId, voteSubmissionDto.getCityId());
            }
            if (voteSubmissionDto.getDistrictId() != null) {
                queryWrapper.eq(VoteRegistrations::getDistrictId, voteSubmissionDto.getDistrictId());
            }
            if (voteSubmissionDto.getLocationId() != null) {
                queryWrapper.eq(VoteRegistrations::getLocationId, voteSubmissionDto.getLocationId());
            }
            userIds = voteRegistrationsMapper.selectList(queryWrapper).stream()
                    .map(VoteRegistrations::getUid)
                    .collect(Collectors.toList());
            locationFilterApplied = true;

            if (userIds.isEmpty()) {
                return new ArrayList<>();
            }
        }

        LambdaQueryWrapper<VoteSubmission> wrapper = new LambdaQueryWrapper<>();
        if (voteSubmissionDto.getEventId() == null) {
            throw new RuntimeException("活动id为空 暂时无法查询");
        } else {
            wrapper.eq(VoteSubmission::getEventId, voteSubmissionDto.getEventId());
        }

        if (voteSubmissionDto.getWorkSettingsId() != null) {
            wrapper.eq(VoteSubmission::getWorkSettingsId, voteSubmissionDto.getWorkSettingsId());
        }
        if (locationFilterApplied && !userIds.isEmpty()) {
            wrapper.in(VoteSubmission::getUserId, userIds);
        }
        if (voteSubmissionDto.getStatus() != null) {
            wrapper.eq(VoteSubmission::getStatus, voteSubmissionDto.getStatus());
        }
        if (voteSubmissionDto.getKeyword() != null) {
            wrapper.like(VoteSubmission::getName, voteSubmissionDto.getKeyword())
                    .or()
                    .like(VoteSubmission::getPhone, voteSubmissionDto.getKeyword());
        }
        if (voteSubmissionDto.getRoundId() != null) {
            wrapper.eq(VoteSubmission::getRoundId, voteSubmissionDto.getRoundId());
        }
        if (voteSubmissionDto.getLocationId() != null) {
            wrapper.eq(VoteSubmission::getLocationId, voteSubmissionDto.getLocationId());
        }
        if (voteSubmissionDto.getPromoteStatus() != null) {
            wrapper.eq(VoteSubmission::getPromoteStatus, voteSubmissionDto.getPromoteStatus());
        }
        wrapper.orderByDesc(VoteSubmission::getCreateAt);
        return voteSubmissionMapper.selectList(wrapper);
    }


    /**
     * 查询单个详情
     *
     * @param id
     * @return
     */
    @Override
    public VoteSubmissionVo selectById(Long id) {
        VoteSubmission submission = voteSubmissionMapper.selectById(id);
        VoteSubmissionVo vo = new VoteSubmissionVo();
        submission.setFile(submission.getFile() + "," + submission.getImages() + "," + submission.getVideo());
        List<FileInfo> fileInfoList = remoteFileService.selectUrlByIds(submission.getFile()).getData();//文件集合
        // 初始化图片 URL 列表
        List<VoteFileVo> imageFiles = new ArrayList<>();
        List<VoteFileVo> videoFiles = new ArrayList<>();
        List<VoteFileVo> documentFiles = new ArrayList<>();
        for (FileInfo fileInfo : fileInfoList) {
            VoteFileVo fileVo = new VoteFileVo();
            fileVo.setFileUrl(fileInfo.getFileUrl()); // 设置文件URL
            fileVo.setFileName(fileInfo.getFileName());
            // 根据 fileType 来判断文件类型
            String fileType = fileInfo.getFileType();
            switch (fileType) {
                case "1":  // 文件
                    documentFiles.add(fileVo);
                    break;
                case "2":  // 图片类型
                    imageFiles.add(fileVo);
                    break;
                case "3":  // 视频类型
                    videoFiles.add(fileVo);
                    break;
                default:
                    break;
            }
        }
        vo.setVideoFiles(videoFiles)
                .setDocumentFiles(documentFiles)
                .setImageFiles(imageFiles);
        vo.setName(submission.getName())
                .setMainAuthor(submission.getMainAuthor())
                .setTeamWorker(submission.getTeamWorker());
        if (CREATE_TYPE_PERSONAL.equals(submission.getCreateType())) {
            vo.setCreateType(CREATE_TYPE_PERSONAL_DESC);
        } else {
            vo.setCreateType(CREATE_TYPE_TEAM_DESC);
        }
        if (!submission.getAgeSegment().isEmpty()) {
            StringBuilder builder = new StringBuilder();
            String ageSegment = submission.getAgeSegment();
            String[] split = ageSegment.split(",");
            for (String s : split) {
                if (s.equals(ZHONG_BAN_CODE)) {
                    builder.append(ZHONG_BAN_DESC);
                } else if (s.equals(DA_BAN_CODE)) {
                    builder.append(DA_BAN_DESC);
                } else {
                    builder.append(XIAO_BAN_DESC);
                }
            }
            vo.setAgeSegment(builder.toString());
        }
        return vo;
    }

    /**
     * 评选结果 分页查询
     */
    @Override
    public IPage<VoteSubmissionVo> getResult(VoteSubmissionDto voteSubmissionDto) {
        // 获取分页参数
        long pageNum = Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_NUM), 1L);
        long pageSize = Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_SIZE), 10L);

        // 获取作品列表和专家数据
        List<VoteSubmission> voteSubmissions = getVoteSubmissions(voteSubmissionDto);
        // 将专家列表转换为以judgeId为键，专家姓名为值的Map
        Map<String, String> judgeMap = remotePlatformUserService.processExpertList().getData().stream()
                .collect(Collectors.toMap(
                        user -> user.getUserId().toString(),
                        SysPlatformUser::getNickName
                ));
        // 预先生成 submissionId 到 judgeId 的映射
        Map<Long, String> submissionJudgeMap = voteSubmissions.stream()
                .collect(Collectors.toMap(
                        VoteSubmission::getId,
                        submission -> voteEvaluationTasksMapper.selectOne(
                                new LambdaQueryWrapper<VoteEvaluationTasks>()
                                        .eq(VoteEvaluationTasks::getSubmissionId, submission.getId())
                        ).getJudgeId()
                ));
        // 预先生成 submissionId 到 score 的映射
        Map<Long, BigDecimal> submissionScoreMap = voteSubmissions.stream()
                .collect(Collectors.toMap(
                        VoteSubmission::getId,
                        submission -> {
                            try {
                                VoteEventRegistrationWorkScores score = voteEventRegistrationWorkScoresMapper.selectOne(
                                        new LambdaQueryWrapper<VoteEventRegistrationWorkScores>()
                                                .eq(VoteEventRegistrationWorkScores::getEventId, submission.getEventId())
                                                .eq(VoteEventRegistrationWorkScores::getWorkSettingsId, submission.getWorkSettingsId())
                                                .eq(VoteEventRegistrationWorkScores::getSubmissionId, submission.getId())
                                );
                                return (score != null) ? score.getScore() : BigDecimal.ZERO;
                            } catch (Exception e) {
                                return BigDecimal.ZERO;
                            }
                        }
                ));

        // 将VoteSubmission转换为VoteSubmissionVo
        List<VoteSubmissionVo> vos = voteSubmissions.stream()
                .map(submission -> {
                    VoteSubmissionVo vo = new VoteSubmissionVo();
                    vo.setName(submission.getName())
                            .setCommitName(submission.getCommitName())
                            .setPhone(submission.getPhone())
                            .setId(submission.getId());
                    // 根据PromoteStatus设置状态
                    switch (submission.getPromoteStatus()) {
                        case PENDING_1:
                            vo.setPromoteStatus(PENDING_1);
                            break;
                        case PROMOTE_0:
                            vo.setPromoteStatus(PROMOTE_0);
                            break;
                        default:
                            vo.setPromoteStatus(UNKNOWN);
                    }
                    if (submission.getAward() != null && submission.getAward().isEmpty()) {
                        vo.setAward(submission.getAward());
                    } else {
                        vo.setAward(PENDING);
                    }
                    // 设置园所名称
                    SysBranchKindergartenDto data = getSysBranchKindergartenDto(submission);
                    vo.setLocationName(data.getKindergartenName());
                    // 从映射表中获取并设置专家姓名
                    vo.setJudge(judgeMap.get(submissionJudgeMap.get(submission.getId())));
                    // 从映射表中获取并设置分数
                    vo.setScore(submissionScoreMap.get(submission.getId()));
                    return vo;
                })
                .sorted(Comparator.comparing(VoteSubmissionVo::getScore).reversed()) // 按分数降序排序
                .collect(Collectors.toList());
        // 为每个项目分配排序序号
        for (int i = 0; i < vos.size(); i++) {
            vos.get(i).setSort(i + 1);
        }
        // 进行分页
        Page<VoteSubmissionVo> page = new Page<>(pageNum, pageSize);
        page.setRecords(vos.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList()));
        page.setTotal(vos.size());
        return page;
    }

    /**
     * 评选结果 （评选轮） 全部作品类型数量
     */
    @Override
    public VoteSubmissionCountVo getAllSubmissionCount(VoteSubmissionDto voteSubmissionDto) {
        VoteSubmissionCountVo countVo = new VoteSubmissionCountVo();
        List<VoteSubmission> voteSubmissions = getVoteSubmissions(voteSubmissionDto);
        List<VoteSubmission> pendingCount = voteSubmissions.stream().filter(voteSubmission -> voteSubmission.getPromoteStatus().equals(PENDING_1)).collect(Collectors.toList());
        List<VoteSubmission> promoteCount = voteSubmissions.stream().filter(voteSubmission -> voteSubmission.getPromoteStatus().equals(PROMOTE_0)).collect(Collectors.toList());
        countVo.setPendingCount(pendingCount.size());
        countVo.setAllSubmission(voteSubmissions.size());
        countVo.setPromoteCount(promoteCount.size());
        return countVo;
    }

    /**
     * 评选结果 （评选轮） 晋级
     */
    @Override
    @Transactional
    public int promote(VoteSubmissionDto voteSubmissionDto) {
        VoteEventWorkSettings eventWorkSettings = voteEventWorkSettingsMapper.selectById(voteSubmissionDto.getWorkSettingsId());
        String[] split = eventWorkSettings.getRoundsId().split(",");
        List<Long> roundIds = Arrays.stream(split).map(Long::parseLong).collect(Collectors.toList());
        //创建修改对象
        VoteSubmission voteSubmission = new VoteSubmission();
        voteSubmission.setId(voteSubmissionDto.getId())
                .setPromoteStatus(PROMOTE_0);
        if (roundIds.size() > 1) {
            int currentIndex = roundIds.indexOf(voteSubmissionDto.getRoundId());
            if (currentIndex >= 0 && currentIndex < roundIds.size() - 1) {
                //获取当前索引的后一个元素
                Long nextRoundId = roundIds.get(currentIndex + 1);
                voteSubmission.setRoundId(nextRoundId);
            }
        }
        return voteSubmissionMapper.updateById(voteSubmission);
    }


    /**
     * 评选结果 （评奖轮） 全部作品类型数量
     */
    @Override
    public VoteSubmissionCountVo getAllAwardCount(VoteSubmissionDto voteSubmissionDto) {
        List<VoteSubmission> voteSubmissions = getVoteSubmissions(voteSubmissionDto);
        VoteSubmissionCountVo allSubmissionCount = getAllSubmissionCount(voteSubmissionDto);
        List<VoteSubmission> alreadyAwarded = voteSubmissions.stream().filter(voteSubmission -> !voteSubmission.getAward().equals(PROMOTE_0)).collect(Collectors.toList());
        allSubmissionCount.setAlreadyAwarded(alreadyAwarded.size());//已评奖
        VoteEventEvaluationRounds voteEventEvaluationRounds = voteEventEvaluationRoundsMapper.selectById(voteSubmissionDto.getRoundId());
        String[] split = voteEventEvaluationRounds.getAwards().split(",");
        List<Map<String, Integer>> list = new ArrayList<>();
        for (String s : split) {
            Map<String, Integer> map = new HashMap<>();
            VoteEventAwards eventAwards = voteEventAwardsMapper.selectById(s);
            map.put(eventAwards.getName(), eventAwards.getQuantity());
            list.add(map);
        }
        allSubmissionCount.setAwardNameList(list);
        return allSubmissionCount;
    }

    /**
     * 评选结果 （评奖轮） 分页查询
     */
    @Override
    public IPage<VoteSubmissionVo> getResultAward(VoteSubmissionDto voteSubmissionDto) {
        return getResult(voteSubmissionDto);
    }

    /**
     * 评选结果 （评奖轮） 奖项回显
     */
    @Override
    public List<String> awardShow(VoteSubmissionDto voteSubmissionDto) {
        VoteEventEvaluationRounds rounds = voteEventEvaluationRoundsMapper.selectById(voteSubmissionDto.getRoundId());
        String[] split = rounds.getAwards().split(",");
        List<String> awardName = new ArrayList<>();
        for (String s : split) {
            VoteEventAwards awards = voteEventAwardsMapper.selectById(s);
            awardName.add(awards.getName());
        }
        return awardName;
    }

    /**
     * 评奖
     */
    @Override
    @Transactional
    public int distribute(VoteSubmissionDto voteSubmissionDto) {
        VoteSubmission voteSubmission = new VoteSubmission();
        voteSubmission.setId(voteSubmissionDto.getId())
                .setAward(voteSubmissionDto.getAward());
        return voteSubmissionMapper.updateById(voteSubmission);
    }

    /**
     * 修改评分回显
     */
    @Override
    @Transactional
    public VoteSubmissionItemVo getSubmissionItem(VoteSubmissionDto voteSubmissionDto) {
        VoteSubmissionItemVo itemVo = new VoteSubmissionItemVo();
        LambdaQueryWrapper<VoteSubmissionItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VoteSubmissionItem::getSubmissionId, voteSubmissionDto.getId());
        List<VoteSubmissionItem> submissionItems = voteSubmissionItemMapper.selectList(wrapper);//单项评分
        List<VoteScoringItem> items = new ArrayList<>();
        Integer totalScore = 0;
        for (VoteSubmissionItem submissionItem : submissionItems) {
            VoteScoringItem scoringItem = voteScoringItemMapper.selectById(submissionItem.getItemId());
            scoringItem.setAggregate(submissionItem.getScore());
            scoringItem.setItemId(submissionItem.getId());
            items.add(scoringItem);
            totalScore += submissionItem.getScore();
        }
        itemVo.setAggregateScore(totalScore);
        itemVo.setItemList(items);
        return itemVo;
    }


    /**
     * 修改
     *
     * @param voteSubmissionDto
     * @return
     */
    @Override
    @Transactional
    public int editItem(VoteSubmissionItemDto voteSubmissionDto) {
        List<VoteScoringItem> itemList = voteSubmissionDto.getItemList();
        for (VoteScoringItem voteScoringItem : itemList) {
            VoteSubmissionItem voteSubmissionItem = new VoteSubmissionItem();
            voteSubmissionItem.setSubmissionId(voteSubmissionDto.getId())
                    .setId(voteScoringItem.getItemId())
                    .setScore(voteScoringItem.getAggregate());
            voteSubmissionItemMapper.updateById(voteSubmissionItem);
        }
        LambdaQueryWrapper<VoteSubmissionItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VoteSubmissionItem::getSubmissionId, voteSubmissionDto.getId());
        List<VoteSubmissionItem> submissionItems = voteSubmissionItemMapper.selectList(wrapper);
        int total = 0;
        for (VoteSubmissionItem submissionItem : submissionItems) {
            total += submissionItem.getScore();
        }
        LambdaQueryWrapper<VoteEventRegistrationWorkScores> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VoteEventRegistrationWorkScores::getSubmissionId, voteSubmissionDto.getId());
        VoteEventRegistrationWorkScores scores = new VoteEventRegistrationWorkScores();
        scores.setScore(BigDecimal.valueOf(total));
        return voteEventRegistrationWorkScoresMapper.update(scores, queryWrapper);

    }


}




