package com.srs.comprehensive.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.srs.common.annotation.DataSource;
import com.srs.common.enums.DataSourceType;
import com.srs.comprehensive.domain.CphStuScoreMiddle;
import com.srs.comprehensive.domain.Dto.CphStuScoreMiddleDto;
import com.srs.comprehensive.domain.Vo.CphStuScoreMiddleDtoVo;
import com.srs.comprehensive.mapper.CphStuScoreMiddleDtoMapper;
import com.srs.comprehensive.mapper.CphStuScoreMiddlesMapper;
import com.srs.comprehensive.service.ICphStuScoreMiddlesService;
import com.srs.comprehensive.util.ListSliceUtil;
import com.srs.comprehensive.config.SyncConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class CphStuScoreMiddlesServiceImpl implements ICphStuScoreMiddlesService {

    @Autowired
    private CphStuScoreMiddlesMapper cphStuScoreMiddlesMapper;

    @Autowired
    private CphStuScoreMiddleDtoMapper cphStuScoreMiddleDtoMapper;
    
    @Autowired
    private SyncConfig syncConfig;

    @Override
    @DataSource(DataSourceType.DATABASE)//sqlserver
    public List<CphStuScoreMiddle> serectCphStuScoreMiddlesAdd() {
        List<CphStuScoreMiddle> cphStuScoreMiddles = cphStuScoreMiddlesMapper.selectList(null);//sql
        return cphStuScoreMiddles;
    }

    //分页查询学生成绩
    @Override
    @DataSource(DataSourceType.DATABASE)//sqlserver
    public List<Map<String,Object>> serectCphStuScoreMiddlesXh(int page, int pageSize,String xh) {
        return cphStuScoreMiddlesMapper.CphStuScoreMiddlePages(page,pageSize,xh);
    }

    //查询总数
    @Override
    @DataSource(DataSourceType.DATABASE)//sqlserver
    public int serectCphStuScoreMiddleCount(String stuNo) {
        return cphStuScoreMiddlesMapper.CphStuScoreMiddleCount(stuNo);
    }

    @Override
    public void typeConversion(List<Map<String,Object>> mapList){
        ArrayList<CphStuScoreMiddle> cphStuScoreMiddleArrayList = new ArrayList<>();

    }

    @Override
    @DataSource(DataSourceType.MASTER)//mysql
    //@Transactional(rollbackFor=Exception.class)
    public List<Map<String,Object>> insertCphStuScoreMiddlesDel(List<Map<String,Object>> cphStuScoreMiddleList) {
        List<Map<String,Object>> stuScoreMiddleAddData = new ArrayList<>(cphStuScoreMiddleList);
        Long aLong = cphStuScoreMiddleDtoMapper.selectCount(null);//总数
        int pageNum=1;
        int pageSize=50;
        long sum=aLong/ pageSize;//需要循环的次数
        long sumS=aLong%pageSize>0? sum + 1: sum;
        QueryWrapper<CphStuScoreMiddleDto> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.orderByDesc("stu_no", "kcdm");
        for (pageNum=1; pageNum <= sumS; pageNum++) {
            List<CphStuScoreMiddleDto> cphStuScoreMiddleDtos = cphStuScoreMiddleDtoMapper
                    .selectPage(new Page<>(pageNum, pageSize), objectQueryWrapper).getRecords();

            // 修改
            List<CphStuScoreMiddleDto> intersection = new ArrayList<>();
            for (CphStuScoreMiddleDto dto : cphStuScoreMiddleDtos) {
                for (Map<String, Object> middle : cphStuScoreMiddleList) {
                    if (dto.getStuNo().equals(middle.get("XH").toString())
                            && dto.getKcdm().equals(middle.get("KCDM").toString())) {
                        CphStuScoreMiddleDto cphStuScoreMiddleDto = new CphStuScoreMiddleDto();
                        cphStuScoreMiddleDto.setId(dto.getId());
                        if (middle.get("XQMC") != null) {
                            cphStuScoreMiddleDto.setXqdm(middle.get("XQMC").toString());
                        }
                        if (middle.get("XSHDXF") != null) {
                            cphStuScoreMiddleDto.setXf(new BigDecimal(middle.get("XSHDXF").toString()));
                        }
                        if (middle.get("CJ") != null) {
                            if (Objects.equals(middle.get("CJ").toString(), "不合格")) {
                                cphStuScoreMiddleDto.setCj("45.00");
                            } else if (Objects.equals(middle.get("CJ").toString(), "合格")) {
                                cphStuScoreMiddleDto.setCj("65.00");
                            } else if (Objects.equals(middle.get("CJ").toString(), "中等")) {
                                cphStuScoreMiddleDto.setCj("75.00");
                            } else if (Objects.equals(middle.get("CJ").toString(), "良好")) {
                                cphStuScoreMiddleDto.setCj("85.00");
                            } else if (Objects.equals(middle.get("CJ").toString(), "优秀")) {
                                cphStuScoreMiddleDto.setCj("95.00");
                            } else if (Objects.equals(middle.get("CJ").toString(), "0.00")||
                                    Objects.equals(middle.get("CJ").toString(), "")||
                                    Objects.equals(middle.get("CJ").toString(), null)||
                                    Objects.equals(middle.get("CJ").toString(), "NULL")||
                                    Objects.equals(middle.get("CJ").toString(), "null")) {
                                if (middle.get("BkScore")!=null){
                                    if (
                                        !Objects.equals(middle.get("BkScore").toString(), "")||
                                        !Objects.equals(middle.get("BkScore").toString(), "null")||
                                        !Objects.equals(middle.get("BkScore").toString(), "NULL")||
                                        !Objects.equals(middle.get("BkScore").toString(), null)){
                                            cphStuScoreMiddleDto.setCj(middle.get("BkScore").toString());
                                    } else {
                                        cphStuScoreMiddleDto.setCj(middle.get("CJ").toString());
                                    }
                                }else {
                                    cphStuScoreMiddleDto.setCj(middle.get("CJ").toString());
                                }
                            } else{
                                cphStuScoreMiddleDto.setCj(middle.get("CJ").toString());
                            }
                        }
                        if (middle.get("XSHDJD") != null) {
                            cphStuScoreMiddleDto.setJd(new BigDecimal(middle.get("XSHDJD").toString()));
                        }
                        if (middle.get("FZLX") != null) {
                            cphStuScoreMiddleDto.setFzlx(Long.parseLong(middle.get("FZLX").toString()));
                        }
                        if (middle.get("XH") != null) {
                            cphStuScoreMiddleDto.setStuNo(middle.get("XH").toString());
                        }
                        if (middle.get("KCDM") != null) {
                            cphStuScoreMiddleDto.setKcdm(middle.get("KCDM").toString());
                        }
                        if (middle.get("passed") != null) {
                            cphStuScoreMiddleDto.setIsPass(middle.get("passed").toString());
                        }
                        intersection.add(cphStuScoreMiddleDto);
                        break;
                    }
                }
            }
            if (intersection.size() != 0) {
                List<List<CphStuScoreMiddleDto>> lists = ListSliceUtil.updateSlice(intersection);
                if (lists != null) {
                    for (List<CphStuScoreMiddleDto> dto : lists) {
                        cphStuScoreMiddleDtoMapper.updateBatchByIdList(dto);//批量更新
                    }
                }
            }
            // 添加
            List<Map<String, Object>> difference = new ArrayList<>(cphStuScoreMiddleList);
            //List<Map<String, Object>> differenceCopy = new ArrayList<>(cphStuScoreMiddleList);
            for (Map<String, Object> dtoS : difference) {//所有的减去交集
                for (CphStuScoreMiddleDto middleDto : intersection) {
                    if (dtoS.get("XH").toString().equals(middleDto.getStuNo()) &&
                            dtoS.get("KCDM").toString().equals(middleDto.getKcdm())) {
                        stuScoreMiddleAddData.remove(dtoS);
                        break;
                    }
                }
            }

//            List<CphStuScoreMiddleDto> cphStuScoreMiddleDto = differenceCopy.stream()
//                    .map(m -> convertToB(m)).collect(Collectors.toList());
//            if (!cphStuScoreMiddleDto.isEmpty()) {
//                cphStuScoreMiddleDtoMapper.insertBatchSomeColumn(cphStuScoreMiddleDto);//添加
//            }
            cphStuScoreMiddleDtos.clear();
        }
        return stuScoreMiddleAddData;
    }

    @Override
    public void syncCphStuScoreMiddles() {
            List<CphStuScoreMiddle> cphStuScoreMiddles = serectCphStuScoreMiddlesAdd();
            //insertCphStuScoreMiddlesDel(cphStuScoreMiddles);
    }

    @DataSource(DataSourceType.MASTER)//mysql
    //@Transactional(rollbackFor=Exception.class)
    public List<CphStuScoreMiddleDtoVo> insertCphStuScoreMiddlesDelS(String stuNo) {
        return cphStuScoreMiddleDtoMapper.getCphStuScoreMiddleAll(stuNo);
    }

    //转换
    private CphStuScoreMiddleDto convertToB(Map<String,Object> a) {
        if (a == null) {
            return null;
        }
        
        try {
            CphStuScoreMiddleDto b = new CphStuScoreMiddleDto();
            
            // 设置学号和课程代码（必要字段）
            b.setStuNo(getStringValue(a, "XH"));
            b.setKcdm(getStringValue(a, "KCDM"));
            b.setXqid(1L);
            
            // 处理成绩字段
            String score = processScore(a);
            b.setCj(score);
            
            // 设置其他字段
            b.setXndm(getStringValue(a, "XND"));
            b.setXqdm(getStringValue(a, "XQMC"));
            
            // 处理数值类型字段
            setBigDecimalValue(b::setXf, a, "XSHDXF");
            setBigDecimalValue(b::setJd, a, "XSHDJD");
            setLongValue(b::setFzlx, a, "FZLX");
            
            // 设置是否通过
            b.setIsPass(getStringValue(a, "Passed"));
            
            return b;
            
        } catch (Exception e) {
            System.err.println("转换数据时发生错误: " + e.getMessage());
            return null;
        }
    }
    
    /**
     * 安全获取字符串值
     */
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        String strValue = value.toString().trim();
        return strValue.isEmpty() || "null".equalsIgnoreCase(strValue) || "NULL".equals(strValue) ? null : strValue;
    }
    
    /**
     * 安全设置BigDecimal值
     */
    private void setBigDecimalValue(java.util.function.Consumer<BigDecimal> setter, Map<String, Object> map, String key) {
        try {
            String value = getStringValue(map, key);
            if (value != null) {
                setter.accept(new BigDecimal(value));
            }
        } catch (NumberFormatException e) {
            // 忽略格式错误，保持null值
        }
    }
    
    /**
     * 安全设置Long值
     */
    private void setLongValue(java.util.function.Consumer<Long> setter, Map<String, Object> map, String key) {
        try {
            String value = getStringValue(map, key);
            if (value != null) {
                setter.accept(Long.parseLong(value));
            }
        } catch (NumberFormatException e) {
            // 忽略格式错误，保持null值
        }
    }
    
    /**
     * 处理成绩字段，支持等级制和百分制
     */
    private String processScore(Map<String, Object> data) {
        String score = getStringValue(data, "CJ");
        
        if (score == null || score.isEmpty()) {
            // 如果成绩为空，尝试使用补考成绩
            return getStringValue(data, "BkScore");
        }
        
        // 处理等级制成绩
        switch (score) {
            case "不合格":
                return "45.00";
            case "合格":
                return "65.00";
            case "中等":
                return "75.00";
            case "良好":
                return "85.00";
            case "优秀":
                return "95.00";
            case "0.00":
            case "":
            case "null":
            case "NULL":
                // 空成绩时尝试使用补考成绩
                String bkScore = getStringValue(data, "BkScore");
                return bkScore != null ? bkScore : score;
            default:
                return score;
        }
    }

    //同步学生成绩，先清空在添加
    @Override
    public void convertToT() {
        emptyTableDate();
        int pageNum=1;
        int pageSize=10000;
        int studentInfoNumber = serectCphStuScoreMiddleCount(null);//总数
        int sum=studentInfoNumber/ pageSize;//需要循环的次数
        int sumS=studentInfoNumber%pageSize>0? sum + 1: sum;
        QueryWrapper<CphStuScoreMiddleDto> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.orderByDesc("stu_no", "kcdm");
        for (pageNum=1; pageNum <= sumS; pageNum++){
            List<Map<String,Object>> cphStuScoreMiddles = serectCphStuScoreMiddlesXh(pageNum,pageSize,null);
            selectCphStuScoreMiddleEmptyAndAdd(cphStuScoreMiddles);
            cphStuScoreMiddles.clear();
        }

    }

    //清空数据表
    @Override
    @DataSource(DataSourceType.MASTER)//mysql
    public void emptyTableDate(){
        cphStuScoreMiddleDtoMapper.updateTabeDate();
    }

    //同步学生成绩
    @Override
    @DataSource(DataSourceType.MASTER)//mysql
    public void selectCphStuScoreMiddleEmptyAndAdd(List<Map<String,Object>> cphStuScoreMiddles) {
        if (cphStuScoreMiddles == null || cphStuScoreMiddles.isEmpty()) {
            return;
        }
        
        try {
            // 过滤无效数据
            List<Map<String, Object>> validData = cphStuScoreMiddles.stream()
                    .filter(this::isValidData)
                    .collect(Collectors.toList());
            
            if (validData.isEmpty()) {
                return;
            }
            
            // 批量转换数据
            List<CphStuScoreMiddleDto> cphStuScoreMiddleDto = validData.parallelStream()
                    .map(this::convertToB)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            
            if (!cphStuScoreMiddleDto.isEmpty()) {
                // 分批插入，避免单次插入数据量过大
                List<List<CphStuScoreMiddleDto>> batches = ListSliceUtil.insertSlice(cphStuScoreMiddleDto, syncConfig.getBatchInsertSize());
                if (batches != null) {
                    for (List<CphStuScoreMiddleDto> batch : batches) {
                        if (batch != null && !batch.isEmpty()) {
                            cphStuScoreMiddleDtoMapper.insertBatchSomeColumn(batch);
                        }
                    }
                }
            }
            
        } catch (Exception e) {
            // 记录错误但不抛出异常，避免影响其他批次
            System.err.println("处理学生成绩数据时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 验证数据有效性
     */
    private boolean isValidData(Map<String, Object> data) {
        if (data == null) {
            return false;
        }
        
        // 检查必要字段
        Object stuNo = data.get("XH");
        Object kcdm = data.get("KCDM");
        
        return stuNo != null && !stuNo.toString().trim().isEmpty() &&
               kcdm != null && !kcdm.toString().trim().isEmpty();
    }
}
