package com.sz.admin.monitor.service.impl;

import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.sz.admin.monitor.mapper.CameraMapper;
import com.sz.admin.monitor.mapper.NvrMapper;
import com.sz.admin.monitor.pojo.dto.edgebox.SetupChannelDTO;
import com.sz.admin.monitor.pojo.po.Camera;
import com.sz.admin.monitor.pojo.po.Nvr;
import com.sz.admin.monitor.sdk.ManageNVR;
import com.sz.admin.monitor.service.DeviceService;
import com.sz.admin.monitor.utils.AiBoxRequestUtil;
import com.sz.admin.monitor.utils.AlgMediaConfigResponse;
import com.sz.admin.monitor.utils.RtspUtil;
import com.sz.admin.monitor.utils.VcrlUserIdContainer;
import com.sz.admin.system.pojo.dto.sysmessage.PayloadBody;
import com.sz.core.common.entity.SocketMessage;
import com.sz.core.common.entity.TransferMessage;
import com.sz.core.common.enums.SocketChannelEnum;
import com.sz.core.common.exception.common.BusinessException;
import com.sz.platform.enums.AdminResponseEnum;
import com.sz.redis.WebsocketRedisService;
import com.sz.security.core.util.LoginUtils;
import com.sz.socket.SocketService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ClassName: DeviceServiceImpl
 * Package: com.sz.admin.monitor.service.impl
 * Description:
 */
@Service
@Slf4j
public class DeviceServiceImpl extends ServiceImpl<NvrMapper, Nvr> implements DeviceService {
    @Resource
    private VcrlUserIdContainer vcrlUserIdContainer;
    @Resource
    private ManageNVR manageNVR;
    @Resource
    private CameraMapper cameraMapper;
    @Resource
    private NvrMapper nvrMapper;
    @Resource
    private SocketService socketService;
    @Resource
    private WebsocketRedisService websocketRedisService;
    @Resource
    private AiBoxRequestUtil aiBoxRequestUtil;

    @Override
    public Object deviceLogin(Long id) {
        Nvr nvr = this.getById(id);
        // 设备登录
        int result = (int) manageNVR.loginOne(nvr.getId(), nvr.getIp(), String.valueOf(nvr.getPort()), nvr.getAccount(), nvr.getPassword(), String.valueOf(nvr.getDriver()));
        if(result>0)
        {
            nvr.setStatus(1);
            this.updateById(nvr);
        }
        return result;
    }

    /**
     *  通道刷新
     * @param id NVR的id
     * @param deviceType NVR的类型
     * @return
     */
    @Override
    public Boolean refresh(Long id, Integer deviceType) {
        Integer userId=(Integer)vcrlUserIdContainer.getlUserId(id.intValue());
        if (userId==null)
        {
            throw new BusinessException(AdminResponseEnum.DEVICE_OFFLINE,null, "设备为离线状态无法刷新");
        }
        try {
            // 从SDK中获取到的通道信息
            List<Camera> channel = manageNVR.getChannel(userId, id, deviceType);
            Map<Integer, Camera> sdkMap = channel.stream()
                .collect(Collectors.toMap(Camera::getChannelId, c -> c));
            // 从数据库中获取当前已有的列表
            List<Camera> dbCameras = cameraMapper.selectByNvrId(id);
            Map<Integer, Camera> dbMap = dbCameras.stream()
                .collect(Collectors.toMap(Camera::getChannelId, c -> c));
            Nvr nvr = nvrMapper.selectOneById(id);
            // 处理更新和新增
            for (Camera sdkInfo : channel) {
                Camera existingCamera = dbMap.get(sdkInfo.getChannelId());
                if (existingCamera != null) {
                    // --- 数据库里有 -> 更新状态 ---
                    existingCamera.setName(sdkInfo.getName());
                    existingCamera.setIpAddress(sdkInfo.getIpAddress());
                    existingCamera.setStatus(sdkInfo.getStatus());
                    existingCamera.setVideoType(sdkInfo.getVideoType());
                    existingCamera.setUpdateTime(LocalDateTime.now());
                    cameraMapper.update(existingCamera);
                } else {
                    // ---  数据库里没有 -> 新增 ---
                    this.handleNewCameraSync(id, sdkInfo, nvr);
                }
            }
            // 处理移除，如果数据库中的某个通道，在SDK中没有
            for (Camera dbCam : dbCameras) {
                // 如果数据库里的某个通道，SDK里没有了
                if (!sdkMap.containsKey(dbCam.getChannelId())) {
                    dbCam.setStatus(0); // 0 代表离线
                    cameraMapper.update(dbCam);
                }
            }
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return true;
    }
    private void handleNewCameraSync(Long id, Camera sdkInfo, Nvr nvr) {
        Camera newCamera = new Camera();
        newCamera.setNvrId(id);
        newCamera.setChannelId(sdkInfo.getChannelId());
        newCamera.setName(sdkInfo.getName());
        newCamera.setStatus(sdkInfo.getStatus());
        newCamera.setCreateTime(LocalDateTime.now());
        // 初始化配置
        newCamera.setEnableInspection(0);
        newCamera.setChannelDriver(0);
        newCamera.setWatchfulState(0);
        newCamera.setIpAddress(sdkInfo.getIpAddress());
        newCamera.setType(1);
        newCamera.setVideoType(sdkInfo.getVideoType());
        cameraMapper.insert(newCamera);
    }


}
