package com.srs.dormitory.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.srs.common.core.domain.AjaxResult;
import com.srs.dormitory.domain.*;
import com.srs.dormitory.mapper.*;
import com.srs.dormitory.service.IDmsDormitoryRecordsService;
import io.netty.util.internal.StringUtil;
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.IDmsSemesterService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

/**
 * 学期Service业务层处理
 *
 * @author srs
 * @date 2023-11-09
 */
@Service
public class DmsSemesterServiceImpl extends ServiceImpl<DmsSemesterMapper,DmsSemester> implements IDmsSemesterService {
    @Autowired
    private DmsSemesterMapper dmsSemesterMapper;
    @Autowired
    private DmsDormitoryRecordsMapper recordsMapper;
    @Autowired
    private SrsDormitoryStudentMapper srsDormitoryStudentMapper;
    @Autowired
    private DmsDormitoryMapper dormitoryMapper;
    @Autowired
    private IDmsDormitoryRecordsService recordsService;
    @Autowired
    private DmsLiveDetailMapper dmsLiveDetailMapper;
    @Autowired
    private DmsLiveDetailMapper liveDetailMapper;

    /**
     * 查询学期
     *
     * @param id 学期主键
     * @return 学期
     */
    @Override
    public DmsSemester selectDmsSemesterById(Long id) {
        return dmsSemesterMapper.selectDmsSemesterById(id);
    }

    /**
     * 查询学期列表
     *
     * @param dmsSemester 学期
     * @return 学期
     */
    @Override
    public List<DmsSemester> selectDmsSemesterList(DmsSemester dmsSemester) {
        return dmsSemesterMapper.selectDmsSemesterList(dmsSemester);
    }

    /**
     * 新增学期
     *
     * @param dmsSemester 学期
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult add(DmsSemester dmsSemester) {
        Long isCurrent = lambdaQuery().eq(DmsSemester::getIsCurrentSemester, 1).count();
        if (isCurrent > 0){
            return AjaxResult.error("当前学期未结束，无法添加新学期");
        }
        int i = dmsSemesterMapper.insertDmsSemester(dmsSemester);
        if (i<=0) return AjaxResult.error("添加失败");
        return AjaxResult.success();
    }

    /**
     * 修改学期
     *
     * @param dmsSemester 学期
     * @return 结果
     */
    @Override
    public int updateDmsSemester(DmsSemester dmsSemester) {
        return dmsSemesterMapper.updateDmsSemester(dmsSemester);
    }

    /**
     * 批量删除学期
     *
     * @param ids 需要删除的学期主键
     * @return 结果
     */
    @Override
    public int deleteDmsSemesterByIds(Long[] ids) {
        return dmsSemesterMapper.deleteDmsSemesterByIds(ids);
    }

    /**
     * 删除学期信息
     *
     * @param id 学期主键
     * @return 结果
     */
    @Override
    public int deleteDmsSemesterById(Long id) {
        return dmsSemesterMapper.deleteDmsSemesterById(id);
    }

    /**
     * 结束当前学期
     * @return
     */
    @Override
    @Transactional
    public AjaxResult over() {
        DmsSemester semester = lambdaQuery().eq(DmsSemester::getIsCurrentSemester, 1).one();
        if (semester == null) return AjaxResult.error("当前没有学期");
        List<DmsDormitoryRecords> dormitoryRecords = new ArrayList<>();
        //判断要结束的学期是上学期还是下学期 上学期则添加新的缴费信息 下学期则修改已有的缴费信息
        if (semester.getSemesterType() == 1){
            List<Map<String,String>> dormitoryStudentRecords = srsDormitoryStudentMapper.selectRecords();
            List<Map<String,String>> liveRecords1 = liveDetailMapper.selectRecords(0,semester.getId());
            Map<String, List<Map<String, String>>> liveRecords11 = liveRecords1.stream().collect(Collectors.groupingBy(map -> map.get("stuNo")));
            dormitoryStudentRecords.forEach(item ->{
                DmsDormitoryRecords records = new DmsDormitoryRecords();
                records.setYear(semester.getYear());
                records.setStuName(item.get("stuName"));
                records.setClassName(item.get("className"));
                records.setDormitoryHead(item.get("isDormitoryHead").equals("0")?"否":"是");
                records.setStandardCapacity(Long.valueOf(item.get("bed_num")));
                records.setActualOccupancy(Long.valueOf(item.get("occupancy")));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                records.setAccommodationDuration1(item.get("checkinTime")+" - "+sdf.format(semester.getEndTime()));
                records.setPhone(item.get("stuPhone").isEmpty()?"":item.get("stuPhone"));
                records.setTeacher(item.get("teacherName").isEmpty()?"":item.get("teacherName"));
                records.setTeacherPhone(item.get("teacherPhone").isEmpty()?"":item.get("teacherPhone"));
                records.setStuNo(item.get("stuNo"));
                records.setRoomNo1(item.get("roomNo"));
                records.setChargeStandard1(new BigDecimal(item.get("charge_standard")));
                BigDecimal money = BigDecimal.ZERO;
                if (!liveRecords11.get(item.get("stuNo")).isEmpty()){
                    List<Map<String, String>> liveRecords = liveRecords11.get(item.get("stuNo"));
                    long month = 0;
                    for (Map<String, String> live : liveRecords) {
                        money = money.add(new BigDecimal(live.get("money")));
                        month += Long.parseLong(live.get("duration"));
                    }
                    money = money.add(new BigDecimal(semester.getTotalMonths()-month+"").multiply(new BigDecimal(item.get("charge_standard"))));
                }else {
                    money = new BigDecimal(item.get("charge_standard")).multiply(new BigDecimal(semester.getTotalMonths()+""));
                }
                records.setAmountDue1(money);
                records.setEquivalentMonths1(new BigDecimal(semester.getTotalMonths()+""));
                dormitoryRecords.add(records);
            });
            //查询在本学期中途退宿了的学生的住宿信息
            List<Map<String,String>> liveRecords2 = liveDetailMapper.selectRecords(1,semester.getId());
            if (!liveRecords2.isEmpty()){
                Map<String, List<Map<String, String>>> liveRecords22 = liveRecords2.stream().collect(Collectors.groupingBy(map -> map.get("stuNo")));
                Set<String> keySet22 = liveRecords22.keySet();
                for (String s : keySet22) {
                    DmsDormitoryRecords records = new DmsDormitoryRecords();
                    List<Map<String, String>> maps = liveRecords22.get(s);
                    long totalMonth = 0;
                    BigDecimal money = BigDecimal.ZERO;
                    for (Map<String, String> item : maps) {
                        records.setYear(semester.getYear());
                        records.setStuName(item.get("stuName"));
                        records.setClassName(item.get("className"));
                        records.setStandardCapacity(Long.valueOf(item.get("bed_num")));
                        records.setActualOccupancy(Long.valueOf(item.get("occupancy")));
                        records.setPhone(item.get("stuPhone").isEmpty()?"":item.get("stuPhone"));
                        records.setTeacher(item.get("teacherName").isEmpty()?"":item.get("teacherName"));
                        records.setTeacherPhone(item.get("teacherPhone").isEmpty()?"":item.get("teacherPhone"));
                        records.setStuNo(item.get("stuNo"));
                        records.setRoomNo1(item.get("roomNo"));
                        records.setChargeStandard1(new BigDecimal(item.get("charge_standard")));
                        totalMonth += Long.parseLong(item.get("duration"));
                        money = money.add(new BigDecimal(item.get("money")));
                    }
                    records.setAccommodationDuration1(totalMonth+"");
                    records.setAmountDue1(money);
                    dormitoryRecords.add(records);
                }
                recordsService.saveBatch(dormitoryRecords);
            }
        //下学期则直接修改费用数据
        }else {
            List<DmsDormitoryRecords> recordsList = new LambdaQueryChainWrapper<>(recordsMapper)
                    .eq(DmsDormitoryRecords::getYear, semester.getYear())
                    .list();
            List<Map<String, String>> records = srsDormitoryStudentMapper.selectRecords();
            Map<String,Map<String,String>> data = new HashMap<>();
            records.forEach(item -> {
                data.put(item.get("stuNo"),item);
            });
            List<Map<String, String>> records1 = liveDetailMapper.selectRecords(1, semester.getId());
            Map<String, List<Map<String, String>>> records11 = records1.stream().collect(Collectors.groupingBy(map -> map.get("stuNo")));
            List<Map<String, String>> records0 = liveDetailMapper.selectRecords(0, semester.getId());
            Map<String, List<Map<String, String>>> records00 = records0.stream().collect(Collectors.groupingBy(map -> map.get("stuNo")));
            for (DmsDormitoryRecords item : recordsList) {
                if (data.get(item.getStuNo()) != null){
                    Map<String, String> map = data.get(item.getStuNo());
                    item.setRoomNo2(map.get("roomNo"));
                    item.setActualOccupancy2(Long.valueOf(map.get("occupancy")));
                    item.setChargeStandard2(new BigDecimal(map.get("chargeStandard")));
                    item.setStandardCapacity2(Long.valueOf(map.get("bedNum")));
                    item.setEquivalentMonths2(new BigDecimal(semester.getTotalMonths()));
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    item.setAccommodationDuration2(map.get("checkinTime")+" - "+sdf.format(semester.getEndTime()));
                    BigDecimal money = BigDecimal.ZERO;
                    long month = 0;
                    if (!records00.get(item.getStuNo()).isEmpty()){
                        for (Map<String, String> m : records00.get(item.getStuNo())) {
                            money = money.add(new BigDecimal(m.get("money")));
                            month += Long.parseLong(m.get("duration"));
                        }
                    }
                    money = money.add(new BigDecimal(semester.getTotalMonths()-month+"").multiply(new BigDecimal(map.get("charge_standard"))));
                    item.setAmountDue2(money);
                }else {
                    List<Map<String, String>> maps = records11.get(item.getStuNo());
                    BigDecimal money = BigDecimal.ZERO;
                    long totalMonth = 0;
                    for (Map<String, String> map : maps) {
                        item.setStandardCapacity2(Long.valueOf(map.get("bed_num")));
                        item.setActualOccupancy2(Long.valueOf(map.get("occupancy")));
                        item.setRoomNo2(map.get("roomNo"));
                        item.setChargeStandard2(new BigDecimal(map.get("charge_standard")));
                        totalMonth += Long.parseLong(map.get("duration"));
                        money = money.add(new BigDecimal(map.get("money")));
                    }
                    item.setEquivalentMonths2(new BigDecimal(totalMonth));
                    item.setAmountDue2(money);
                }

            }
            recordsService.updateBatchById(dormitoryRecords);
        }
        semester.setIsCurrentSemester(0);
        boolean b = updateById(semester);
        if (!b) throw new RuntimeException("修改学期信息失败");
        return AjaxResult.success();
    }
}
