package com.srs.comprehensive.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.srs.common.core.domain.AjaxResult;
import com.srs.common.utils.DateUtils;
import com.srs.comprehensive.domain.*;
import com.srs.comprehensive.domain.Dto.CphAuditMany;
import com.srs.comprehensive.domain.Dto.CphCancel;
import com.srs.comprehensive.domain.Vo.CphLakeApplyVo;
import com.srs.comprehensive.domain.Vo.CphSearch;
import com.srs.comprehensive.domain.Vo.CphTotalScoreInfo;
import com.srs.comprehensive.mapper.*;
import org.apache.commons.math3.analysis.function.Exp;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.srs.comprehensive.service.ICphLakeApplyService;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import static com.srs.common.utils.DateUtils.getNowDate;
import static com.srs.common.utils.SecurityUtils.getLoginUser;
import static com.srs.common.utils.SecurityUtils.getUsername;

/**
 * 静湖之星申请Service业务层处理
 *
 * @author srs
 * @date 2023-10-31
 */
@Service
public class CphLakeApplyServiceImpl extends ServiceImpl<CphLakeApplyMapper,CphLakeApply> implements ICphLakeApplyService {
    @Autowired
    private CphLakeApplyMapper cphLakeApplyMapper;

    @Autowired
    private CphGoodCancelLogMapper _logMapper;

    @Autowired
    private CphTotalScoreMapper _scoreMapper;

    @Autowired
    public PlatformTransactionManager transactionManager;

    @Autowired
    public SrsStuYearMapper _yearMapper;

    @Autowired
    public CphScienceScoreMapper _scienceScoreMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult manyAudit(CphAuditMany param){
        try{
            String applyStatus = "6";

            Long[] applyIds = param.applyIds;
            List<Long> applyIdList = new ArrayList<>();

            for (Long id: applyIds ) {
                applyIdList.add(id);
                CphLakeApply temp = new CphLakeApply();
                temp.setApplyStatus(applyStatus);
                temp.setUpdateTime(getNowDate());
                temp.setUpdateBy(getUsername());
                temp.setId(id);
                cphLakeApplyMapper.updateById(temp);
            }

            QueryWrapper<CphLakeApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", applyIdList);
            List<CphLakeApply> needUpdateAudit = cphLakeApplyMapper.selectList(queryWrapper);

            for(CphLakeApply item : needUpdateAudit ){
                item.setJwcComment(param.common);
                item.setXgTime(getNowDate());
                item.setXgNo(getUsername());
                item.setUpdateTime(getNowDate());
                item.setUpdateBy(getUsername());
                cphLakeApplyMapper.updateById(item);
            }

            return AjaxResult.success("操作成功");
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult doAudit(CphLakeApply param){
        try{

            if(param.getXwComment() != null && !param.getXwComment().equals("") && Objects.equals(param.getApplyStatus(), "3")){

                Long applyId = param.getId();
                CphLakeApply find = cphLakeApplyMapper.selectCphLakeApplyById(applyId);
                if(find == null){
                    throw new Exception("出错了，刷新试试");
                }
                if(!Objects.equals(find.getTypeCode(), "SJDXS")){
                    CphLakeApply searchQuery = new CphLakeApply();
                    searchQuery.setStuNo(find.getStuNo());
                    searchQuery.setStuYearId(find.getStuYearId());
                    List<CphLakeApply> isExist = cphLakeApplyMapper.selectCphLakeApplyList(searchQuery).stream()
                            .filter(x-> ( (Objects.equals(x.getApplyStatus(), "3") || Objects.equals(x.getApplyStatus(), "6"))
                                && (!Objects.equals(x.getTypeCode(), "SJDXS"))
                            )
                    ).collect(Collectors.toList());
                    if(isExist.size() > 0){
                        throw new Exception("该生已通过一项百优大学生申请,建议把机会留给别的同学。");
                    }
                }
            }

            param.setUpdateTime(getNowDate());
            param.setUpdateBy(getUsername());
            int res = cphLakeApplyMapper.updateById(param);
            if(res == 1){
                return AjaxResult.success("操作成功");
            }else{
                throw new Exception("操作失败，刷新试试");
            }
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult reApplyLake(CphLakeApply param){
        try{
            Long oldId = param.getId();
            CphLakeApply old = cphLakeApplyMapper.selectCphLakeApplyById(oldId);

            if(old == null){
                throw new Exception("该记录不存在");
            }

            if(!Objects.equals(old.getApplyStatus(), "10")){
                throw new Exception("这条记录不是驳回项，不可以重新提交");
            }

            CphLakeApply searchQuery2 = new CphLakeApply();
            searchQuery2.setStuYearId(param.getStuYearId());
            searchQuery2.setStuNo(getUsername());
            searchQuery2.setTypeCode(param.getTypeCode());
            List<CphLakeApply> isExist2 = cphLakeApplyMapper.selectCphLakeApplyList(searchQuery2);
            List<CphLakeApply> isExist3 = isExist2.stream()
                    .filter(x-> (!Objects.equals(x.getApplyStatus(), "14") )
                   &&( !Objects.equals(x.getApplyStatus(), "12"))
                   &&(!Objects.equals(x.getApplyStatus(), "10")) )
                    .collect(Collectors.toList());

            if(isExist3.size() >0){
                throw new Exception("您已经申请过了。");
            }

            old.setApplyStatus("14");
            old.setUpdateBy(getUsername());
            old.setUpdateTime(getNowDate());

            int res1 = cphLakeApplyMapper.updateCphLakeApply(old);
            if(res1 == 0){
                throw new Exception("更新旧记录失败");
            }

            CphLakeApply needInsert = new CphLakeApply();
            needInsert.setStuNo(param.getStuNo());
            needInsert.setApplyStatus("1");
            needInsert.setApplyTime(getNowDate());
            needInsert.setTypeCode(param.getTypeCode());
            needInsert.setCreateBy(getUsername());
            needInsert.setStuYearId(param.getStuYearId());
            needInsert.setCreateTime(getNowDate());
            needInsert.setBankAddr(param.getBankAddr());
            needInsert.setBankCard(param.getBankCard());
            needInsert.setClassPost(param.getClassPost());
            needInsert.setZzmm(param.getZzmm());
            needInsert.setGoodHis(param.getGoodHis());
            needInsert.setMainHis(param.getMainHis());

            int res2 = cphLakeApplyMapper.insertCphLakeApply(needInsert);
            if(res2 == 0){
                throw new Exception("插入新记录失败");
            }

            return AjaxResult.success("操作成功");
        }catch (Exception ex){
            return AjaxResult.error("错误信息:"+ex.getMessage());
        }
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult applyTen(CphLakeApply param){
        try{
            CphLakeApply searchQuery1 = new CphLakeApply();
            searchQuery1.setStuNo(getUsername());
            searchQuery1.setStuYearId(param.getStuYearId());
            searchQuery1.setApplyStatus("6");
            List<CphLakeApply> isExist1 = cphLakeApplyMapper.selectCphLakeApplyList(searchQuery1);
            if(isExist1.size() == 0){
                throw new Exception("申请十佳大学生需要申请百名优秀大学生并且学工处审核通过，您不满足这个条件。");
            }

            QueryWrapper<CphTotalScore> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no",getUsername())
                    .eq("stu_year_id",param.getStuYearId());
            CphTotalScore findScore = _scoreMapper.selectOne(queryWrapper);
            if(findScore == null){
                throw new Exception("未找到该生该学年成绩记录");
            }

            BigDecimal sportScore = findScore.getSportScore();
            BigDecimal eighty = new BigDecimal("80");

            int result = sportScore.compareTo(eighty);
            if(result <0){
                throw new Exception("当前学年体能测试成绩未达到80分，不可以申请。");
            }



            String typeCode = "SJDXS";

            CphLakeApply searchQuery2 = new CphLakeApply();
            searchQuery2.setStuYearId(param.getStuYearId());
            searchQuery2.setStuNo(getUsername());
            searchQuery2.setTypeCode(typeCode);
            List<CphLakeApply> isExist2 = cphLakeApplyMapper.selectCphLakeApplyList(searchQuery2);
            List<CphLakeApply> isExist3 = isExist2.stream().filter( x-> (!Objects.equals(x.getApplyStatus(), "14") ) &&(!Objects.equals(x.getApplyStatus(), "12") )).collect(Collectors.toList());

            if(isExist3.size() >0){
                throw new Exception("您已经申请过了。");
            }

            param.setStuNo(getUsername());
            param.setApplyStatus("1");
            param.setApplyTime(getNowDate());
            param.setTypeCode(typeCode);
            param.setCreateTime(getNowDate());
            param.setCreateBy(getUsername());

            int res = cphLakeApplyMapper.insertCphLakeApply(param);
            if(res == 0){
                throw new Exception("添加记录失败，请联系管理员");
            }
            return AjaxResult.success("操作成功");

        }catch (Exception ex){
            return AjaxResult.error("错误信息:"+ex.getMessage());
        }
    }



    @Override
    public AjaxResult applyLake(CphLakeApply param){
        TransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        try{
            param.setStuNo(getUsername());
            param.setApplyStatus("1");
            param.setApplyTime(getNowDate());
            param.setCreateTime(getNowDate());
            param.setCreateBy(getUsername());
            //TODO
            QueryWrapper<CphTotalScore> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no",getUsername())
                    .eq("stu_year_id",param.getStuYearId());
            CphTotalScore findScore = _scoreMapper.selectOne(queryWrapper);
            if(findScore == null){
                throw new Exception("未找到该生该学年成绩记录");
            }

            BigDecimal sportScore = findScore.getSportScore();
            BigDecimal sixty = new BigDecimal("60");

            int result = sportScore.compareTo(sixty);
            if(result <0){
                throw new Exception("当前学年体能测试成绩未达到60分，不可以申请。");
            }

            SrsStuYear year = _yearMapper.selectSrsStuYearById(param.getStuYearId());
            String xndm = year.xndm;

            QueryWrapper<CphScienceScore> scoreQuery = new QueryWrapper<>();
            scoreQuery.eq("stu_no",param.getStuNo())
                    .eq("stu_year",xndm);
            List<CphScienceScore> scoreList = _scienceScoreMapper.selectList(scoreQuery);
            boolean hasUnPass = false;
            for(CphScienceScore score : scoreList){
                if (score.getIsPass() == 0) {
                    hasUnPass = true;
                    break;
                }
            }
            if(hasUnPass){
                throw new Exception("您当前学年有课程成绩未通过");
            }


            CphLakeApply searchQuery = new CphLakeApply();
            searchQuery.setStuNo(getUsername());
            searchQuery.setStuYearId(param.getStuYearId());
            searchQuery.setTypeCode(param.getTypeCode());
            List<CphLakeApply> isExist1 = cphLakeApplyMapper.selectCphLakeApplyList(searchQuery);
            List<CphLakeApply> isExist2 = isExist1.stream().filter( x-> (!Objects.equals(x.getApplyStatus(), "14") ) &&(!Objects.equals(x.getApplyStatus(), "12") )).collect(Collectors.toList());
            if(isExist2.size() != 0){
                throw new Exception("您之前已提交过一份此奖项的申请");
            }

            int res = cphLakeApplyMapper.insertCphLakeApply(param);
            if(res == 0){
                throw new Exception("添加记录失败，请联系管理员");
            }
            transactionManager.commit(status);
            return AjaxResult.success("操作成功");
        }catch(Exception ex){
            transactionManager.rollback(status);
            return AjaxResult.error("错误信息:"+ex.getMessage());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult cancelOwnApply(CphCancel param){
        try{
            if(param.reason == null || param.reason.equals("")){
                throw new Exception("请填写原因");
            }
            Long id = param.id;
            String stuNo = getUsername();
            CphLakeApply f = cphLakeApplyMapper.selectCphLakeApplyById(id);
            if(!Objects.equals(f.getStuNo(), stuNo)){
                throw new Exception("what do u want to do?");
            }

            if(!Objects.equals(f.getApplyStatus(), "1")){
                throw new Exception("该记录已经过审核，不可以取消申请，刷新试试");
            }

            CphGoodCancelLog log = new CphGoodCancelLog();
            log.setReason(param.reason);
            log.setIp(getLoginUser().getIpaddr());
            log.setStuNo(f.getStuNo());
            log.setTypeCode(f.getTypeCode());
            log.setCreateBy(getUsername());
            log.setCreateTime(getNowDate());
            int res3 = _logMapper.insertCphGoodCancelLog(log);
            if(res3 == 0){
                throw new Exception("插入取消记录失败，请联系管理员。");
            }

            int res = cphLakeApplyMapper.deleteCphLakeApplyById(id);
            if(res == 1){
                return AjaxResult.success("操作成功");
            }else{
                throw new Exception("操作失败，刷新试试");
            }
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }


    public List<CphLakeApplyVo> listView(CphSearch param){
        return cphLakeApplyMapper.listView(param);
    }

    public List<CphLakeApplyVo> exportView(CphSearch param){
        return cphLakeApplyMapper.exportView(param);
    }


    /**
     * 查询静湖之星申请
     *
     * @param id 静湖之星申请主键
     * @return 静湖之星申请
     */
    @Override
    public CphLakeApply selectCphLakeApplyById(Long id) {
        return cphLakeApplyMapper.selectCphLakeApplyById(id);
    }

    /**
     * 查询静湖之星申请列表
     *
     * @param cphLakeApply 静湖之星申请
     * @return 静湖之星申请
     */
    @Override
    public List<CphLakeApply> selectCphLakeApplyList(CphLakeApply cphLakeApply) {
        return cphLakeApplyMapper.selectCphLakeApplyList(cphLakeApply);
    }

    /**
     * 新增静湖之星申请
     *
     * @param cphLakeApply 静湖之星申请
     * @return 结果
     */
    @Override
    public int insertCphLakeApply(CphLakeApply cphLakeApply) {
                cphLakeApply.setCreateTime(getNowDate());
                cphLakeApply.setCreateBy(getUsername());
            return cphLakeApplyMapper.insertCphLakeApply(cphLakeApply);
    }

    /**
     * 修改静湖之星申请
     *
     * @param cphLakeApply 静湖之星申请
     * @return 结果
     */
    @Override
    public int updateCphLakeApply(CphLakeApply cphLakeApply) {
                cphLakeApply.setUpdateTime(getNowDate());
                cphLakeApply.setUpdateBy(getUsername());
        return cphLakeApplyMapper.updateCphLakeApply(cphLakeApply);
    }

    /**
     * 批量删除静湖之星申请
     *
     * @param ids 需要删除的静湖之星申请主键
     * @return 结果
     */
    @Override
    public int deleteCphLakeApplyByIds(Long[] ids) {
        return cphLakeApplyMapper.deleteCphLakeApplyByIds(ids);
    }

    /**
     * 删除静湖之星申请信息
     *
     * @param id 静湖之星申请主键
     * @return 结果
     */
    @Override
    public int deleteCphLakeApplyById(Long id) {
        return cphLakeApplyMapper.deleteCphLakeApplyById(id);
    }
}
