package com.fdkankan.platform.user.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.CameraConstant;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.ServerCode;
import com.fdkankan.common.constant.TbStatus;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.user.SSOUser;
import com.fdkankan.common.util.DateUtil;
import com.fdkankan.common.util.JwtUtil;
import com.fdkankan.platform.goods.entity.Camera;
import com.fdkankan.platform.goods.entity.CameraDetail;
import com.fdkankan.platform.goods.service.ICameraDetailService;
import com.fdkankan.platform.goods.service.ICameraService;
import com.fdkankan.platform.user.entity.IncrementLog;
import com.fdkankan.platform.user.entity.User;
import com.fdkankan.platform.user.entity.UserIncrement;
import com.fdkankan.platform.user.mapper.IUserIncrementMapper;
import com.fdkankan.platform.user.request.RequestUserIncrement;
import com.fdkankan.platform.user.service.IIncrementLogService;
import com.fdkankan.platform.user.service.IUserIncrementService;
import com.fdkankan.platform.user.service.IUserService;
import com.fdkankan.platform.user.vo.ResponseUserIncrement;
import com.fdkankan.scene.api.feign.SceneUserSceneClient;
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.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户增值权益表 服务实现类
 * </p>
 *
 * @author 
 * @since 2021-12-24
 */
@Service
public class UserIncrementServiceImpl extends ServiceImpl<IUserIncrementMapper, UserIncrement> implements IUserIncrementService {

    @Resource
    private IUserIncrementMapper userIncrementMapper;
    @Autowired
    private ICameraDetailService cameraDetailService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ICameraService cameraService;
    @Autowired
    private IIncrementLogService incrementLogService;
    @Autowired
    private SceneUserSceneClient sceneUserSceneClient;

    @Override
    public Integer getCountByUserId(Long userId, int status) {
        QueryWrapper<UserIncrement> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserIncrement::getTbStatus, TbStatus.VALID.code());
        queryWrapper.lambda().eq(UserIncrement::getUserId,userId);
        queryWrapper.lambda().eq(UserIncrement::getIsExpired,status);
        return Math.toIntExact(this.count(queryWrapper));
    }

    @Override
    public Integer getCountBindByUserId(Long userId) {
        QueryWrapper<UserIncrement> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserIncrement::getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(UserIncrement::getUserId,userId);
        queryWrapper.lambda().isNotNull(UserIncrement::getCameraId);
        return Math.toIntExact(this.count(queryWrapper));
    }

    @Override
    public UserIncrement getByCameraId(Long cameraId) {
        QueryWrapper<UserIncrement> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserIncrement::getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(UserIncrement::getCameraId,cameraId);
        List<UserIncrement> list = this.list(queryWrapper);
        if(list == null || list.size()<=0){
            return null;
        }
        return list.get(0);
    }

    @Override
    public List<UserIncrement> getByChildName(String childName) {
        return userIncrementMapper.getByChildName(childName);
    }

    @Override
    public String unbindCamera(Long userId, Long id, boolean unbind, CameraDetail cameraDetail, UserIncrement userIncrement) {
        if(userIncrement == null){
            userIncrement = this.getById(id);
        }
        if(userIncrement == null){
            throw new BusinessException(ErrorCode.VALUE_NOT_EXIST);
        }
        if(userIncrement.getCameraId() == null){
            return ServerCode.SUCCESS.message();
        }
        if(cameraDetail == null){
            cameraDetail = cameraDetailService.getByCameraId(userIncrement.getCameraId());
        }
        if(cameraDetail == null){
            throw new BusinessException(CameraConstant.FAILURE_6003);
        }
        if(unbind){
            userIncrement.setCameraId(null);
            this.updateById(userIncrement);
        }

        //根据相机实际容量使用情况，封锁场景
        sceneUserSceneClient.lockBeyondSpaceScenes(cameraDetail.getUsedSpace(), cameraDetail.getTotalSpace(), cameraDetail.getCameraId());
        return ServerCode.SUCCESS.message();
    }

    @Override
    public String unbindCamera(RequestUserIncrement param, String token) {
        SSOUser ssoUser = userService.getSSOUserByToken(token);
        return  this.unbindCamera(ssoUser.getId(),param.getId(),true,null,null);
    }

    @Override
    public String bindCamera(RequestUserIncrement param, String token) {
        SSOUser ssoUser = userService.getSSOUserByToken(token);
        if(param.getId() == null || param.getSnCode() == null){
            throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
        }
        UserIncrement userIncrementEntity = this.getById(param.getId());
        if(userIncrementEntity == null){
            throw new BusinessException(ErrorCode.VALUE_NOT_EXIST);
        }
        Camera cameraEntity = cameraService.getBySnCode(param.getSnCode());
        if(cameraEntity == null){
            throw new BusinessException(CameraConstant.FAILURE_6003);
        }

        UserIncrement byCameraId = this.getByCameraId(cameraEntity.getId());
        if(byCameraId != null){
            throw new BusinessException(ErrorCode.CAMERA_GIVEN);
        }
        CameraDetail cameraDetailEntity = cameraDetailService.getByCameraId(cameraEntity.getId());
        if(cameraDetailEntity == null){
            throw new BusinessException(CameraConstant.FAILURE_6003);
        }
        if(cameraDetailEntity.getUserId() == null || cameraDetailEntity.getUserId().longValue() != ssoUser.getId().longValue()){
            throw new BusinessException(CameraConstant.FAILURE_6005);
        }
        userIncrementEntity.setCameraId(cameraEntity.getId());
        this.updateById(userIncrementEntity);

        //解封所有场景
        sceneUserSceneClient.unlockBeyondSpaceScenes(null, cameraEntity.getId());
        return ServerCode.SUCCESS.message();
    }

    @Override
    public Page<ResponseUserIncrement> findIncrementList(RequestUserIncrement param, String token) {
        SSOUser ssoUser = userService.getSSOUserByToken(token);
        Page<ResponseUserIncrement> pageVo = new Page<>(param.getPageNum(), param.getPageSize());

        List<Long> cameraIdList = null;
        if(StrUtil.isNotEmpty(param.getSnCode()) && StrUtil.isNotEmpty(param.getSnCode().trim())){
            List<Camera> cameraEntityList = cameraService.getCameraLikeSnCode(param.getSnCode().trim());
            if(cameraEntityList == null || cameraEntityList.size()<=0){
                return pageVo;
            }
            cameraIdList = cameraEntityList.stream().map(Camera::getId)
                    .collect(Collectors.toList());
        }
        Page<UserIncrement> page = new Page<>(param.getPageNum(), param.getPageSize());
        QueryWrapper<UserIncrement> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserIncrement::getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(UserIncrement::getUserId,ssoUser.getId());
        if(cameraIdList!=null ){
            queryWrapper.lambda().in(UserIncrement::getCameraId,cameraIdList);
        }
        Page<UserIncrement> pageEntity = this.page(page, queryWrapper);

        List<ResponseUserIncrement> responseList = convert(pageEntity.getRecords());
        pageVo.setTotal(pageEntity.getTotal());
        pageVo.setRecords(responseList);
        return pageVo;
    }

    public List<ResponseUserIncrement> convert(List<UserIncrement> list) {
        List<ResponseUserIncrement> result = new ArrayList<>();
        if(list == null){
            return result;
        }
        ResponseUserIncrement responseUserIncrement = new ResponseUserIncrement();
        for (UserIncrement userIncrementEntity : list) {
            responseUserIncrement = new ResponseUserIncrement();
            BeanUtils.copyProperties(userIncrementEntity, responseUserIncrement);
            if(!ObjectUtils.isEmpty(responseUserIncrement.getIncrementStartTime())){
                responseUserIncrement.setIncrementStartStr(DateUtil.date2String(responseUserIncrement.getIncrementStartTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
            }
            if(!ObjectUtils.isEmpty(responseUserIncrement.getIncrementEndTime())){
                responseUserIncrement.setIncrementEndStr(DateUtil.date2String(responseUserIncrement.getIncrementEndTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
            }
            if(!ObjectUtils.isEmpty(responseUserIncrement.getCreateTime())){
                responseUserIncrement.setCreateStr(DateUtil.date2String(responseUserIncrement.getCreateTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
            }
            if(responseUserIncrement.getCameraId() != null){
                Camera cameraEntity = cameraService.getById(responseUserIncrement.getCameraId());
                responseUserIncrement.setSnCode(cameraEntity != null ? cameraEntity.getSnCode() : null);
            }
            responseUserIncrement.setIsExpire(userIncrementEntity.getIsExpired() != 0);
            result.add(responseUserIncrement);
        }
        return result;
    }


    @Override
    public ResponseUserIncrement findById(RequestUserIncrement param, String token) {
        UserIncrement userIncrementEntity = this.getById(param.getId());
        if(userIncrementEntity == null || TbStatus.DELETE.code().equals(userIncrementEntity.getTbStatus())){
            throw new BusinessException(ErrorCode.ERROR_MSG);
        }
        ResponseUserIncrement responseUserIncrement = new ResponseUserIncrement();
        BeanUtils.copyProperties(userIncrementEntity, responseUserIncrement);
        responseUserIncrement.setIncrementStartStr(DateUtil.date2String(responseUserIncrement.getIncrementStartTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
        responseUserIncrement.setIncrementEndStr(DateUtil.date2String(responseUserIncrement.getIncrementEndTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
        responseUserIncrement.setCreateStr(DateUtil.date2String(responseUserIncrement.getCreateTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
        return responseUserIncrement;
    }

    @Override
    public String insertIncrementls(RequestUserIncrement param,String token) {
        String managerName = JwtUtil.getUsername(token);
        if(StringUtils.isEmpty(param.getUserName())){
            throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
        }
        IncrementLog tmIncrementLogEntity = new IncrementLog();
        //获取用户id
        User userEntity = userService.getUserByUserName(param.getUserName());
        if(userEntity==null || userEntity.getId()==null || TbStatus.DELETE.code().equals(userEntity.getTbStatus())){
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        if(param.getIncrementNum()!=null && param.getIncrementNum()>0 && param.getIncrementEndTime() != null){
            tmIncrementLogEntity.setType("2");
            for(int i=1;i<=param.getIncrementNum();i++){
                //增加一条会员权益
                UserIncrement userIncrementEntity = new UserIncrement();
                userIncrementEntity.setKeyWord(UUID.randomUUID().toString().replace("-", ""));
                userIncrementEntity.setUserId(userEntity.getId());
                userIncrementEntity.setIncrementStartTime(new Date());
                userIncrementEntity.setIncrementEndTime(param.getIncrementEndTime());
                userIncrementEntity.setIsExpired(0);
                this.save(userIncrementEntity);
                userEntity.setDownloadNumTotal(userEntity.getDownloadNumTotal() + 10);
                userService.updateById(userEntity);

            }
            tmIncrementLogEntity.setDownloadNum(10 * param.getIncrementNum());
        }
        if(param.getDownloadNum()!=null && param.getDownloadNum() > 0){
            //增加下载次数
            userEntity.setDownloadNumTotal(userEntity.getDownloadNumTotal() + param.getDownloadNum());
            userService.updateById(userEntity);
            tmIncrementLogEntity.setType("3");
            tmIncrementLogEntity.setDownloadNum(param.getDownloadNum());
        }

        //操作记录log
        managerName = managerName.substring(managerName.indexOf(":")+1,managerName.length());
        tmIncrementLogEntity.setUserId(userEntity.getId());
        tmIncrementLogEntity.setUserName(Long.valueOf(userEntity.getUserName()));
        tmIncrementLogEntity.setOperateUesr(managerName);
        tmIncrementLogEntity.setIncrementNum(param.getIncrementNum() == null ? 0:param.getIncrementNum());

        if(param.getIncrementEndTime()!=null){
            tmIncrementLogEntity.setIncrementEndtime(param.getIncrementEndTime());
        }
        incrementLogService.save(tmIncrementLogEntity);
        return ServerCode.SUCCESS.message();
    }

    @Override
    public List<UserIncrement> findExpireData() {
        return userIncrementMapper.findExpireData();
    }

    @Override
    public List<UserIncrement> findReadyExpire(Integer date, Integer isExpired) {
        return userIncrementMapper.findReadyExpire(date,isExpired);
    }
}
