package com.multictrl.modules.business.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.multictrl.common.config.SrsConfig;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.utils.FfmpegUtils;
import com.multictrl.modules.business.dao.SrsClient;
import com.multictrl.modules.business.dao.SrsRecordDao;
import com.multictrl.modules.business.dto.SrsCallBackDTO;
import com.multictrl.modules.business.entity.SrsRecordEntity;
import com.multictrl.modules.business.service.SrsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 视频服务接口
 *
 * @author Sdy
 * @since 1.0.0 2026/4/24
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SrsServiceImpl implements SrsService {
    private static final String RTMP_PROTOCOL = "rtmp://";
    private final SrsRecordDao srsRecordDao;
    private final SrsConfig srsConfig;
    private final SrsClient srsClient;

    @Override
    public void saveSrsRecord(SrsCallBackDTO srsCallBack) {
        try {
            String callBackFile = srsCallBack.getFile();
            if (StrUtil.isNotBlank(callBackFile) &&
                    (callBackFile.contains("/dock") || callBackFile.contains("/uav"))) {
                SrsRecordEntity srsRecordEntity = new SrsRecordEntity();
                srsRecordEntity.setApp(srsCallBack.getApp());
                srsRecordEntity.setStream(srsCallBack.getStream());
                if (callBackFile.startsWith("/")) {
                    srsRecordEntity.setFile(callBackFile.substring(1));
                } else {
                    srsRecordEntity.setFile(callBackFile);
                }
                srsRecordEntity.setStreamUrl(srsCallBack.getStream_url());
                String file = callBackFile;
                //  /live_record/aaa/bbb/2025-04-03_16-33-43-404.mp4
                String dateTime = (file = file.substring(file.lastIndexOf("/") + 1))
                        .substring(0, file.indexOf("."));
                dateTime = dateTime.split("_")[0] + " " + dateTime.split("_")[1]
                        .replaceAll("-", ":");
                log.info("on_dvr dateTime:{}", dateTime);
                if (StrUtil.isNotBlank(dateTime)) {
                    srsRecordEntity.setRecordDate(DateUtil.parse(dateTime, "yyyy-MM-dd HH:mm:ss:SSS"));
                }

                //设置封面
                String videoCoverPath = srsRecordEntity.getFile().replaceAll(".mp4", BusinessConstant.VIDEO_COVER_SUFFIX);
                FfmpegUtils.generateVideoCover("/" + file, "/" + videoCoverPath);
                srsRecordDao.insert(srsRecordEntity);
            }
        } catch (Exception e) {
            log.error("解析 srs callback on_dvr error", e);
        }
    }

    @Override
    public boolean checkToken(SrsCallBackDTO srsCallBack) {
        String query = srsCallBack.getParam();
        if (query == null || query.isEmpty()) {
            return false;
        }
        // 去掉开头的 '?'（如果存在）
        String q = query.startsWith("?") ? query.substring(1) : query;
        // 按 & 分割成键值对
        String[] pairs = q.split("&");
        for (String pair : pairs) {
            String[] kv = pair.split("=", 2); // 限制最多分成2部分，防止 value 中也有 =
            if (kv.length == 2 && "token".equals(kv[0])) {
                return srsConfig.getRtmpToken().equals(kv[1]);
            }
        }
        return false;
    }

    @Override
    public JSONArray streamsBySn(String dockSn) {
        if (StrUtil.isBlank(dockSn)) {
            return null;
        }
        // 调用服务获取流列表
        log.info("开始调取srs获取流列表，提交参数：{}", dockSn);
        JSONObject jsonResult = srsClient.serviceSrsStream(0, Integer.MAX_VALUE);
        log.info("获取srs获取流列表结束，返回参数：{}", jsonResult);
        JSONArray streamsArray = jsonResult.getJSONArray("streams");

        //解析并封装返回参数
        JSONArray resultArray = new JSONArray();

        if (streamsArray != null && !streamsArray.isEmpty()) {
            streamsArray.stream()
                    .map(stream -> (JSONObject) stream)
                    .forEach(stream -> {
                        String streamId = stream.getStr("id");
                        String streamName = stream.getStr("name");
                        String streamUrl = stream.getStr("url");
                        String streamSn = stream.getStr("app");
                        String tcUrl = stream.getStr("tcUrl");

                        JSONObject publishObject = stream.getJSONObject("publish");
                        boolean active = publishObject.getBool("active");
                        Map<String, Object> map = new LinkedHashMap<>();
                        if ("all".equals(dockSn) || streamSn.equals(dockSn)) {
                            map.put("id", streamId);
                            map.put("name", streamName);
                            map.put("url", streamUrl);
                            map.put("sn", streamSn);
                            map.put("active", active);
                            map.put("tcUrl", tcUrl);
                        }
                        if (!map.isEmpty()) {
                            resultArray.add(JSONUtil.parseObj(map));
                        }
                    });
        }
        return resultArray;
    }

    @Override
    public String getDockPushLiveUrl(String dockSn) {

        return RTMP_PROTOCOL + srsConfig.getIp() + ":" + srsConfig.getRtmpPort() + "/" + dockSn + "/dock?token=" + srsConfig.getRtmpToken();
    }

    @Override
    public String getUavPushLiveUrl(String dockSn) {

        return RTMP_PROTOCOL + srsConfig.getIp() + ":" + srsConfig.getRtmpPort() + "/" + dockSn + "/uav?token=" + srsConfig.getRtmpToken();
    }

    @Override
    public SrsRecordDao getDao() {
        return srsRecordDao;
    }
}
