package com.srs.dormitory.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.srs.common.core.domain.AjaxResult;
import com.srs.comprehensive.domain.SrsStuYear;
import com.srs.comprehensive.domain.SrsStudent;
import com.srs.comprehensive.domain.Vo.CphSearch;
import com.srs.comprehensive.mapper.SrsStuYearMapper;
import com.srs.comprehensive.mapper.SrsStudentMapper;
import com.srs.dormitory.domain.*;
import com.srs.dormitory.mapper.*;
import liquibase.pro.packaged.A;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.srs.dormitory.service.IDmsNewTaskService;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import static com.srs.common.utils.DateUtils.getNowDate;

/**
 * 宿舍调整任务Service业务层处理
 *
 * @author srs
 * @date 2024-03-19
 */
@Service
public class DmsNewTaskServiceImpl extends ServiceImpl<DmsNewTaskMapper,DmsNewTask> implements IDmsNewTaskService {
    @Autowired
    private DmsNewTaskMapper dmsNewTaskMapper;
    @Autowired
    public SrsDormitoryStudentMapper _srsDormStuMapper;
    @Autowired
    public DmsNewRangeMapper _rangeMapper;
    @Autowired
    public DmsNewRecordMapper _recordMapper;
    @Autowired
    public DmsDormitoryMapper _dormMapper;
    @Autowired
    public SrsStuYearMapper _yearMapper;
    @Autowired
    public SrsStudentMapper _stuMapper;

    @Autowired
    public PlatformTransactionManager transactionManager;

    @Override
    public AjaxResult nowDoTask(Long taskId){
        TransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        try{
            String needResMsg = "操作成功。";
            DmsNewTask task = dmsNewTaskMapper.selectDmsNewTaskById(taskId); //查询需要执行的任务id

            if(task == null){
                throw new Exception("该任务不存在");
            }

            if(Objects.equals(task.getTaskStatus(), "1")){
                throw new Exception("该任务已成功执行过，不能再次执行");
            }

            Long oldDormId = task.getOldDormId(); //旧宿舍id
            Long newDormId = task.getNewDormId(); //新宿舍id
            String stuNo = task.getStuNo(); //需要调整的学生的学号


            QueryWrapper<DmsNewRange> rangeQuery = new QueryWrapper<>(); //构造住宿区间的查询构造器
            rangeQuery.eq("range_status",'1')
                    .orderByDesc("id")
                    .last("limit 1"); //获取最新的正在启用的住宿区间
            DmsNewRange nowRange = _rangeMapper.selectOne(rangeQuery); //通过查询构造器查出最新的住宿区间

            if(nowRange == null){
                throw new Exception("当前未开启住宿区间");
            }


            QueryWrapper<SrsStuYear> yearQuery = new QueryWrapper<>(); //构造学年的查询构造第
            yearQuery.eq("xndm", nowRange.getXndm()); //通过学年代码进行查询
            SrsStuYear year = _yearMapper.selectOne(yearQuery); //通过学年代码查询学年

            if(year == null){
                throw new Exception("学年不存在");
            }

            Date checkInTime = getNowDate();
            Instant instant = checkInTime.toInstant();
            LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();

            QueryWrapper<DmsNewRecord> recordQuery = new QueryWrapper<>();
            recordQuery.eq("stu_no",stuNo)
                    .orderByDesc("id")
                    .last("limit 1");

            DmsDormitory oldDorm = _dormMapper.selectById(oldDormId);

            if(oldDorm == null){
                throw new Exception("旧宿舍不存在");
            }

            DmsNewRecord needUpdateRecord = _recordMapper.selectOne(recordQuery);
            if(needUpdateRecord == null){
                needResMsg += "该生的银行卡信息未完善，请联系该生及时填写。";
                needUpdateRecord = new DmsNewRecord();
                needUpdateRecord.setStuNo(stuNo);
                needUpdateRecord.setRoomId(oldDormId);
                needUpdateRecord.setStartDate(nowRange.getStartDate());
                needUpdateRecord.setEndDate(checkInTime);
                needUpdateRecord.setApplyStatus("6");
                needUpdateRecord.setStuYearId(year.getId());
                needUpdateRecord.setRangeCode(nowRange.getRangeCode());
                int res = _recordMapper.insert(needUpdateRecord);
                if(res == 0){
                    throw new Exception("该生原本不在学生住宿记录表中，现插入也失败");
                }
            }

            Calendar endTime = Calendar.getInstance();
            Calendar startTime = Calendar.getInstance();
            startTime.setTime(needUpdateRecord.getStartDate());
            endTime.setTime(checkInTime);
            endTime.add(Calendar.DATE, -1);

            int i1 = startTime.get(Calendar.DAY_OF_MONTH);
            int i2 = endTime.get(Calendar.DAY_OF_MONTH);
            double month = 0.5;
            if (i2 >= 15 && i1 <= 15) month = 1;
            int yearDiff = endTime.get(Calendar.YEAR) - startTime.get(Calendar.YEAR);
            int monthDiff = endTime.get(Calendar.MONTH) - startTime.get(Calendar.MONTH);
            double totalMonthDiff = yearDiff * 12 + monthDiff + month;

            needUpdateRecord.setInMonth(new BigDecimal(totalMonthDiff));
            needUpdateRecord.setNeedMoney(needUpdateRecord.getInMonth().multiply(oldDorm.getChargeStandard().divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP)));
            needUpdateRecord.setMainMoney(oldDorm.getChargeStandard());
            needUpdateRecord.setEndDate(endTime.getTime());

            int res = _recordMapper.updateById(needUpdateRecord);
            if(res == 0){
                throw new Exception("更新学生旧宿舍费用记录失败");
            }

            if(Objects.equals(task.getTaskType(), "1")){ //如果执行的是调宿任务
                QueryWrapper<SrsDormitoryStudent> srsDormStuQuery = new QueryWrapper<>(); //构造学生宿舍表的查询构造器
                srsDormStuQuery.eq("stu_no",stuNo)
                        .orderByDesc("id")
                        .last("limit 1"); //通过学号查询最新的学生宿舍信息
                SrsDormitoryStudent srsDormitoryStudent = _srsDormStuMapper.selectOne(srsDormStuQuery); //进行查询
                if(srsDormitoryStudent == null){ //如果该学生不存在学生宿舍表中

                    SrsDormitoryStudent needInsertSrsDormStu = new SrsDormitoryStudent();
                    needInsertSrsDormStu.setStuNo(stuNo);
                    needInsertSrsDormStu.setDormitoryId(newDormId);

                    needInsertSrsDormStu.setCheckinTime(localDateTime);
                    int res1 = _srsDormStuMapper.insert(needInsertSrsDormStu); //就插入一条
                    if(res1 == 0){
                        throw new Exception("该生原本不在宿舍学生表中，现插入也失败");
                    }
                }else{
                    srsDormitoryStudent.setDormitoryId(newDormId);
                    int res1 = _srsDormStuMapper.updateById(srsDormitoryStudent);
                    if(res1 == 0){
                        throw new Exception("更新学生宿舍表失败");
                    }
                }

                QueryWrapper<SrsStudent> stuQuery = new QueryWrapper<>();
                stuQuery.eq("stu_no",stuNo)
                        .last("limit 1");
                SrsStudent stu = _stuMapper.selectOne(stuQuery);
                if(stu == null){
                    throw new Exception("该生不存在");
                }

                DmsNewRecord needInsertRecord = new DmsNewRecord();
                needInsertRecord.setBankCard(stu.xhk);
                needInsertRecord.setStuNo(stuNo);
                needInsertRecord.setRoomId(newDormId);
                needInsertRecord.setStartDate(checkInTime);
                needInsertRecord.setEndDate(nowRange.getEndDate());


                DmsDormitory newDorm = _dormMapper.selectById(newDormId);

                if(newDorm == null){
                    throw new Exception("该宿舍不存在，请重新选择宿舍");
                }

                Calendar endTime1 = Calendar.getInstance();
                Calendar startTime1 = Calendar.getInstance();
                startTime1.setTime(checkInTime);
                endTime1.setTime(nowRange.getEndDate());

                int i11 = startTime1.get(Calendar.DAY_OF_MONTH);
                int i21 = endTime1.get(Calendar.DAY_OF_MONTH);
                double month1 = 0.5;
                if (i21 >= 15 && i11 <= 15) month1 = 1;
                int yearDiff1 = endTime1.get(Calendar.YEAR) - startTime1.get(Calendar.YEAR);
                int monthDiff1 = endTime1.get(Calendar.MONTH) - startTime1.get(Calendar.MONTH);
                double totalMonthDiff1 = yearDiff1 * 12 + monthDiff1 + month1;

                needInsertRecord.setInMonth(new BigDecimal(totalMonthDiff1));
                needInsertRecord.setRangeCode(nowRange.getRangeCode());
                needInsertRecord.setNeedMoney(needInsertRecord.getInMonth().multiply(newDorm.getChargeStandard().divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP)));
                needInsertRecord.setMainMoney(newDorm.getChargeStandard());
                needInsertRecord.setApplyStatus("6");
                needInsertRecord.setStuYearId(year.getId());

                int res1 = _recordMapper.insert(needInsertRecord);
                if(res1 == 0){
                    throw new Exception("插入新的住宿费用记录失败");
                }
            }

            if(Objects.equals(task.getTaskType(), "2")){
                QueryWrapper<SrsDormitoryStudent> deleteStuDormQuery = new QueryWrapper<>();
                deleteStuDormQuery.eq("stu_no",stuNo);
                _srsDormStuMapper.delete(deleteStuDormQuery);
            }

            task.setTaskStatus("1");
            task.setTaskRun(getNowDate());
            int res2 = dmsNewTaskMapper.updateById(task);
            if(res2 == 0){
                throw new Exception("更新任务状态失败");
            }

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

    @Override
    public AjaxResult listView(CphSearch param){
        return AjaxResult.success(dmsNewTaskMapper.listView(param));
    }


    /**
     * 查询宿舍调整任务
     *
     * @param id 宿舍调整任务主键
     * @return 宿舍调整任务
     */
    @Override
    public DmsNewTask selectDmsNewTaskById(Long id) {
        return dmsNewTaskMapper.selectDmsNewTaskById(id);
    }

    /**
     * 查询宿舍调整任务列表
     *
     * @param dmsNewTask 宿舍调整任务
     * @return 宿舍调整任务
     */
    @Override
    public List<DmsNewTask> selectDmsNewTaskList(DmsNewTask dmsNewTask) {
        return dmsNewTaskMapper.selectDmsNewTaskList(dmsNewTask);
    }

    /**
     * 新增宿舍调整任务
     *
     * @param dmsNewTask 宿舍调整任务
     * @return 结果
     */
    @Override
    public int insertDmsNewTask(DmsNewTask dmsNewTask) {
            return dmsNewTaskMapper.insertDmsNewTask(dmsNewTask);
    }

    /**
     * 修改宿舍调整任务
     *
     * @param dmsNewTask 宿舍调整任务
     * @return 结果
     */
    @Override
    public int updateDmsNewTask(DmsNewTask dmsNewTask) {
        return dmsNewTaskMapper.updateDmsNewTask(dmsNewTask);
    }

    /**
     * 批量删除宿舍调整任务
     *
     * @param ids 需要删除的宿舍调整任务主键
     * @return 结果
     */
    @Override
    public int deleteDmsNewTaskByIds(Long[] ids) {
        return dmsNewTaskMapper.deleteDmsNewTaskByIds(ids);
    }

    /**
     * 删除宿舍调整任务信息
     *
     * @param id 宿舍调整任务主键
     * @return 结果
     */
    @Override
    public int deleteDmsNewTaskById(Long id) {
        return dmsNewTaskMapper.deleteDmsNewTaskById(id);
    }
}
