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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.TbStatus;
import com.fdkankan.platform.agent.request.RequestAgent;
import com.fdkankan.platform.agent.vo.ResponseAgentCamera;
import com.fdkankan.common.constant.AppConstant;
import com.fdkankan.common.util.DateUtil;
import com.fdkankan.common.util.FileSizeUtil;
import com.fdkankan.platform.goods.entity.Camera;
import com.fdkankan.platform.goods.entity.CameraDetail;
import com.fdkankan.platform.goods.entity.CameraDetailNumEntity;
import com.fdkankan.platform.goods.mapper.ICameraDetailMapper;
import com.fdkankan.platform.goods.service.ICameraDetailService;
import com.fdkankan.platform.goods.service.ICameraService;
import com.fdkankan.platform.goods.service.ICameraSpaceService;
import com.fdkankan.platform.order.service.IVirtualOrderService;
import com.fdkankan.platform.user.entity.User;
import com.fdkankan.platform.user.entity.UserIncrement;
import com.fdkankan.platform.user.request.RequestCamera;
import com.fdkankan.platform.user.service.IUserIncrementService;
import com.fdkankan.platform.user.service.IUserService;
import com.fdkankan.platform.user.vo.ResponseCamera;
import com.fdkankan.platform.user.vo.ResponseCameraSpace;
import com.fdkankan.platform.user.vo.ResponseUserIncrement;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.exception.BusinessException;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 相机子表 服务实现类
 * </p>
 *
 * @author 
 * @since 2021-12-24
 */
@Service
public class CameraDetailServiceImpl extends ServiceImpl<ICameraDetailMapper, CameraDetail> implements ICameraDetailService {

    @Autowired
    private ICameraService cameraService;
    @Autowired
    private IVirtualOrderService virtualOrderService;
    @Resource
    private ICameraDetailMapper cameraDetailMapper;
    @Autowired
    private IUserService userService;
    @Autowired
    private ICameraSpaceService cameraSpaceService;
    @Autowired
    private IUserIncrementService userIncrementService;

    @Override
    public Integer getCountByAgentId(String agentId) {
        LambdaQueryWrapper<CameraDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CameraDetail::getTbStatus, TbStatus.VALID.code());
        queryWrapper.eq(CameraDetail::getAgency, agentId);
        long count = this.count();
        return Math.toIntExact(count);
    }
    @Override
    public CameraDetail getByCameraId(Long cameraId) {
        QueryWrapper<CameraDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CameraDetail :: getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(CameraDetail :: getCameraId,cameraId);
        List<CameraDetail> list = this.list(queryWrapper);
        if(list == null || list.size()<=0){
            return null;
        }
        return list.get(0);
    }

    @Override
    public Page<ResponseAgentCamera> getPageByAgentId(RequestAgent param) {
        QueryWrapper<CameraDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CameraDetail :: getAgency,param.getAgentId());
        queryWrapper.lambda().eq(CameraDetail :: getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().orderByDesc(CameraDetail::getCreateTime);

        Page<CameraDetail> page = new Page<>();
        page.setCurrent(param.getPageNum());
        page.setSize(param.getPageSize());
        Page<CameraDetail> pageResult = this.page(page, queryWrapper);

        List<ResponseAgentCamera> voList = new ArrayList<>();
        for (CameraDetail record : pageResult.getRecords()) {
            Camera camera = cameraService.getById(record.getCameraId());
            if(camera == null){
                continue;
            }
            ResponseAgentCamera vo = virtualOrderService.getPointsByCameraId(record.getCameraId(), param.getStartDate(), param.getEndDate());
            vo.setId(camera.getId());
            vo.setBalance(Integer.parseInt(record.getBalance()));
            vo.setChildName(camera.getChildName());
            voList.add(vo);
        }
        Page<ResponseAgentCamera> pageVo = new Page<>();
        pageVo.setCurrent(page.getCurrent());
        pageVo.setSize(page.getSize());
        pageVo.setTotal(page.getTotal());
        pageVo.setRecords(voList);
        return pageVo;
    }

    @Override
    public List<CameraDetail> getListByAgentId(String agentId) {
        QueryWrapper<CameraDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CameraDetail::getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(CameraDetail::getAgency,agentId);
        queryWrapper.lambda().orderByDesc(CameraDetail::getCreateTime);
        return  this.list(queryWrapper);
    }

    @Override
    public Page<ResponseCamera> getPageByUserAndType(RequestCamera param, Long userId) {
        QueryWrapper<CameraDetail> queryWrapper = this.getQueryByUserAndType(param.getCameraType(), userId);
        Page<CameraDetail> page = new Page<>();
        page.setCurrent(param.getPageNum());
        page.setSize(param.getPageSize());
        Page<CameraDetail> pageEntity = this.page(page, queryWrapper);

        List<ResponseCamera> voList = cameraService.convert(pageEntity.getRecords());

        Page<ResponseCamera> voPage = new Page<>(param.getPageNum(), param.getPageSize());
        voPage.setTotal(pageEntity.getTotal());
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public List<ResponseCamera> getListByUserAndType(Integer cameraType, Long userId) {
        QueryWrapper<CameraDetail> queryWrapper = this.getQueryByUserAndType(cameraType, userId);
        List<CameraDetail> list = this.list(queryWrapper);
        return list.parallelStream().map(cameraDetail -> {
            ResponseCamera responseCamera = new ResponseCamera();
            BeanUtils.copyProperties(cameraDetail, responseCamera);
            return responseCamera;
        }).collect(Collectors.toList());
    }

    private QueryWrapper<CameraDetail> getQueryByUserAndType(Integer cameraType, Long userId) {
        QueryWrapper<CameraDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CameraDetail::getTbStatus,TbStatus.VALID.code());
        if(userId != null){
            queryWrapper.lambda().eq(CameraDetail::getUserId,userId);
        }
        queryWrapper.lambda().orderByDesc(CameraDetail::getCreateTime);
        if(cameraType!=null){
            switch (cameraType){
                case 0 :
                case 9 :
                    queryWrapper.lambda().eq(CameraDetail::getCameraType,cameraType);break;
                case 4:queryWrapper.lambda().eq(CameraDetail::getCameraType,1);break;
                case 1:queryWrapper.lambda().eq(CameraDetail::getCameraType,0);break;
                default:queryWrapper.lambda().ne(CameraDetail::getCameraType,0);break;
            }
        }
       return queryWrapper;
    }

    @Override
    public List<CameraDetailNumEntity> getTypeNumByUser(Integer type, Long userId) {
        if(type!=null){
            return cameraDetailMapper.selectTypeNum(userId,type);
        }else{
            return cameraDetailMapper.selectTypeNumAll(userId);
        }
    }

    @Override
    public ResponseCamera getByChildName(Long userId, RequestCamera param) {
        ResponseCamera vo = new ResponseCamera();
        Camera cameraEntity = cameraService.getByChildName(param.getChildName());
        if (cameraEntity != null){
            CameraDetail detailEntity = this.getByCameraId(cameraEntity.getId());
            if (detailEntity != null){
                vo.setId(cameraEntity.getId());
                vo.setUserId(detailEntity.getUserId());
                vo.setActivatedTime(cameraEntity.getActivatedTime());
                vo.setBalance(detailEntity.getBalance());
                vo.setChildName(cameraEntity.getChildName());
                vo.setSnCode(cameraEntity.getSnCode());
                if (detailEntity.getCameraType() != 0){
                    vo.setUsedSpace(FileSizeUtil.formetFileSize(detailEntity.getUsedSpace(), FileSizeUtil.SIZETYPE_GB));
                    vo.setTotalSpace(FileSizeUtil.formetFileSize(detailEntity.getTotalSpace(), FileSizeUtil.SIZETYPE_GB));
                    vo.setUsedSpaceStr(FileSizeUtil.formatFileSize(detailEntity.getUsedSpace()));
                    vo.setTotalSpaceStr(FileSizeUtil.formatFileSize(detailEntity.getTotalSpace()));
                }
                vo.setType(detailEntity.getCameraType());
                vo.setCountry(detailEntity.getCountry());
            }
        }
        if(userId != null){
            User userEntity = userService.getById(userId);
            vo.setNickName(userEntity.getNickName());
        }else {
            if(vo.getType().equals(9)){
                vo.setNickName("Minion设备用户");
            }else if(vo.getType().equals(10)){
                vo.setNickName("Laser设备用户");
            }else{
                vo.setNickName("Pro设备用户");
            }
        }

        List<ResponseCameraSpace> cameraList = cameraSpaceService.getVoListByCameraId(vo.getId());
        if(cameraList != null && cameraList.size() > 0){
            ResponseCameraSpace cameraSpace = cameraList.get(0);

            Long space = cameraSpace.getSpace();
            vo.setSpaceId(cameraSpace.getId());
            vo.setSpace((long)FileSizeUtil.formetFileSize(space, FileSizeUtil.SIZETYPE_GB));
            vo.setSpaceStr(FileSizeUtil.formatFileSize(space));
            vo.setSpaceEndStr(DateUtil.date2String(cameraSpace.getSpaceEndTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
            if(Days.daysBetween(new DateTime(), new DateTime(cameraSpace.getSpaceEndTime())).getDays() < 7){
                vo.setIsExpire(true);
            }
        }

        //获取会员权益
        List<UserIncrement> userIncrementEntityList = userIncrementService.getByChildName(param.getChildName());
        ResponseUserIncrement responseUserIncrement = new ResponseUserIncrement();
        if(userIncrementEntityList!=null && userIncrementEntityList.size()>0){

            UserIncrement userIncrementEntity = userIncrementEntityList.get(0);
            BeanUtils.copyProperties(userIncrementEntity,responseUserIncrement);

            vo.setResponseUserIncrement(responseUserIncrement);
        }
        return vo;
    }



    @Override
    public HashMap<String, Object> getCameraDetailDeadline(Long userId, RequestCamera param) {
        List<ResponseCameraSpace> cameraSpaceList = new ArrayList<>();
        //所有期限的集合
        List<ResponseCameraSpace> cameraSpaceAll = new ArrayList<>();
        DateTime dateTime = null;
        Long space = 0L;
        User user = userService.getById(userId);
        if(param.getChildName() != null && user == null){
            Camera cameraEntity = cameraService.getByChildName(param.getChildName());
            if (cameraEntity == null){
                throw new BusinessException(ErrorCode.CAMERA_BIND_NO_EXIST);
            }

            CameraDetail detailEntity = this.getByCameraId(cameraEntity.getId());
            if (detailEntity == null){
                throw new BusinessException(ErrorCode.CAMERA_BIND_NO_EXIST);
            }
            List<ResponseCameraSpace> cameraList = cameraSpaceService.getVoListByCameraId(cameraEntity.getId());

            if(cameraList != null && cameraList.size() > 0){
                ResponseCameraSpace cameraSpace = cameraList.get(0);
                dateTime = new DateTime(cameraSpace.getSpaceEndTime());
                cameraSpace.setSnCode(cameraEntity.getSnCode());
                cameraSpace.setChildName(cameraEntity.getChildName());
                cameraSpace.setUsedSpace(FileSizeUtil.formetFileSize(detailEntity.getUsedSpace(), FileSizeUtil.SIZETYPE_GB));
                cameraSpace.setTotalSpace(FileSizeUtil.formetFileSize(detailEntity.getTotalSpace(), FileSizeUtil.SIZETYPE_GB));
                cameraSpace.setUsedSpaceStr(FileSizeUtil.formatFileSize(detailEntity.getUsedSpace()));
                cameraSpace.setTotalSpaceStr(FileSizeUtil.formatFileSize(detailEntity.getTotalSpace()));

                space = cameraSpace.getSpace();
                cameraSpace.setSpace((long)FileSizeUtil.formetFileSize(space, FileSizeUtil.SIZETYPE_GB));
                cameraSpace.setSpaceStr(FileSizeUtil.formatFileSize(space));
                cameraSpace.setSpaceEndStr(DateUtil.date2String(cameraSpace.getSpaceEndTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));
                if(Days.daysBetween(new DateTime(), dateTime).getDays() < 7){
                    cameraSpaceList.add(cameraSpace);
                }
                cameraSpaceAll.add(cameraSpace);
            }

            HashMap<String,Object> map = new HashMap<>();
            map.put("nickName", "Pro设备用户");

            if(cameraSpaceList.size() > 0){
                map.put("isExpire", true);
                map.put("cameraList", cameraSpaceList);
                return map;
            }

            map.put("isExpire", false);
            map.put("cameraList", cameraSpaceAll);
            return map;
        }
        List<ResponseCamera> cameras8 = cameraService.getByUser(userId, 4);
        for(ResponseCamera responseCamera : cameras8){
            List<ResponseCameraSpace> cameraList = cameraSpaceService.getVoListByCameraId(responseCamera.getId());

            if(cameraList != null && cameraList.size() > 0){
                ResponseCameraSpace cameraSpace = cameraList.get(0);

                dateTime = new DateTime(cameraSpace.getSpaceEndTime());
                cameraSpace.setSnCode(responseCamera.getSnCode());
                cameraSpace.setUsedSpace(responseCamera.getUsedSpace());
                cameraSpace.setUsedSpaceStr(responseCamera.getUsedSpaceStr());
                cameraSpace.setTotalSpace(responseCamera.getTotalSpace());
                cameraSpace.setTotalSpaceStr(responseCamera.getTotalSpaceStr());

                space = cameraSpace.getSpace().longValue();
                cameraSpace.setSpace((long)FileSizeUtil.formetFileSize(space, FileSizeUtil.SIZETYPE_GB));
                cameraSpace.setSpaceStr(FileSizeUtil.formatFileSize(space));
                cameraSpace.setSpaceEndStr(DateUtil.date2String(cameraSpace.getSpaceEndTime(), DateUtil.YYYY_MM_DD_DATE_FORMAT));

                if(Days.daysBetween(new DateTime(), dateTime).getDays() < 7){
                    cameraSpaceList.add(cameraSpace);
                    cameraSpaceAll.add(cameraSpace);
                    continue;
                }

                cameraSpaceAll.add(cameraSpace);
            }
        }
        HashMap<String,Object> map = new HashMap<>();
        map.put("nickName", user.getNickName());

        if(cameraSpaceList.size() > 0){
            map.put("isExpire", true);
            Collections.sort(cameraSpaceList);
            map.put("cameraList", cameraSpaceList);
            return map;
        }

        map.put("isExpire", false);
        Collections.sort(cameraSpaceAll);
        map.put("cameraList", cameraSpaceAll);
        return map;
    }

    @Override
    public Integer getDeadLineNumber(Long userId) {
        QueryWrapper<CameraDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CameraDetail::getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(CameraDetail::getUserId,userId);
        List<CameraDetail> list = this.list(queryWrapper);
        Integer number = 0;
        List<ResponseCameraSpace> cameraList = null;
        for (CameraDetail cameraDetailEntity : list) {
            cameraList = cameraSpaceService.getVoListByCameraId(cameraDetailEntity.getCameraId());
            if(cameraList != null && cameraList.size() > 0){
                if(Days.daysBetween(new DateTime(), new DateTime(cameraList.get(0).getSpaceEndTime())).getDays() < 30){
                    number++;
                }
            }
        }
        return number;
    }

    @Override
    public boolean unbind(Long cameraId) {
        return this.bindOrUnbind(cameraId,null);
    }

    @Override
    public boolean bind(Long userId, Long cameraId) {
        CameraDetail byCameraId = this.getByCameraId(cameraId);
        if(byCameraId != null){
            throw new BusinessException(AppConstant.FAILURE_CODE_4011, AppConstant.FAILURE_MSG_4011);
        }
        return this.bindOrUnbind(cameraId,userId);
    }

    private boolean bindOrUnbind(Long cameraId, Long userId){
        UpdateWrapper<CameraDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(CameraDetail::getUserId,userId);
        updateWrapper.lambda().eq(CameraDetail::getTbStatus,TbStatus.VALID.code());
        updateWrapper.lambda().eq(CameraDetail::getCameraId,cameraId);
        return this.update(updateWrapper);
    }

    @Override
    public CameraDetail updateCameraDetailByCameraIdAndSpace(Long cameraId, Long space) {
        CameraDetail cameraDetail = this.getByCameraId(cameraId);
        if(Objects.isNull(cameraDetail)){
            return null;
        }
        cameraDetail.setUsedSpace(cameraDetail.getUsedSpace() + space);
        if(cameraDetail.getUsedSpace() < 0){
            cameraDetail.setUsedSpace(0L);
        }
        if(!this.updateById(cameraDetail)){
            throw new BusinessException(ErrorCode.ERROR_MSG);
        }
        return cameraDetail;
    }

    @Override
    public Long getSumBalanceByUserId(Long userId) {
        return cameraDetailMapper.getSumBalanceByUserId(userId);
    }

    @Override
    public boolean updateCameraBalance(Long cameraId, int body, Integer points) {
        CameraDetail detailEntity = this.getByCameraId(cameraId);
        int sub = Integer.parseInt(detailEntity.getBalance());
        if (0 == body){
            sub += points;
        }else if (-2 == body){
            sub -= points;
        }
        detailEntity.setBalance(String.valueOf(sub));
        return this.updateById(detailEntity);
    }

    @Override
    public List<CameraDetail> getListByUserId(Long userId, Long cameraType) {
        QueryWrapper<CameraDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CameraDetail::getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(CameraDetail::getUserId,userId);
        queryWrapper.lambda().orderByDesc(CameraDetail::getUpdateTime);
        if(cameraType != null ){
            queryWrapper.lambda().eq(CameraDetail::getGoodsId,cameraType);
            return this.list(queryWrapper);
        }
        queryWrapper.lambda().ne(CameraDetail::getGoodsId,4);
        return this.list(queryWrapper);
    }

    @Override
    public Page<ResponseCamera> queryListByParams(RequestCamera param) {
        Page<ResponseCamera> pageVo = new Page<ResponseCamera>(param.getPageNum(), param.getPageSize());
        param.setOrderBy("t.id desc");
        return cameraDetailMapper.queryListByParams(pageVo,param);
    }

    @Override
    public Page<ResponseCamera>  queryCompanyCameraListByParams(RequestCamera param) {
        Page<ResponseCamera> pageVo = new Page<>(param.getPageNum(), param.getPageSize());
        param.setOrderBy("a.create_time desc");
        return cameraDetailMapper.queryCompanyCameraListByParams(pageVo,param);
    }

    @Override
    public Page<ResponseCamera> cameraList(RequestCamera param) {
        Page<ResponseCamera> pageVo = new Page<>(param.getPageNum(),param.getPageSize());
        param.setOrderBy("a.create_time desc");
        return cameraDetailMapper.cameraList(pageVo,param);
    }

    @Override
    public void updateCompanyId(Long companyId) {
        UpdateWrapper<CameraDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(CameraDetail::getCompanyId,null);
        updateWrapper.lambda().eq(CameraDetail::getCompanyId,companyId);
        this.update(updateWrapper);
    }

}
