package com.xjrsoft.module.student.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.github.yulichang.base.MPJBaseService;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.enums.ConsumeTypeEnum;
import com.xjrsoft.config.TransactionConfig;
import com.xjrsoft.module.base.entity.BaseClass;
import com.xjrsoft.module.base.entity.BaseGrade;
import com.xjrsoft.module.base.entity.BaseMajorSet;
import com.xjrsoft.module.organization.entity.UserRoleRelation;
import com.xjrsoft.module.student.dto.StudentConsumeDateExcelImportDto;
import com.xjrsoft.module.student.entity.BaseMajor;
import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
import com.xjrsoft.module.student.entity.StudentConsumeDate;
import com.xjrsoft.module.student.mapper.StudentConsumeDateMapper;
import com.xjrsoft.module.student.service.IStudentConsumeDateService;
import com.xjrsoft.module.student.vo.StuConsumeImportStuInfoVo;
import com.xjrsoft.module.teacher.entity.XjrUser;
import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
import com.xjrsoft.module.textbook.entity.SubjectGroup;
import com.xjrsoft.module.textbook.service.ITextbookCoreAttributeService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @title: 学生消费数据
 * @Author dzx
 * @Date: 2024-08-26
 * @Version 1.0
 */
@Service
@AllArgsConstructor
public class StudentConsumeDateServiceImpl extends MPJBaseServiceImpl<StudentConsumeDateMapper, StudentConsumeDate> implements IStudentConsumeDateService {

    private final XjrUserMapper xjrUserMapper;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Override
    public String excelImport(MultipartFile file) throws IOException {
        List<StudentConsumeDateExcelImportDto> excelDataList = EasyExcel.read(file.getInputStream()).headRowNumber(1).head(StudentConsumeDateExcelImportDto.class).sheet().doReadSync();
        StringBuilder sb = new StringBuilder();

        // 获取所有学生id和其他信息
        MPJLambdaWrapper<XjrUser> xjrUserMPJLambdaWrapper = new MPJLambdaWrapper<>();
        xjrUserMPJLambdaWrapper
                .distinct()
                .disableSubLogicDel()
                .selectAs(BaseStudentSchoolRoll::getClassId, StuConsumeImportStuInfoVo::getClassId)
                .selectAs(BaseClass::getName, StuConsumeImportStuInfoVo::getClassName)
                .selectAs(XjrUser::getId, StuConsumeImportStuInfoVo::getStudentId)
                .selectAs(XjrUser::getName, StuConsumeImportStuInfoVo::getStudentName)
                .selectAs(XjrUser::getCredentialNumber, StuConsumeImportStuInfoVo::getStudentUserName)
                .selectAs(BaseGrade::getId, StuConsumeImportStuInfoVo::getGradeId)
                .selectAs(BaseGrade::getName, StuConsumeImportStuInfoVo::getGradeName)
                .selectAs(BaseMajor::getId, StuConsumeImportStuInfoVo::getMajorId)
                .selectAs(BaseMajor::getName, StuConsumeImportStuInfoVo::getMajorName)
                .innerJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
                .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, XjrUser::getId)
                .leftJoin(BaseClass.class, BaseClass::getId, BaseStudentSchoolRoll::getClassId)
                .leftJoin(BaseGrade.class, BaseGrade::getId, BaseClass::getGradeId)
                .leftJoin(BaseMajorSet.class, BaseMajorSet::getId, BaseClass::getMajorSetId)
                .leftJoin(BaseMajor.class, BaseMajor::getId, BaseMajorSet::getMajorId)
                .eq(UserRoleRelation::getRoleId, 3)
        ;

        List<StuConsumeImportStuInfoVo> stuConsumeImportStuInfoVos = xjrUserMapper.selectJoinList(StuConsumeImportStuInfoVo.class, xjrUserMPJLambdaWrapper);

        Map<String, StuConsumeImportStuInfoVo> stringStuConsumeImportStuInfoVoMap = stuConsumeImportStuInfoVos.stream()
                .filter(x -> ObjectUtil.isNotNull(x.getStudentUserName()))
                .collect(Collectors.toMap(data -> data.getStudentUserName(), data -> data, (e1, e2) -> e1));

        int batchSize = 1000;
        int processedCount = 0;
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);

        try {
            for (StudentConsumeDateExcelImportDto dto : excelDataList) {
                String studentUserName = dto.getStudentUserName();
                // 处理学生信息
                StuConsumeImportStuInfoVo stuConsumeImportStuInfoVo = stringStuConsumeImportStuInfoVoMap.get(studentUserName);
                if (ObjectUtils.isEmpty(stuConsumeImportStuInfoVo)) {
                    sb.append(dto.getStudentUserName())
                            .append("学号无效，导入失败。")
                    ;
                    continue;
                }

                StudentConsumeDate studentConsumeDate = BeanUtil.toBean(stuConsumeImportStuInfoVo, StudentConsumeDate.class);
                studentConsumeDate.setConsumeTime(dto.getConsumeTime());

                // 处理消费数据
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//
//            try {
//                // 解析字符串为Date对象
//                Date date = sdf.parse(dto.getConsumeTime());
//                System.out.println("解析后的日期：" + date);
//            } catch (ParseException e) {
//                sb.append(dto.getStudentUserName())
//                        .append("学号无效，添加失败。")
//                ;
//                continue;
//            }

//                try {
//                    // 解析字符串为BigDecimal对象
//                    if (ObjectUtils.isEmpty(dto.getConsumeMoney())) {
//                        sb.append(dto.getStudentUserName())
//                                .append("消费金额无效，导入失败。")
//                        ;
//                        continue;
//                    }
//                    BigDecimal consumeMoney = new BigDecimal(dto.getConsumeMoney());
//                    studentConsumeDate.setConsumeMoney(consumeMoney);
//                } catch (NumberFormatException e) {
//                    sb.append(dto.getStudentUserName())
//                            .append("消费金额无效，导入失败。")
//                    ;
//                    continue;
//                }

                studentConsumeDate.setConsumeMoney(dto.getConsumeMoney());

                if (ObjectUtil.isNotNull(dto.getConsumeType())) {
                    String consumeType = ConsumeTypeEnum.getCode(dto.getConsumeType());
                    studentConsumeDate.setConsumeType(consumeType);
                }
                this.save(studentConsumeDate);

                processedCount++;
                if (processedCount % batchSize == 0) {
                    // 每处理1000条记录时提交一次事务
                    transactionManager.commit(status);
                    status = transactionManager.getTransaction(def); // 开始新事务
                }
            }

            // 最后处理剩余不足1000条的数据
            if (processedCount % batchSize != 0) {
                transactionManager.commit(status);
            }

        } catch (Exception e) {
            // 如果发生异常，则回滚事务
            transactionManager.rollback(status);
            throw e;
        }
        return sb.toString();
    }
}
