package com.usky.cdi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.usky.cdi.service.CdiDeliveryLogService;
import com.usky.cdi.service.config.Gb28181VideoProperties;
import com.usky.cdi.service.enums.MqttTopics;
import com.usky.cdi.service.mqtt.MqttConnectionTool;
import com.usky.cdi.service.util.Gb28181MqttCredentialResolver;
import com.usky.cdi.service.util.Gb28181VideoPlatformClient;
import com.usky.cdi.service.util.SnowflakeIdGenerator;
import com.usky.cdi.service.vo.video.VideoChannelVO;
import com.usky.cdi.service.vo.video.VideoDeviceItemVO;
import com.usky.cdi.service.vo.video.VideoDeviceSyncPacketVO;
import com.usky.common.core.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * GB28181 视频设备目录同步：WVP HTTP API 拉取 → MQTT 上报市平台。
 */
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "gb28181.video", name = "enabled", havingValue = "true")
public class VideoDataTransferService {

    private static final int DELIVERY_DATA_TYPE = 5;

    @Value("${snowflake.worker-id:4}")
    private long workerId;

    @Value("${snowflake.data-center-id:4}")
    private long dataCenterId;

    private final Gb28181VideoProperties properties;
    private final Gb28181VideoPlatformClient platformClient;
    private final MqttConnectionTool mqttConnectionTool;
    private final CdiDeliveryLogService cdiDeliveryLogService;
    private final Gb28181MqttCredentialResolver mqttCredentialResolver;

    private SnowflakeIdGenerator idGenerator;
    private final SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    @PostConstruct
    public void init() {
        this.idGenerator = new SnowflakeIdGenerator(workerId, dataCenterId);
    }

    public JSONObject checkConfiguration() {
        return platformClient.checkConfiguration();
    }

    public void synchronizeVideoDevices() {
        Gb28181MqttCredentialResolver.MqttCredentials credentials = mqttCredentialResolver.resolve();
        long startTime = System.currentTimeMillis();
        int total = 0;
        int failure = 0;

        log.info("开始同步 GB28181 视频设备目录: engineeringId={}", credentials.getEngineeringId());
        List<VideoDeviceItemVO> devices = platformClient.queryAllDevicesWithChannels();

        if (properties.isFetchPlayUrl()) {
            enrichPlayUrls(devices);
        }

        for (VideoDeviceItemVO device : devices) {
            if (device.getChannels() != null) {
                total += device.getChannels().size();
            } else {
                total++;
            }
        }

        String topic = resolveDeviceTopic();
        VideoDeviceSyncPacketVO packet = buildDeviceSyncPacket(credentials.getEngineeringId(), devices);
        String jsonMessage = JSON.toJSONString(packet);

        try {
            MqttConnectionTool.MqttGateway gateway = mqttConnectionTool.connectOrRefresh(
                    credentials.getUsername(), credentials.getPassword());
            gateway.sendToMqtt(topic, jsonMessage);
            log.info("视频设备目录 MQTT 上报成功: topic={}, devices={}, channels={}",
                    topic, devices.size(), total);
        } catch (Exception e) {
            failure = total;
            log.error("视频设备目录 MQTT 上报失败: {}", e.getMessage(), e);
            throw new BusinessException("视频设备目录 MQTT 上报失败: " + e.getMessage());
        } finally {
            long endTime = System.currentTimeMillis();
            int success = total - failure;
            cdiDeliveryLogService.saveLog(topic, MqttTopics.Base.VIDEO_DEVICE.getDesc(), DELIVERY_DATA_TYPE,
                    credentials.getTenantId(), credentials.getEngineeringId(), LocalDateTime.now(),
                    startTime, endTime, total, success, failure, 0, failure > 0 ? 0 : 1, "自动同步");
        }
    }

    private void enrichPlayUrls(List<VideoDeviceItemVO> devices) {
        for (VideoDeviceItemVO device : devices) {
            if (device.getChannels() == null) {
                continue;
            }
            for (VideoChannelVO channel : device.getChannels()) {
                if (!"ON".equalsIgnoreCase(channel.getStatus())) {
                    continue;
                }
                try {
                    channel.setPlayUrl(platformClient.queryPlayUrl(device.getDeviceId(), channel.getChannelId()));
                } catch (Exception e) {
                    log.warn("获取预览地址失败 deviceId={} channelId={}: {}",
                            device.getDeviceId(), channel.getChannelId(), e.getMessage());
                }
            }
        }
    }

    private VideoDeviceSyncPacketVO buildDeviceSyncPacket(Long engineeringId, List<VideoDeviceItemVO> devices) {
        VideoDeviceSyncPacketVO packet = new VideoDeviceSyncPacketVO();
        packet.setDataPacketID(idGenerator.nextPacketId());
        packet.setEngineeringID(engineeringId);
        packet.setPublishTime(timeFormat.format(new Date()));
        packet.setPlatformSipId(properties.getSipId());
        packet.setPlatformSipDomain(properties.getSipDomain());
        packet.setDevices(devices);
        return packet;
    }

    private String resolveDeviceTopic() {
        if (StringUtils.hasText(properties.getMqttTopic())) {
            return properties.getMqttTopic();
        }
        return MqttTopics.Base.VIDEO_DEVICE.getTopic();
    }
}
