package com.keao.edu.user.service.impl;


import com.keao.edu.auth.api.entity.SysUser;
import com.keao.edu.common.dal.BaseDAO;
import com.keao.edu.common.exception.BizException;
import com.keao.edu.common.page.PageInfo;
import com.keao.edu.common.service.IdGeneratorService;
import com.keao.edu.common.service.impl.BaseServiceImpl;
import com.keao.edu.user.dao.*;
import com.keao.edu.user.dto.ExamRegistrationStatisticsDto;
import com.keao.edu.user.entity.*;
import com.keao.edu.user.enums.ExamStatusEnum;
import com.keao.edu.user.enums.StudentRegistrationStatusEnum;
import com.keao.edu.user.page.ExamRegistrationQueryInfo;
import com.keao.edu.user.service.ExamRegistrationPaymentService;
import com.keao.edu.user.service.ExamRegistrationService;
import com.keao.edu.user.service.OrganizationService;
import com.keao.edu.user.service.PayService;
import com.keao.edu.util.collection.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class ExamRegistrationServiceImpl extends BaseServiceImpl<Long, ExamRegistration> implements ExamRegistrationService {

    @Autowired
    private ExamRegistrationDao examRegistrationDao;
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private ExamCertificationDao examCertificationDao;
    @Autowired
    private ExaminationBasicDao examinationBasicDao;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private PayService payService;
    @Autowired
    private ExamSubjectSongDao examSubjectSongDao;
    @Autowired
    private ExamMusicTheoryDao examMusicTheoryDao;
    @Autowired
    private IdGeneratorService idGeneratorService;
    @Autowired
    private SysConfigDao sysConfigDao;
    @Autowired
    private ExamRegistrationPaymentService examRegistrationPaymentService;

    @Override
    public BaseDAO<Long, ExamRegistration> getDAO() {
        return examRegistrationDao;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> addRegistration(ExamRegistration examRegistration) throws Exception {
        SysUser sysUser = examRegistration.getSysUser();
        ExaminationBasic examinationBasic = examinationBasicDao.get(examRegistration.getExaminationBasicId().longValue());
        if (examinationBasic == null || !examinationBasic.getStatus().equals(ExamStatusEnum.APPLYING)) {
            throw new BizException("项目不在报名中，请核对");
        }
        SysUser user = sysUserDao.get(examRegistration.getUserId());
        user.setBirthdate(sysUser.getBirthdate());
        user.setGender(sysUser.getGender());
        user.setIdCardNo(examRegistration.getCardNo());
        user.setRealName(sysUser.getRealName());
        user.setNation(sysUser.getNation());
        sysUserDao.update(user);

        //考试级别信息
        ExamSubjectSong examSubjectSong = examSubjectSongDao.get(examRegistration.getExamSubjectSongId());
        if (examSubjectSong == null) {
            throw new BizException("请选择专业级别");
        }
        Date nowDate = new Date();
        String orderNo = idGeneratorService.generatorId("payment") + "";

        examRegistration.setLevel(examSubjectSong.getLevel());
        BigDecimal amount = examSubjectSong.getRegistrationFee();
        //乐理考试级别
        ExamMusicTheory examMusicTheory = null;
        if (examRegistration.getExamMusicTheoryId() != null) {
            examMusicTheory = examMusicTheoryDao.get(examRegistration.getExamMusicTheoryId());
        }
        if (examMusicTheory != null) {
            examRegistration.setExamMusicTheoryLevel(examMusicTheory.getLevel());
            amount.add(examMusicTheory.getFee());
        }

        examRegistration.setUserId(examRegistration.getStudentId());
        studentDao.insert(examRegistration);
        examRegistration.setStatus(StudentRegistrationStatusEnum.PAY_WAIT);
        examRegistrationDao.insert(examRegistration);

        ExamRegistrationPayment examRegistrationPayment = new ExamRegistrationPayment();
        examRegistrationPayment.setTenantId(examRegistration.getTenantId());
        examRegistrationPayment.setExamRegistrationId(examRegistration.getId().longValue());
        examRegistrationPayment.setStudentId(examRegistration.getUserId());
        examRegistrationPayment.setExaminationBasicId(examRegistration.getExaminationBasicId());
        examRegistrationPayment.setOrderNo(orderNo);
        examRegistrationPayment.setTransAmount(amount);
        examRegistrationPayment.setTransStatus("ING");
        examRegistrationPayment.setCreateTime(nowDate);
        examRegistrationPayment.setUpdateTime(nowDate);
        examRegistrationPaymentService.insert(examRegistrationPayment);

        String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");
        Map<String, Object> payMap = payService.getPayMap(
                amount,
                orderNo,
                baseApiUrl + "/api-student/studentOrder/notify",
                baseApiUrl + "/api-student/studentOrder/paymentResult?orderNo=" + orderNo,
                examinationBasic.getName(),
                examinationBasic.getName()
        );
        return payMap;
    }

    @Override
    public PageInfo<ExamRegistration> queryExamRegistrationStudents(ExamRegistrationQueryInfo queryInfo) {
        PageInfo<ExamRegistration> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
        Map<String, Object> params = new HashMap<String, Object>();
        MapUtil.populateMap(params, queryInfo);

        List<Integer> nextLevelOrganIds = organizationService.getChildOrganIds(queryInfo.getOrganId(), true);
        params.put("organIds", nextLevelOrganIds);

        List<ExamRegistration> dataList = Collections.EMPTY_LIST;
        int count = this.findCount(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = this.getDAO().queryPage(params);
            List<Integer> organIds = dataList.stream().map(ExamRegistration::getOrganId).collect(Collectors.toList());
            Map<Integer, String> organIdNameMap = this.getMap("organization", "id_", "name_", organIds, Integer.class, String.class);
            List<Integer> subjectIds = dataList.stream().map(ExamRegistration::getSubjectId).collect(Collectors.toList());
            Map<Integer, String> subjectIdNameMap = this.getMap("subject", "id_", "name_", subjectIds, Integer.class, String.class);
            for (ExamRegistration examRegistration : dataList) {
                examRegistration.getOrganization().setName(organIdNameMap.get(examRegistration.getOrganId()));
                examRegistration.getSubject().setName(subjectIdNameMap.get(examRegistration.getStudentId()));
            }
        }

        pageInfo.setRows(dataList);
        return pageInfo;
    }

    @Override
    public ExamRegistrationStatisticsDto getExamRegistrationStaticsInfo(Integer organId, Integer examId) {
        List<Integer> childOrganIds = organizationService.getChildOrganIds(organId, true);
        ExamRegistrationStatisticsDto examRegistrationStaticsInfo = examRegistrationDao.getExamRegistrationStaticsInfo(organId, childOrganIds, examId);
        if (Objects.isNull(examRegistrationStaticsInfo)) {
            examRegistrationStaticsInfo = new ExamRegistrationStatisticsDto();
        }
        return examRegistrationStaticsInfo;
    }
}
