package com.qmth.exam.reserve.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.boot.core.exception.StatusException;
import com.qmth.exam.reserve.bean.category.CategoryCacheBean;
import com.qmth.exam.reserve.bean.student.StudentInfo;
import com.qmth.exam.reserve.bean.student.WechatBindReq;
import com.qmth.exam.reserve.cache.impl.CategoryCacheService;
import com.qmth.exam.reserve.dao.StudentDao;
import com.qmth.exam.reserve.entity.StudentEntity;
import com.qmth.exam.reserve.service.StudentService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> implements StudentService {

    private static final Logger log = LoggerFactory.getLogger(StudentServiceImpl.class);

    @Autowired
    private CategoryCacheService categoryCacheService;

    @Override
    public StudentEntity findByStudentCode(Long applyTaskId, String studentCode) {
        if (StringUtils.isEmpty(studentCode)) {
            throw new StatusException("学号不能为空");
        }
        if (applyTaskId == null) {
            throw new StatusException("预约任务ID不能为空");
        }

        LambdaQueryWrapper<StudentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentEntity::getStudentCode, studentCode);
        wrapper.eq(StudentEntity::getApplyTaskId, applyTaskId);

        return baseMapper.selectOne(wrapper);
    }

    @Override
    public StudentEntity findByOpenIdAndUid(String openId, String uid) {
        if (StringUtils.isEmpty(openId)) {
            throw new StatusException("微信OID不能为空");
        }

        LambdaQueryWrapper<StudentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentEntity::getOpenId, openId);
        if (StringUtils.isNotEmpty(uid)) {
            wrapper.eq(StudentEntity::getUid, uid);
        }

        return baseMapper.selectOne(wrapper);
    }

    @Override
    public int findStudentApplyNumberById(Long studentId) {
        // 只查询applyNumber等少量字段
        LambdaQueryWrapper<StudentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StudentEntity::getApplyNumber);
        wrapper.eq(StudentEntity::getId, studentId);
        StudentEntity stu = this.getOne(wrapper);
        if (stu == null) {
            log.warn("学生信息不存在！studentId:{}", studentId);
            throw new StatusException("学生信息不存在");
        }
        return stu.getApplyNumber();
    }

    @Override
    public StudentEntity findLessInfoByStudentId(Long studentId) {
        // 只查询id、name等少量字段
        LambdaQueryWrapper<StudentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StudentEntity::getId, StudentEntity::getName);
        wrapper.eq(StudentEntity::getId, studentId);
        return this.getOne(wrapper);
    }

    @Override
    public StudentInfo findInfoByStudentId(Long studentId) {
        StudentEntity entity = baseMapper.selectById(studentId);
        if (entity == null) {
            throw new StatusException("学生信息不存在");
        }

        StudentInfo info = new StudentInfo();
        info.setId(entity.getId());
        info.setName(entity.getName());
        info.setStudentCode(entity.getStudentCode());
        info.setIdentityNumber(entity.getIdentityNumber());
        info.setPhotoPath(entity.getPhotoPath());
        info.setGender(entity.getGender());
        info.setApplyNumber(entity.getApplyNumber());
        info.setOpenId(entity.getOpenId());
        info.setUid(entity.getUid());
        info.setOrgId(entity.getOrgId());
        info.setApplyTaskId(entity.getApplyTaskId());
        info.setCategoryId(entity.getCategoryId());

        CategoryCacheBean category = categoryCacheService.getCategoryById(entity.getCategoryId());
        if (category != null) {
            info.setCategoryName(category.getName());
        }

        return info;
    }

    @Transactional
    @Override
    public void bindingWechat(WechatBindReq req) {
        StudentEntity stu = baseMapper.selectById(req.getStudentId());
        if (stu == null) {
            throw new StatusException("学生信息不存在");
        }

        if (StringUtils.isNotEmpty(stu.getOpenId())) {
            throw new StatusException("微信账号已绑定");
        }

        if (StringUtils.isEmpty(req.getOpenId())) {
            throw new StatusException("微信OID不能为空");
        }

        LambdaUpdateWrapper<StudentEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(StudentEntity::getOpenId, req.getOpenId());
        updateWrapper.set(StudentEntity::getUid, req.getUid());
        updateWrapper.eq(StudentEntity::getId, req.getStudentId());
        this.update(updateWrapper);
        log.info("[WECHAT_BINDING] studentId:{} openId:{} uid:{}", req.getStudentId(), req.getOpenId(), req.getUid());
    }

    @Transactional
    @Override
    public void unbindWechatByStudentId(Long studentId) {
        StudentEntity stu = baseMapper.selectById(studentId);
        if (stu == null) {
            throw new StatusException("学生信息不存在");
        }

        if (StringUtils.isEmpty(stu.getOpenId())) {
            return;
        }

        LambdaUpdateWrapper<StudentEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(StudentEntity::getOpenId, null);
        updateWrapper.set(StudentEntity::getUid, null);
        updateWrapper.eq(StudentEntity::getId, studentId);
        this.update(updateWrapper);
        log.info("[WECHAT_UNBIND] studentId:{} openId:{} uid:{}", stu.getId(), stu.getOpenId(), stu.getUid());
    }

    @Override
    public List<StudentEntity> listNoFinishStudent(Long taskId, Boolean cancel) {
        return this.baseMapper.listNoFinishStudent(taskId, cancel);
    }

}
