package jnpf.cultivate.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.base.UserInfo;
import jnpf.cultivate.mapper.FtbCultivateCertificateUserMapper;
import jnpf.cultivate.service.FtbCultivateCertificateService;
import jnpf.cultivate.service.FtbCultivateCertificateUserService;
import jnpf.model.cultivate.dto.certificate.FtbCertificateUserForm;
import jnpf.model.cultivate.po.certificate.CertificateUserPagination;
import jnpf.model.cultivate.po.certificate.FtbCertificateEntity;
import jnpf.model.cultivate.po.certificate.FtbCertificateUserEntity;
import jnpf.model.enums.CourseEnums;
import jnpf.model.enums.SelfrowingEnum;
import jnpf.util.SelfGrowthUtil;
import jnpf.util.UserProvider;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hao.peng
 */
@Service
public class FtbCultivateCertificateUserServiceImpl extends ServiceImpl<FtbCultivateCertificateUserMapper, FtbCertificateUserEntity> implements FtbCultivateCertificateUserService {
    @Autowired

    private UserProvider userProvider;
    @Autowired
    private FtbCultivateCertificateService certificateService;
    @Override
    public List<FtbCertificateUserEntity> getList(CertificateUserPagination pagination) {
        //通过UserProvider获取用户信息
        QueryWrapper<FtbCertificateUserEntity> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(pagination.getKeyword())) {
            queryWrapper.lambda().and(
                    t -> t.like(FtbCertificateUserEntity::getUserName, pagination.getKeyword())
            );
        }
        if (!StringUtils.isEmpty(pagination.getCertificateId())) {
            queryWrapper.lambda().eq(FtbCertificateUserEntity::getCertificateId, pagination.getCertificateId());
        }
        if (!StringUtils.isEmpty(pagination.getUserId())) {
            queryWrapper.lambda().eq(FtbCertificateUserEntity::getUserId, pagination.getUserId());
        }
        queryWrapper.lambda().eq(FtbCertificateUserEntity::getEnabledMark, CourseEnums.EnabledMarkType.VALID.getCode());
        //排序
        if (StringUtils.isEmpty(pagination.getSidx())) {
        } else {
            queryWrapper = "asc".equalsIgnoreCase(pagination.getSort()) ? queryWrapper.orderByAsc(pagination.getSidx()) : queryWrapper.orderByDesc(pagination.getSidx());
        }
        queryWrapper.lambda().eq(FtbCertificateUserEntity::getEnabledMark, 1);
        updateStatus(queryWrapper);
        Page<FtbCertificateUserEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<FtbCertificateUserEntity> userIPage = this.page(page, queryWrapper);
        return pagination.setData(userIPage.getRecords(), page.getTotal());
    }

    @Override
    public FtbCertificateUserEntity getInfo(String id) {
        QueryWrapper<FtbCertificateUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FtbCertificateUserEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    @DSTransactional
    public void create(FtbCertificateUserForm form) {
        List<FtbCertificateUserForm.UserInfoForm> userInfoFormList = form.getUserInfoFormList();
        if (CollectionUtils.isEmpty(userInfoFormList)) {
            return;
        }
        FtbCertificateEntity certificateEntity = certificateService.getById(form.getCertificateId());
        FtbCertificateUserEntity entity = new FtbCertificateUserEntity();
        entity.setCertificateId(form.getCertificateId());
        entity.setCertificateName(certificateEntity.getName());
        entity.setCompanyName(certificateEntity.getCompanyName());
        entity.setStatus(CourseEnums.CertUserStatus.USING.getCode());
        entity.setEffectTime(LocalDateTime.now());
        entity.setReason(form.getReason());
        if (certificateEntity.getExpireTime() > 0 && !CourseEnums.CertExpireType.NEVER.getCode().equals(certificateEntity.getExpireType())) {
            //设置失效时间 ExpireTime=0时 null表示永久
            LocalDateTime expireTime = LocalDateTime.now();
            if (CourseEnums.CertExpireType.DAY.getCode().equals(certificateEntity.getExpireType())) {
                expireTime = expireTime.plusDays(certificateEntity.getExpireTime().longValue());
            } else if (CourseEnums.CertExpireType.MONTH.getCode().equals(certificateEntity.getExpireType())) {
                expireTime = expireTime.plusMonths(certificateEntity.getExpireTime().longValue());
            }
            Date date = Date.from(expireTime.atZone(ZoneId.systemDefault()).toInstant());
            entity.setExpireTime(date);
        }
        UserInfo userInfo = userProvider.get();
        List<String> arrayList = new ArrayList<>();
        userInfoFormList.stream().forEach(item -> {
            String userId = item.getUserId();
            CertificateUserPagination certificateUserPagination = new CertificateUserPagination();
            certificateUserPagination.setCertificateId(form.getCertificateId());
            certificateUserPagination.setUserId(userId);
            List<FtbCertificateUserEntity> list = getList(certificateUserPagination);
            List<FtbCertificateUserEntity> collect = list.stream().filter(vo -> vo.getStatus() == 0).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(collect)){
                arrayList.add(item.getUserName());
            }
        });
        if (CollUtil.isNotEmpty(arrayList)){
            throw new RuntimeException(String.join(",",arrayList)+"用户已存在证书,请勿重复颁发!");
        }
        List<FtbCertificateUserEntity> entityList = new ArrayList<>();
        for (FtbCertificateUserForm.UserInfoForm userInfoForm : userInfoFormList) {
            entity.setId(IdWorker.getIdStr());
            entity.setUserId(userInfoForm.getUserId());
            entity.setUserName(userInfoForm.getUserName());
            entity.setOrganizeId(userInfoForm.getOrganizeId());
            entity.setPositionId(userInfoForm.getPositionId());
            entity.setCreatorUserId(userInfo.getUserId());
            String basedOnTheModule = SelfGrowthUtil.provideACustomIDBasedOnTheModule(
                    SelfrowingEnum.CERTIFICATE_ENCODING_PREFIX,4);
            entity.setNumber(basedOnTheModule);
            entity.setTenantId(userInfo.getTenantId());
            entity.setEnabledMark(CourseEnums.EnabledMarkType.VALID.getCode());
            FtbCertificateUserEntity entitySave = new FtbCertificateUserEntity();
            BeanUtils.copyProperties(entity, entitySave);
            entityList.add(entitySave);
        }
        this.saveBatch(entityList);
    }

    @Override
    @Transactional
    public void update(String id, FtbCertificateUserEntity entity) {
        entity.setId(id);
        entity.setLastModifyUserId(userProvider.get().getUserId());
        this.updateById(entity);
    }

    @Override
    public boolean delete(String id) {
        LambdaQueryWrapper<FtbCertificateUserEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FtbCertificateUserEntity::getId, id);
        List<FtbCertificateUserEntity> users = this.list(wrapper);
        FtbCertificateUserEntity user = users.get(0);
        if (ObjectUtils.isEmpty(user)) {
            return false;
        }
        if (1 == user.getStatus() || 2 == user.getStatus()) {
            return false;
        }
        user.setStatus(2);
        this.updateById(user);
        return true;
    }

    @Override
    public List<FtbCertificateUserEntity> userList(String userId) {
        QueryWrapper<FtbCertificateUserEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(FtbCertificateUserEntity::getUserId, userId);
        wrapper.lambda().eq(FtbCertificateUserEntity::getStatus, 0);
        wrapper.lambda().eq(FtbCertificateUserEntity::getEnabledMark, 1);
        updateStatus(wrapper);
        // 更改失效不显示
        return this.list(new LambdaQueryWrapper<FtbCertificateUserEntity>()
                .eq(FtbCertificateUserEntity::getUserId, userId)
                .eq(FtbCertificateUserEntity::getEnabledMark, 1)
        );
    }

    /**
     * 更新证书状态
     *
     * @param queryWrapper queryWrapper
     */
    @Override
    public void updateStatus(QueryWrapper<FtbCertificateUserEntity> queryWrapper) {
        //更新证书状态
        List<FtbCertificateUserEntity> users = super.list(queryWrapper);
        List<FtbCertificateUserEntity> updates = users.stream().filter(r -> ObjectUtils.isNotEmpty(r.getExpireTime())
                        && cn.hutool.core.date.DateUtil.date().after(r.getExpireTime()))
                .map(r -> r.setStatus(1)).collect(Collectors.toList());
        this.updateBatchById(updates);
    }

}