package cn.iocoder.yudao.module.system.service.robot.camera;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.system.config.poperties.ZnConfigConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraAddVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotCameraDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotCameraMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotStatusEnum;
import cn.iocoder.yudao.module.system.util.aes.AESEncryptionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 车辆摄像头信息 Service 实现类
 *
 * @author 陈宾顺
 */
@Service
@Validated
public class RobotCameraServiceImpl extends ServiceImpl<RobotCameraMapper, RobotCameraDO> implements RobotCameraService {

    @Resource
    private RobotCameraMapper cameraMapper;

    @Autowired
    private ZnConfigConstant znConfigConstant;

    @Override
    public Long createCamera(RobotCameraSaveReqVO createReqVO) {
        // 插入
        RobotCameraDO camera = BeanUtils.toBean(createReqVO, RobotCameraDO.class);
        cameraMapper.insert(camera);
        // 返回
        return camera.getId();
    }

    @Override
    public void updateCamera(RobotCameraSaveReqVO updateReqVO) {
        // 校验存在
        validateCameraExists(updateReqVO.getId());
        // 更新
        RobotCameraDO updateObj = BeanUtils.toBean(updateReqVO, RobotCameraDO.class);
        cameraMapper.updateById(updateObj);
    }

    @Override
    public void deleteCamera(Long id) {
        // 校验存在
        validateCameraExists(id);
        // 删除
        cameraMapper.deleteById(id);
    }

    private void validateCameraExists(Long id) {
        if (cameraMapper.selectById(id) == null) {
            throw exception(CAMERA_NOT_EXISTS);
        }
    }

    @Override
    public RobotCameraDO getCamera(Long id) {
        return cameraMapper.selectById(id);
    }

    @Override
    public PageResult<RobotCameraDO> getCameraPage(RobotCameraPageReqVO pageReqVO) {
        return cameraMapper.selectPage(pageReqVO);
    }

    /**
     * 判断IP是否存在
     *
     * @param cameraAddVOList
     */
    @Override
    public void checkCameraExist(List<RobotCameraAddVO> cameraAddVOList) {
        List<String> list = cameraAddVOList.stream().map(RobotCameraAddVO::getCameraIp).collect(Collectors.toList());

        if (Sets.newHashSet(list).size() < list.size()) {
            throw exception(CAMERA_IP_REPEAT);
        }

        List<RobotCameraDO> robotCameraDOs = cameraMapper.selectList(new LambdaQueryWrapper<RobotCameraDO>()
                .in(RobotCameraDO::getCameraIp, list));
        if (ObjectUtil.isEmpty(robotCameraDOs)) {
            return;
        }
        List<String> ips = robotCameraDOs.stream().map(RobotCameraDO::getCameraIp).collect(Collectors.toList());
        String join = StringUtils.join(ips, ",");
        throw exception(CAMERA_IP_EXIST, "以下摄像头IP已经存在 " + join);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createCameraList(List<RobotCameraAddVO> cameraAddVOList, String robotNo) {
        List<RobotCameraDO> cameraDOList = BeanUtils.toBean(cameraAddVOList, RobotCameraDO.class);
        for (RobotCameraDO robotCameraDO : cameraDOList) {
            try {
                setCameraAccountAndPassword(robotCameraDO);
            } catch (Exception e) {
                throw exception(CAMERA_DECRYPTION_FAILED);
            }
            robotCameraDO.setRobotNo(robotNo);
        }
        cameraMapper.insert(cameraDOList);
    }

    private void setCameraAccountAndPassword(RobotCameraDO robotCameraDO) {
        if (ObjectUtil.isEmpty(robotCameraDO.getId())) {
            try {
                robotCameraDO.setCameraAccount(AESEncryptionUtil.encrypt(robotCameraDO.getCameraAccount(), znConfigConstant.getCameraSecretKey()));
                robotCameraDO.setCameraPassword(AESEncryptionUtil.encrypt(robotCameraDO.getCameraPassword(), znConfigConstant.getCameraSecretKey()));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            robotCameraDO.setCameraAccount(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraAccount(),znConfigConstant.getCameraSecretKey()));
            robotCameraDO.setCameraPassword(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraPassword(),znConfigConstant.getCameraSecretKey()));
        }
    }

    /**
     * 根据车辆编号删除
     *
     * @param robotNo
     */
    @Override
    public void deleteCameraByRobotNo(String robotNo) {
        cameraMapper.deleteByRobotNo(robotNo);
    }

    @Override
    public List<RobotCameraAddVO> getCameraByRobotNo(String robotNo) {
        List<RobotCameraDO> cameraDOList = cameraMapper.selectList(new LambdaQueryWrapper<RobotCameraDO>()
                .eq(RobotCameraDO::getRobotNo, robotNo));
        if (ObjectUtil.isEmpty(cameraDOList)) {
            return new ArrayList<>();
        }

        List<RobotCameraAddVO> list = BeanUtils.toBean(cameraDOList, RobotCameraAddVO.class);
        return list;
    }

}
