package com.usky.sas.common.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.usky.sas.common.dahua.DahuaVideoStreamService;
// import com.fjkj.agcp.common.global.GlobalMemoryMap; // Replaced
import com.usky.sas.common.UnityVideoInfo;
import java.util.concurrent.ConcurrentHashMap; // Added
import java.net.URI;
import java.net.URISyntaxException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import com.usky.sas.common.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class ZLMediaKitUtils {
    private static final Logger log = LoggerFactory.getLogger(ZLMediaKitUtils.class);
    @Autowired
    private RestTemplate restTemplate;
    @Value("${media-kit.http.port}")
    private Integer mediaHttpPort;
    static Map<String, UnityVideoInfo> unityVideoInfo;

    public ZLMediaKitUtils() {
    }

    public boolean streamIsExist(String mediaIp, Integer mediaHttpPort, String secret, String ssrc) {
        try {
            String url = String.format("http://%s:%d/index/api/getMediaList?secret=%s&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
            ResponseEntity<JsonNode> response = this.restTemplate.getForEntity(url, JsonNode.class, new Object[0]);
            if (!response.getStatusCode().is2xxSuccessful()) {
                log.error("获取流列表失败: {}", response.getStatusCode());
                return false;
            } else {
                JsonNode dataNode = ((JsonNode)Objects.requireNonNull(response.getBody())).path("data");
                return dataNode.isArray() && !dataNode.isEmpty();
            }
        } catch (Exception e) {
            log.error("检查流是否存在失败", e);
            return false;
        }
    }

    public boolean streamIsUsed(String mediaIp, Integer mediaHttpPort, String secret, String ssrc, Long playHandle, String macAddr, boolean isPlayback) {
        try {
            String url = String.format("http://%s:%d/index/api/getMediaPlayerList?secret=%s&schema=rtsp&vhost=__defaultVhost__&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
            ResponseEntity<JsonNode> response = this.restTemplate.getForEntity(url, JsonNode.class, new Object[0]);
            if (!response.getStatusCode().is2xxSuccessful()) {
                log.error("获取播放器列表失败: {}", response.getStatusCode());
                return false;
            }

            JsonNode dataNode = ((JsonNode)response.getBody()).path("data");
            if (dataNode.isArray() && dataNode.size() == 0) {
                log.info("没有客户端在观看，即将关闭流: {}", ssrc);
                //HikVideoStreamService.stopPlayStreamData(playHandle, macAddr);
                return true;
            }
        } catch (Exception e) {
            log.error("检查或关闭流失败", e);
        }

        return false;
    }

    public boolean dahuaStreamIsUsed(String mediaIp, Integer mediaHttpPort, String secret, String ssrc, Long playHandle, String macAddr, boolean isPlayback) {
        try {
            String url = String.format("http://%s:%d/index/api/getMediaPlayerList?secret=%s&schema=rtsp&vhost=__defaultVhost__&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
            ResponseEntity<JsonNode> response = this.restTemplate.getForEntity(url, JsonNode.class, new Object[0]);
            if (!response.getStatusCode().is2xxSuccessful()) {
                log.error("获取播放器列表失败: {}", response.getStatusCode());
                return false;
            }

            JsonNode dataNode = ((JsonNode)response.getBody()).path("data");
            if (dataNode.isArray() && dataNode.size() == 0) {
                log.info("没有客户端在观看，即将关闭流: {}", ssrc);
                DahuaVideoStreamService.stopPlayStreamData(playHandle, macAddr);
                return true;
            }
        } catch (Exception e) {
            log.error("检查或关闭流失败", e);
        }

        return false;
    }

    public String addStreamProxy(String secret, String streamSsrc, String rtspUrl, String username, String password) {
        try {
            URI originalUri = new URI(rtspUrl);
            String userInfo = username + ":" + password;
            URI newUri = new URI(originalUri.getScheme(), userInfo, originalUri.getHost(), originalUri.getPort(), originalUri.getPath(), originalUri.getQuery(), originalUri.getFragment());
            String newRtspUrl = newUri.toString();
            String zlmApiUrl = "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/addStreamProxy";
            Map<String, Object> body = new HashMap();
            body.put("vhost", "__defaultVhost__");
            body.put("app", "rtp");
            body.put("stream", streamSsrc);
            body.put("url", newRtspUrl);
            body.put("secret", secret);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, Object>> request = new HttpEntity(body, headers);
            ResponseEntity<Map> response = this.restTemplate.postForEntity(zlmApiUrl, request, Map.class, new Object[0]);
            if (response.getStatusCode().is2xxSuccessful()) {
                Map<String, Object> responseBody = (Map)response.getBody();
                if (responseBody != null && "0".equals(String.valueOf(responseBody.get("code")))) {
                    log.info("ZLM 拉流成功: " + responseBody);
                    return "__defaultVhost__/rtp/" + streamSsrc;
                } else {
                    log.error(" ZLM 拉流失败: " + responseBody);
                    throw new BusinessException("播放失败", -1);
                }
            } else {
                log.error("HTTP 请求失败: " + response.getStatusCode());
                throw new BusinessException("播放失败", -1);
            }
        } catch (URISyntaxException e) {
            log.error(" URL 解析错误: " + e.getMessage());
            throw new BusinessException("播放失败", -1);
        } catch (Exception e) {
            log.error(" 调用 ZLM API 异常: " + e.getMessage());
            throw new BusinessException(" 播放失败 ", -1);
        }
    }

    public String addStreamUnityProxy(String secret, String streamSsrc, String rtspUrl) {
        try {
            String zlmApiUrl = "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/addStreamProxy";
            Map<String, Object> body = new HashMap();
            body.put("vhost", "__defaultVhost__");
            body.put("app", "rtp");
            body.put("stream", streamSsrc);
            body.put("url", rtspUrl);
            body.put("secret", secret);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, Object>> request = new HttpEntity(body, headers);
            ResponseEntity<Map> response = this.restTemplate.postForEntity(zlmApiUrl, request, Map.class, new Object[0]);
            if (response.getStatusCode().is2xxSuccessful()) {
                Map<String, Object> responseBody = (Map)response.getBody();
                if (responseBody != null && "0".equals(String.valueOf(responseBody.get("code")))) {
                    log.info("ZLM 拉流成功: " + responseBody);
                    return "__defaultVhost__/rtp/" + streamSsrc;
                } else {
                    log.error(" ZLM 拉流失败: " + responseBody);
                    throw new BusinessException("播放失败", -1);
                }
            } else {
                log.error("HTTP 请求失败: " + response);
                throw new BusinessException("播放失败", -1);
            }
        } catch (Exception e) {
            log.error(" 调用 ZLM API 异常: " + e.getMessage());
            throw new BusinessException("播放失败", -1);
        }
    }

    public String addPlayStreamProxy(String secret, String streamSsrc, String rtspUrl, String username, String password, LocalDateTime startTime, LocalDateTime endTime) {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'");
            String startStr = startTime.atOffset(ZoneOffset.UTC).format(formatter);
            String endStr = endTime.atOffset(ZoneOffset.UTC).format(formatter);
            String timeParams = "?starttime=" + startStr + "&endtime=" + endStr;
            if (rtspUrl.contains("?")) {
                rtspUrl = rtspUrl.substring(0, rtspUrl.indexOf(63));
            }

            String fullRtspUrl = rtspUrl + timeParams;
            URI originalUri = new URI(fullRtspUrl);
            String userInfo = username + ":" + password;
            URI newUri = new URI(originalUri.getScheme(), userInfo, originalUri.getHost(), originalUri.getPort(), originalUri.getPath(), originalUri.getQuery(), originalUri.getFragment());
            String newRtspUrl = newUri.toString();
            String zlmApiUrl = "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/addStreamProxy";
            Map<String, Object> body = new HashMap();
            body.put("vhost", "__defaultVhost__");
            body.put("app", "rtp");
            body.put("stream", streamSsrc);
            body.put("url", newRtspUrl);
            body.put("secret", secret);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, Object>> request = new HttpEntity(body, headers);
            ResponseEntity<Map> response = this.restTemplate.postForEntity(zlmApiUrl, request, Map.class, new Object[0]);
            if (response.getStatusCode().is2xxSuccessful()) {
                Map<String, Object> responseBody = (Map)response.getBody();
                if (responseBody != null && "0".equals(String.valueOf(responseBody.get("code")))) {
                    log.info("ZLM 拉流成功: " + responseBody);
                    return "__defaultVhost__/rtp/" + streamSsrc;
                } else {
                    log.error(" 拉流失败，请检查设备IP、用户名、密码、通道 是否正确，更多详细信息请看日志: " + responseBody);
                    throw new BusinessException("播放失败", -1);
                }
            } else {
                log.error("HTTP 请求失败: " + response.getStatusCode());
                throw new BusinessException("播放失败", -1);
            }
        } catch (URISyntaxException e) {
            log.error(" URL 解析错误: " + e.getMessage());
            throw new BusinessException(" 播放失败", -1);
        } catch (Exception e) {
            log.error(" 调用 ZLM API 异常: " + e.getMessage());
            throw new BusinessException(" 播放失败", -1);
        }
    }

    public void unityStreamProxyIsUsed(String mediaIp, Integer mediaHttpPort, String secret, String ssrc, String key, String macAddr) {
        try {
            String listUrl = String.format("http://%s:%d/index/api/getMediaPlayerList?secret=%s&schema=rtsp&vhost=__defaultVhost__&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
            ResponseEntity<JsonNode> listResponse = this.restTemplate.getForEntity(listUrl, JsonNode.class, new Object[0]);
            if (!listResponse.getStatusCode().is2xxSuccessful()) {
                log.warn("获取播放器列表失败: {}", listResponse.getStatusCode());
                return;
            }

            JsonNode dataNode = ((JsonNode)Objects.requireNonNull(listResponse.getBody())).path("data");
            if (dataNode.isArray() && dataNode.isEmpty()) {
                log.info("没有客户端在观看，即将关闭流: {}", ssrc);
                String delUrl = String.format("http://%s:%d/index/api/delStreamProxy?secret=%s&key=%s", mediaIp, mediaHttpPort, secret, key);
                ResponseEntity<JsonNode> delResponse = this.restTemplate.getForEntity(delUrl, JsonNode.class, new Object[0]);
                if (!delResponse.getStatusCode().is2xxSuccessful()) {
                    log.warn("删除流代理失败: {}", delResponse.getStatusCode());
                    return;
                }

                boolean flag = ((JsonNode)Objects.requireNonNull(delResponse.getBody())).path("data").path("flag").asBoolean(false);
                if (flag) {
                    unityVideoInfo.remove(macAddr);
                    log.info("成功关闭设备{}拉流代理", macAddr);
                } else {
                    log.error("关闭设备{}拉流代理失败", macAddr);
                }
            }
        } catch (Exception e) {
            log.error("检查或关闭实时预览流失败", e);
        }

    }

    static {
        unityVideoInfo = new ConcurrentHashMap<>();
    }
}
