package com.ruoyi.system.service.conference.impl;

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

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.jPush.JPushToolUtil;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.domain.conference.SysUserConference;
import com.ruoyi.system.domain.loan.LoanApplication;
import com.ruoyi.system.domain.remind.WaitRemind;
import com.ruoyi.system.domain.review.ReviewComments;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.conference.ISysUserConferenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import static com.ruoyi.common.constant.CommonConstants.*;

/**
 * 参会人员Service业务层处理
 *
 * @author boman
 * @date 2024-05-06
 */
@Service
public class SysUserConferenceServiceImpl implements ISysUserConferenceService {
    @Autowired
    private SysUserConferenceMapper sysUserConferenceMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private LoanApplicationMapper loanApplicationMapper;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private ReviewCommentsMapper reviewCommentsMapper;

    @Autowired
    private RedisCache redisCache;

    @Resource
    private WaitRemindMapper waitRemindMapper;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 查询参会人员
     *
     * @param conferenceId 参会人员主键
     * @return 参会人员
     */
    @Override
    public SysUserConference selectSysUserConferenceByConferenceId(Long conferenceId) {
        return sysUserConferenceMapper.selectSysUserConferenceByConferenceId(conferenceId);
    }

    /**
     * 查询参会人员列表
     *
     * @param sysUserConference 参会人员
     * @return 参会人员
     */
    @Override
    public List<SysUserConference> selectSysUserConferenceList(SysUserConference sysUserConference) {
        return sysUserConferenceMapper.selectSysUserConferenceList(sysUserConference);
    }

    /**
     * 新增参会人员
     *
     * @param sysUserConference 参会人员
     * @return 结果
     */
    @Override
    public int insertSysUserConference(SysUserConference sysUserConference) {
        sysUserConference.setCreateTime(DateUtils.getNowDate());
        return sysUserConferenceMapper.insertSysUserConference(sysUserConference);
    }

    /**
     * 修改参会人员
     *
     * @param sysUserConference 参会人员
     * @return 结果
     */
    @Override
    public int updateSysUserConference(SysUserConference sysUserConference) {
        sysUserConference.setUpdateTime(DateUtils.getNowDate());
        return sysUserConferenceMapper.updateSysUserConference(sysUserConference);
    }

    /**
     * 批量删除参会人员
     *
     * @param conferenceIds 需要删除的参会人员主键
     * @return 结果
     */
    @Override
    public int deleteSysUserConferenceByConferenceIds(Long[] conferenceIds) {
        return sysUserConferenceMapper.deleteSysUserConferenceByConferenceIds(conferenceIds);
    }

    /**
     * 删除参会人员信息
     *
     * @param conferenceId 参会人员主键
     * @return 结果
     */
    @Override
    public int deleteSysUserConferenceByConferenceId(Long conferenceId) {
        return sysUserConferenceMapper.deleteSysUserConferenceByConferenceId(conferenceId);
    }

    @Override
    @Transactional
    public AjaxResult randomAdd(SysUserConference sysUserConference) {

        int num = 0;
        //查询贷款信息
        LoanApplication loanApplication = loanApplicationMapper.selectLoanApplicationByLoanApplicationId(sysUserConference.getLoanApplicationId());
        //主表赋值
        loanApplication.setReviewTime(sysUserConference.getConferenceTime());
        loanApplication.setReviewSchedule(FOR);
        loanApplicationMapper.updateLoanApplication(loanApplication);
        
        redisCache.setCacheObject(sysUserConference.getLoanApplicationNumber()+"tp",FOR);

        //查询参会人员的字典值
        List<SysDictData> data = dictTypeService.selectDictDataByType("conference_role");
        List<String> strlist = data.stream().map(SysDictData::getDictValue).collect(Collectors.toList());
        //查询人员
        List<SysUser> userList = userMapper.selectUserManageList(strlist);
        //生成0-n的随机数
        List<Integer> intList = new ArrayList<>();
        Random random = new Random();
        while (num < 5) {
            int randomNumber = random.nextInt(userList.size() - 1);
            if(intList.size()>0 && intList.contains(randomNumber)){
                continue;
            }
            SysUser sysUser = userList.get(randomNumber);
            //A
            boolean b1 = sysUser.getUserId().equals(loanApplication.getaUserId());
            //B
            boolean b2 = sysUser.getUserId().equals(loanApplication.getbUserId());
            //风险
            boolean b3 = sysUser.getUserId().equals(loanApplication.getfUserId());
            //只有同时满足随机人员不是这三个时才能加入参会人员
            if (!b1 && !b2 && !b3) {
                //将信息存入库
                SysUserConference userConference = new SysUserConference();
                userConference.setUserId(sysUser.getUserId());
                userConference.setRealName(sysUser.getNickName());
                userConference.setLoanApplicationId(sysUserConference.getLoanApplicationId());
                userConference.setLoanApplicationName(loanApplication.getEnterpriseName());
                userConference.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
                userConference.setConferenceTime(sysUserConference.getConferenceTime());
                sysUserConferenceMapper.insertSysUserConference(userConference);
                //给人员发生代办信息
                WaitRemind waitRemind = new WaitRemind();
                waitRemind.setLoanApplicationId(sysUserConference.getLoanApplicationId());
                waitRemind.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
                waitRemind.setRemindTitle("您有一条【" + loanApplication.getEnterpriseName() + "】评审会议");
                waitRemind.setRemindTime(DateUtils.getNowDate());
                waitRemind.setRemindType("11");
                waitRemind.setReadUserId(sysUser.getUserId().toString());
                waitRemind.setRemindContent("您有一个评审会议需参加，会议时间："+sysUserConference.getConferenceTime()+"，会议主题：【"+loanApplication.getEnterpriseName()+"】评审会");
                waitRemindMapper.insertWaitRemind(waitRemind);
                num++;
                intList.add(randomNumber);

                //发极光推送
                SysUser user = sysUserService.selectUserById(sysUser.getUserId());
                if(StringUtils.isNotEmpty(user.getJgId())){
                    String notificationTitle = "消息通知";
                    String msgTitle = "评审会议";
                    String msgContent = "您有一个评审会议需参加，会议时间："+sysUserConference.getConferenceTime()+"，会议主题：【"+loanApplication.getEnterpriseName()+"】评审会";
                    String jPushVO = "";
                    JPushToolUtil.sendToRegistrationId(notificationTitle,msgTitle,msgContent,jPushVO,user.getJgId());
                }
            }
        }
        return AjaxResult.success("成功");
    }

    @Override
    public AjaxResult timeTist(SysUserConference sysUserConference) {
        List<SysUserConference> sysUserConferences = sysUserConferenceMapper.selectSysUserConferenceList(sysUserConference);
        List<Map<String,Object>> listMap = new ArrayList<>();
        if(sysUserConferences==null || sysUserConferences.size()<=0){
            return AjaxResult.success(listMap);
        }
        Map<String,List<SysUserConference>> map = sysUserConferences.stream().collect(Collectors.groupingBy(SysUserConference::getConferenceTime));

        //根据时间进行升序排序
        Map<String, List<SysUserConference>> result = new LinkedHashMap<>();
        map.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByKey())).forEachOrdered(x -> result.put(x.getKey(), x.getValue()));



        for (Map.Entry<String, List<SysUserConference>> entry : result.entrySet()) {
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("conferenceTime",entry.getKey());
            resultMap.put("children",entry.getValue());
            listMap.add(resultMap);
        }
        return AjaxResult.success(listMap);
    }

    @Override
    public AjaxResult pcTimeTist(SysUserConference sysUserConference) {
        List<SysUserConference> sysUserConferences = sysUserConferenceMapper.selectSysUserConferenceList(sysUserConference);
        return AjaxResult.success(sysUserConferences);
    }

    @Override
    @Transactional
    public AjaxResult vote(SysUserConference sysUserConference) {
        //将状态改为投票中
        redisCache.setCacheObject(sysUserConference.getLoanApplicationNumber()+"tp",ONE);
        SysUser user = SecurityUtils.getLoginUser().getUser();
        //查询所有人员的投票结果
        List<SysUserConference> sysUserConferences = sysUserConferenceMapper.selectSysUserConferenceList(sysUserConference);
        //如果投票人员不在参会人员中，投票失败
        Boolean bo = false;
        //是否重复投票
        Boolean bn = false;
        for (SysUserConference userConference : sysUserConferences) {
            if(user.getUserId().equals(userConference.getUserId())){
                bo = true;
                if(StringUtils.isNotEmpty(userConference.getVotingResult())){
                    bn = true;
                }
                break;
            }
        }
        //为 false 时表示不在
        if(!bo){
            return AjaxResult.error("不是当前项目投票人员，投票失败");
        }
        if(bn){
            return AjaxResult.error("请勿重复投票");
        }

        sysUserConference.setUserId(user.getUserId());
        sysUserConference.setUpdateTime(DateUtils.getNowDate());
        sysUserConferenceMapper.updateSysUserConferenceByUserId(sysUserConference);
        //除了本人外是否全部投票
        //不同意人数
        int bty = 0;
        if("N".equals(sysUserConference.getVotingResult())){
            bty++;
        }
        for (SysUserConference userConference : sysUserConferences) {
            //是否有人未投票
            if(!userConference.getUserId().equals(user.getUserId()) && StringUtils.isEmpty(userConference.getVotingResult())){
                //有人未投票就直接返回结果
                return AjaxResult.success("成功");
            }
            //排除掉本人
            if(!userConference.getUserId().equals(user.getUserId()) && StringUtils.isNotEmpty(userConference.getVotingResult()) && "N".equals(userConference.getVotingResult())){
                bty++;
            }

        }
        redisCache.setCacheObject(sysUserConference.getLoanApplicationNumber()+"tp",TWO);
        if(bty>=2){
            //修改主表信息 未通过
            LoanApplication loanApplication = new LoanApplication();
            loanApplication.setAuditType(FOR);
            loanApplication.setReviewSchedule(SIX);
            loanApplication.setLoanApplicationId(sysUserConference.getLoanApplicationId());
            loanApplicationMapper.updateLoanApplication(loanApplication);
            // todo 未通过 业务流程表插入数据
            //业务审核意见
            ReviewComments reviewComments = new ReviewComments();
            reviewComments.setLoanApplicationId(loanApplication.getLoanApplicationId());
            reviewComments.setLoanApplicationNumber(sysUserConference.getLoanApplicationNumber());
            reviewComments.setAuditSchedule(SEV);
            reviewComments.setAuditType(FOR);
            reviewComments.setAuditTime(DateUtils.getNowDate());
            reviewComments.setCreateBy(SecurityUtils.getUsername());
            reviewCommentsMapper.insertReviewComments(reviewComments);

            return AjaxResult.success("成功");
        }


        //判断所有人的金额是否一样
        //最后一个投票人员
        String je = sysUserConference.getLineGuarantee();
        if("N".equals(sysUserConference.getVotingResult())){
            for (SysUserConference userConference : sysUserConferences) {
                if(StringUtils.isNotEmpty(userConference.getLineGuarantee())){
                    je = userConference.getLineGuarantee();
                }
            }
        }
        Boolean bl = true;
        for (SysUserConference userConference : sysUserConferences) {
            if(!userConference.getUserId().equals(user.getUserId()) && !je.equals(userConference.getLineGuarantee())){
                bl = false;
                break;
            }
        }
        //不一样
        if(!bl){
            redisCache.setCacheObject(sysUserConference.getLoanApplicationNumber()+"tp",THR);
            return AjaxResult.success("成功,投票金额不同，请通知管理员重新发起投票");
        }

        if(bty<2){
            //修改主表信息 通过
            LoanApplication loanApplication = new LoanApplication();
            loanApplication.setAuditType(ONE);
            loanApplication.setReviewSchedule(FIV);
            loanApplication.setAuditSchedule(EIG);
            loanApplication.setLoanSchedule(SEV);
            loanApplication.setActuallyAmount(Double.parseDouble(je));
            loanApplication.setLoanApplicationId(sysUserConference.getLoanApplicationId());
            loanApplicationMapper.updateLoanApplication(loanApplication);
            // todo 通过 业务流程表插入数据
            //业务审核意见
            ReviewComments reviewComments = new ReviewComments();
            reviewComments.setLoanApplicationId(loanApplication.getLoanApplicationId());
            reviewComments.setLoanApplicationNumber(sysUserConference.getLoanApplicationNumber());
            reviewComments.setAuditSchedule(SEV);
            reviewComments.setAuditType(TWO);
            reviewComments.setAuditTime(DateUtils.getNowDate());
            reviewComments.setCreateBy(SecurityUtils.getUsername());
            reviewCommentsMapper.insertReviewComments(reviewComments);
            return AjaxResult.success("成功");
        }

        return AjaxResult.success("成功");
    }

    @Override
    @Transactional
    public AjaxResult again(SysUserConference sysUserConference) {
        //删除投票状态
        redisCache.deleteObject(sysUserConference.getLoanApplicationNumber()+"tp");
        //查询最新的投票人员
        //查询贷款表信息
        LoanApplication loanApplication = loanApplicationMapper.selectLoanApplicationByLoanApplicationId(sysUserConference.getLoanApplicationId());
        //查询所有人员的投票结果 必须有时间和贷款id
        SysUserConference userConference = new SysUserConference();
        userConference.setLoanApplicationId(sysUserConference.getLoanApplicationId());
        userConference.setConferenceTime(loanApplication.getReviewTime());
        List<SysUserConference> sysUserConferences = sysUserConferenceMapper.selectSysUserConferenceList(userConference);
        for (SysUserConference conference : sysUserConferences) {
            //重新赋值投票人员
            SysUserConference user = new SysUserConference();
            user.setUserId(conference.getUserId());
            user.setRealName(conference.getRealName());
            user.setLoanApplicationId(conference.getLoanApplicationId());
            user.setLoanApplicationName(conference.getLoanApplicationName());
            user.setLoanApplicationNumber(conference.getLoanApplicationNumber());
            user.setConferenceTime(sysUserConference.getConferenceTime());
            sysUserConferenceMapper.insertSysUserConference(user);
        }
        //修改主表信息
        loanApplication.setReviewTime(sysUserConference.getConferenceTime());
        loanApplication.setReviewSchedule(FOR);
        loanApplicationMapper.updateLoanApplication(loanApplication);
        return AjaxResult.success("成功");
    }

    @Override
    public AjaxResult finish(SysUserConference sysUserConference) {
        //将项目放入回收站
        LoanApplication loanApplication = new LoanApplication();
        loanApplication.setLoanApplicationId(sysUserConference.getLoanApplicationId());
        loanApplication.setLoanApplicationType(THR);
        loanApplicationMapper.updateLoanApplication(loanApplication);
        return AjaxResult.success("成功");
    }

}
