package com.sqx.modules.member.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.validator.ValidatorUtils;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.member.dao.SpecialFavorStudentDao;
import com.sqx.modules.member.dto.SpecialFavorStudentDTO;
import com.sqx.modules.member.dto.SpecialFavorStudentVerifyDTO;
import com.sqx.modules.member.dto.VipPromoRecordDTO;
import com.sqx.modules.member.entity.SpecialFavorStudent;
import com.sqx.modules.member.query.SpecialFavorStudentQuery;
import com.sqx.modules.member.service.SpecialFavorStudentService;
import com.sqx.modules.member.service.VipPromoRecordService;
import com.sqx.modules.member.vo.SpecialFavorStudentVO;
import com.sqx.modules.utils.VipExpirationUtil;
import com.sqx.modules.utils.excel.EasyExcelUtil;
import com.sqx.modules.utils.excel.ExcelFinishCallBack;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
public class SpecialFavorStudentServiceImpl extends ServiceImpl<SpecialFavorStudentDao, SpecialFavorStudent> implements SpecialFavorStudentService {

    private final UserService userService;
    private final CommonInfoService commonInfoService;
    private final VipPromoRecordService vipPromoRecordService;

    @Override
    public PageUtils pages(SpecialFavorStudentQuery query) {
        IPage<SpecialFavorStudentVO> page = baseMapper.pages(new Page<>(query.getPage(), query.getLimit()), query);
        return new PageUtils(page);
    }

    @Override
    public void save(SpecialFavorStudentDTO dto) {
        // 检验参数
        checkParam(dto);

        SpecialFavorStudent specialFavorStudent = new SpecialFavorStudent();
        BeanUtil.copyProperties(dto, specialFavorStudent);
        specialFavorStudent.setCreateTime(new Date());
        baseMapper.insert(specialFavorStudent);
    }

    @Override
    public void update(SpecialFavorStudentDTO dto) {
        // 校验参数
        checkParam(dto);

        SpecialFavorStudent specialFavorStudent = new SpecialFavorStudent();
        BeanUtil.copyProperties(dto, specialFavorStudent);
        baseMapper.updateById(specialFavorStudent);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importData(MultipartFile file) {
        EasyExcelUtil.readAnalysis(file, SpecialFavorStudentDTO.class, new ExcelFinishCallBack<SpecialFavorStudentDTO>() {
            @Override
            public void doAfterAllAnalysed(List<SpecialFavorStudentDTO> result) {
                if (!result.isEmpty()) {
                    saveBatchData(result);
                }
            }

            @Override
            public void doSaveBatch(List<SpecialFavorStudentDTO> result) {
                saveBatchData(result);
            }

            private void saveBatchData(List<SpecialFavorStudentDTO> dtoList) {
                List<SpecialFavorStudent> entities = new ArrayList<>();
                Date now = new Date();
                for (SpecialFavorStudentDTO dto : dtoList) {
                    // 校验参数
                    ValidatorUtils.validateEntity(dto);
                    checkParam(dto);

                    SpecialFavorStudent entity = new SpecialFavorStudent();
                    BeanUtil.copyProperties(dto, entity);
                    entity.setCreateTime(now);
                    entities.add(entity);
                }

                // 批量保存
                saveBatch(entities);
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void verify(Long userId, SpecialFavorStudentVerifyDTO dto) {
        LambdaQueryWrapper<SpecialFavorStudent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SpecialFavorStudent::getStudentNumber, dto.getStudentNumber());
        queryWrapper.eq(SpecialFavorStudent::getName, dto.getName());

        SpecialFavorStudent specialFavorStudent = baseMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNull(specialFavorStudent)) {
            throw new SqxException("认证失败，身份不符合");
        }

        UserEntity user = userService.getById(userId);
        if(ObjectUtil.isNotNull(user.getIsVip()) && user.getIsVip() == 1 && VipExpirationUtil.isVipValid(user.getVipExpirationTime())) {
            throw new SqxException("已经是会员，不能重复购买！");
        }

        // 更新认证状态
        specialFavorStudent.setVerifyStatus("1");
        specialFavorStudent.setVerifyUserId(userId);
        specialFavorStudent.setLastVerifyTime(new Date());

        updateById(specialFavorStudent);

        // 添加会员推广记录
        VipPromoRecordDTO recordDTO = VipPromoRecordDTO.builder()
                .userId(userId)
                .userName(user.getNickName())
                .userPhone(user.getPhone())
                .payType("3")
                .payAmount(0.0)
                .build();
        vipPromoRecordService.add(recordDTO);

        // 会员期限（天）
        CommonInfo vipExpirationDays = commonInfoService.findOne(314);

        // 更新用户为会员
        userService.updateUserToVip(userId, VipExpirationUtil.getFutureTimeWithDays(Integer.valueOf(vipExpirationDays.getValue())));
    }

    private void checkParam(SpecialFavorStudentDTO dto) {
        // 校验学号是否存在
        LambdaQueryWrapper<SpecialFavorStudent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SpecialFavorStudent::getStudentNumber, dto.getStudentNumber());
        queryWrapper.ne(ObjectUtil.isNotNull(dto.getId()), SpecialFavorStudent::getId, dto.getId());
        if (count(queryWrapper) > 0) {
            throw new SqxException("学号[" + dto.getStudentNumber() + "]已存在");
        }
    }
}
