package com.srs.comprehensive.service.impl;

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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.*;
import com.srs.comprehensive.mapper.*;
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.ICphBiyeApplyService;
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 org.springframework.web.bind.annotation.RequestBody;

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 2024-01-05
 */
@Service
public class CphBiyeApplyServiceImpl extends ServiceImpl<CphBiyeApplyMapper,CphBiyeApply> implements ICphBiyeApplyService {
    @Autowired
    private CphBiyeApplyMapper cphBiyeApplyMapper;
    @Autowired
    private CphGoodCancelLogMapper _cancelMapper;
    @Autowired
    private SrsStudentMapper _stuMapper;
    @Autowired
    private SrsClassMapper _classMapper;
    @Autowired
    private SrsGradeMapper _gradeMapper;

    @Autowired
    private CphTotalScoreMapper _totalMapper;
    @Autowired
    private SrsStuYearMapper _yearMapper;

    @Autowired
    public PlatformTransactionManager transactionManager;

    @Override
    public AjaxResult getStuScoreMajorRank(String stuNo){
        try{
            CphClassRankScore res = cphBiyeApplyMapper.getOwnStuScoreMajorRank(stuNo);
            return AjaxResult.success(res);
        }catch (Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }

    @Override
    public AjaxResult listStuSportScore(String stuNo){
        try{
            QueryWrapper<SrsStuYear> yearQueryWrapper = new QueryWrapper<>();
            yearQueryWrapper.eq("status",1);
            List<SrsStuYear> nowYear = _yearMapper.selectList(yearQueryWrapper);

            List<Long> nowYearId = new ArrayList<>();
            nowYear.forEach(x->{
                nowYearId.add(x.getId());
            });

            MPJLambdaWrapper<CphTotalScore> query =  JoinWrappers.lambda(CphTotalScore.class)
                    .selectAll(CphTotalScore.class)
                    .selectAs(SrsStuYear::getStuYearName,CphTotalScoreStuYearName::getStuYearName)
                    .leftJoin(SrsStuYear.class,SrsStuYear::getId,CphTotalScore::getStuYearId)
                    .eq(CphTotalScore::getStuNo,stuNo);
            if(nowYearId.size() != 0){
                query.notIn(CphTotalScore::getStuYearId,nowYearId);
            }

            List<CphTotalScoreStuYearName> list = _totalMapper.selectJoinList(CphTotalScoreStuYearName.class, query);

            return AjaxResult.success(list);
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }



    @Override
    public AjaxResult cancelApply(CphCancel param){
        TransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        try{
            Long id = param.id;
            CphBiyeApply find = cphBiyeApplyMapper.selectCphBiyeApplyById(id);
            if(!find.getStuNo().equals(getUsername())){
                throw new Exception("不是本人操作");
            }

            if(!Objects.equals(find.getApplyStatus(), "1")){
                throw new Exception("已审核，不能取消申请");
            }
            int res = cphBiyeApplyMapper.deleteCphBiyeApplyById(id);
            if(res == 0){
                throw new Exception("取消失败");
            }

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

            transactionManager.commit(status);
            return AjaxResult.success();
        }catch(Exception ex){
            transactionManager.rollback(status);
            return AjaxResult.error(ex.getMessage());
        }
    }

    @Override
    public AjaxResult reApply(@RequestBody CphBiyeApply param){
        try{
            Long oldId = param.getId();
            CphBiyeApply old = cphBiyeApplyMapper.selectCphBiyeApplyById(oldId);

            String nowUser = getUsername();


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

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

            CphBiyeApply searchQuery2 = new CphBiyeApply();
            searchQuery2.setStuYearId(param.getStuYearId());
            searchQuery2.setStuNo(getUsername());
            List<CphBiyeApply> isExist2 = cphBiyeApplyMapper.selectCphBiyeApplyList(searchQuery2);
            List<CphBiyeApply> 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 = cphBiyeApplyMapper.updateCphBiyeApply(old);
            if(res1 == 0){
                throw new Exception("更新旧记录失败");
            }

            CphBiyeApply needInsert = new CphBiyeApply();
            needInsert.setStuNo(old.getStuNo());
            needInsert.setApplyStatus("1");
            needInsert.setCreateBy(getUsername());
            needInsert.setStuYearId(param.getStuYearId());
            needInsert.setCreateTime(getNowDate());
            needInsert.setClassPost(param.getClassPost());
            needInsert.setZzmm(param.getZzmm());
            needInsert.setYouthStudy(param.getYouthStudy());
            needInsert.setClassTwo(param.getClassTwo());
            needInsert.setGoodHis(param.getGoodHis());
            needInsert.setMainHis(param.getMainHis());

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

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



    @Override
    public AjaxResult doApply(CphBiyeApply param){
        try{
            QueryWrapper<CphTotalScore> totalScoreQueryWrapper = new QueryWrapper<>();
            totalScoreQueryWrapper.eq("stu_no",getUsername());

            List<CphTotalScore> scoreList = _totalMapper.selectList(totalScoreQueryWrapper);

            SrsStudent student = _stuMapper.selectSrsStudentByStuNo(getUsername());
            if(student == null){
                throw new Exception("学生信息不存在");
            }

            Long classId = student.getClassId();

            SrsClass srsClass = _classMapper.selectById(classId);
            if(srsClass == null){
                throw new Exception("班级信息不存在");
            }
            Long gradeId = srsClass.getGradeId();
            SrsGrade srsGrade = _gradeMapper.selectById(gradeId);
            if(srsGrade == null){
                throw new Exception("年级信息不存在");
            }

            String gradeCode = srsGrade.getGradeCode();

            for (CphTotalScore score:scoreList ) {
                BigDecimal sportScore = score.getSportScore();
                BigDecimal sixty = new BigDecimal("60");
                int result = sportScore.compareTo(sixty);
                SrsStuYear srsStuYear = _yearMapper.selectById(score.getStuYearId());
                if(srsStuYear == null){
                    throw new Exception("学年信息不存在");
                }
                String yearCode = srsStuYear.getXndm();
                if(Integer.parseInt(yearCode) >= Integer.parseInt(gradeCode)){
                    if (result < 0 && !Objects.equals(score.getStuYearId(), param.getStuYearId())){
                        throw new Exception("您有一学年的体育成绩未达到60分，不能参与申请");
                    }
                }
            }

            List<String> notStatus = new ArrayList<>();
            notStatus.add("11");
            notStatus.add("10");
            notStatus.add("1");
            notStatus.add("2");
            notStatus.add("3");
            notStatus.add("6");


            param.setStuNo(getUsername());
            QueryWrapper<CphBiyeApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no",param.getStuNo())
                    .eq("stu_year_id",param.getStuYearId())
                    .in("apply_status",notStatus );
            List<CphBiyeApply> isExist = cphBiyeApplyMapper.selectList(queryWrapper);
            if(isExist.size() >0){
                throw new Exception("您已经提交过了");
            }
            param.setApplyStatus("1");

            int res = cphBiyeApplyMapper.insert(param);
            if(res == 0){
                throw new Exception("插入申请记录失败");
            }

            return AjaxResult.success();
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }



    @Override
    public List<CphBiyeApplyVo> listOwnApply(){
        String stuNo = getUsername();

        MPJLambdaWrapper<CphBiyeApply> query = JoinWrappers.lambda(CphBiyeApply.class)
                .selectAll(CphBiyeApply.class)
                .selectAs(SrsStuYear::getStuYearName,CphBiyeApplyVo::getStuYearName)
                .leftJoin(SrsStuYear.class,SrsStuYear::getId,CphBiyeApply::getStuYearId)
                .eq(CphTotalScore::getStuNo,stuNo)
                .orderByAsc("id");

        List<CphBiyeApplyVo> list = cphBiyeApplyMapper.selectJoinList(CphBiyeApplyVo.class, query);
        return list;
    }

    @Override
    public List<CphBiyeApplyVo> listView(CphSearch param){
        return cphBiyeApplyMapper.listView(param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult doAudit(CphBiyeApply param){
        try{
            param.setUpdateTime(getNowDate());
            param.setUpdateBy(getUsername());
            int res = cphBiyeApplyMapper.updateById(param);
            if(res == 1){
                return AjaxResult.success("操作成功");
            }else{
                throw new Exception("操作失败，刷新试试");
            }
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }

    @Override
    public List<CphBiyeApplyVo> exportView(CphSearch param){
        return cphBiyeApplyMapper.exportView(param);
    }

    @Override
    public AjaxResult manyAudit(CphAuditMany param){
        try{
            String applyStatus = "6";

            Long[] applyIds = param.applyIds;

            List<Long> applyIdList = new ArrayList<>(Arrays.asList(applyIds));

            QueryWrapper<CphBiyeApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id",applyIdList);

            List<CphBiyeApply> needUpdateAudit = cphBiyeApplyMapper.selectList(queryWrapper);

            for(CphBiyeApply item : needUpdateAudit ){
                item.setJwcCmt(param.common);
                item.setXgNo(getUsername());
                item.setXgTime(getNowDate());
                item.setApplyStatus(applyStatus);
                item.setUpdateTime(getNowDate());
                item.setUpdateBy(getUsername());
                cphBiyeApplyMapper.updateById(item);
            }

            return AjaxResult.success("操作成功");
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }

    @Override
    public AjaxResult xwManyAudit(CphAuditMany param){
        try{
            String applyStatus = "3";

            Long[] applyIds = param.applyIds;

            List<Long> applyIdList = new ArrayList<>(Arrays.asList(applyIds));

            QueryWrapper<CphBiyeApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id",applyIdList);

            List<CphBiyeApply> needUpdateAudit = cphBiyeApplyMapper.selectList(queryWrapper);

            for(CphBiyeApply item : needUpdateAudit ){
                item.setXwCmt(param.common);
                item.setXwNo(getUsername());
                item.setXwTime(getNowDate());
                item.setApplyStatus(applyStatus);
                item.setUpdateTime(getNowDate());
                item.setUpdateBy(getUsername());
                cphBiyeApplyMapper.updateById(item);
            }

            return AjaxResult.success("操作成功");
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }





    /**
     * 查询优秀毕业生
     *
     * @param id 优秀毕业生主键
     * @return 优秀毕业生
     */
    @Override
    public CphBiyeApply selectCphBiyeApplyById(Long id) {
        return cphBiyeApplyMapper.selectCphBiyeApplyById(id);
    }

    /**
     * 查询优秀毕业生列表
     *
     * @param cphBiyeApply 优秀毕业生
     * @return 优秀毕业生
     */
    @Override
    public List<CphBiyeApply> selectCphBiyeApplyList(CphBiyeApply cphBiyeApply) {
        return cphBiyeApplyMapper.selectCphBiyeApplyList(cphBiyeApply);
    }

    /**
     * 新增优秀毕业生
     *
     * @param cphBiyeApply 优秀毕业生
     * @return 结果
     */
    @Override
    public int insertCphBiyeApply(CphBiyeApply cphBiyeApply) {
                cphBiyeApply.setCreateTime(DateUtils.getNowDate());
            return cphBiyeApplyMapper.insertCphBiyeApply(cphBiyeApply);
    }

    /**
     * 修改优秀毕业生
     *
     * @param cphBiyeApply 优秀毕业生
     * @return 结果
     */
    @Override
    public int updateCphBiyeApply(CphBiyeApply cphBiyeApply) {
                cphBiyeApply.setUpdateTime(DateUtils.getNowDate());
        return cphBiyeApplyMapper.updateCphBiyeApply(cphBiyeApply);
    }

    /**
     * 批量删除优秀毕业生
     *
     * @param ids 需要删除的优秀毕业生主键
     * @return 结果
     */
    @Override
    public int deleteCphBiyeApplyByIds(Long[] ids) {
        return cphBiyeApplyMapper.deleteCphBiyeApplyByIds(ids);
    }

    /**
     * 删除优秀毕业生信息
     *
     * @param id 优秀毕业生主键
     * @return 结果
     */
    @Override
    public int deleteCphBiyeApplyById(Long id) {
        return cphBiyeApplyMapper.deleteCphBiyeApplyById(id);
    }
}
