class RtspServer {
  constructor() {
    const path = require('path');
    const electron = require('electron');
    const app = (electron.remote || electron).app;
    this.basePath = __dirname;
    if (app.isPackaged) {
      this.basePath = process.resourcesPath;
    }
    this.ffmpegPath = path.join(this.basePath, 'ffmpeg', 'windows', 'ffmpeg.exe');
    this.mediamtxPath = path.join(this.basePath, 'ffmpeg', 'windows', 'mediamtx.exe');
    if (global.process.platform === 'linux') {
      this.ffmpegPath = 'ffmpeg';
      this.mediamtxPath = path.join(this.basePath, 'ffmpeg', 'linux', 'mediamtx');
    }
    this.deviceIp = '';
    this.timer = null;
    this.mediamtxProcess = null;
    this.ffmpegProcess = null;
    this.createdIng = false; //是否正在创建中
    this.stateOptions = {
      videoDevicePath: '', // 视频流串口地址
      streamType: 1, //  1:rtsp视频流 2:http视频流
      autoCloseTime: 60 * 3, //  自动关闭时间，单位：秒 0:不关闭 默认3分钟
      localIp: '', //  本机IP
      port: 8554, // 视频流端口
      StreamingTool: 'vlc', //推流工具vlc   ffmpeg
      suffix: '',
    };
  }
  getCameraList() {
    return new Promise((resolve, reject) => {
      const { exec } = require('child_process');
      exec(`"${this.ffmpegPath}" -list_devices true -f dshow -i dummy`, (error, stdout, stderr) => {
        if (error) {
          // FFmpeg会通过stderr输出设备信息
          const devices = [];
          const lines = stderr.split('\n');

          let inVideoDevices = false;
          for (const line of lines) {
            if (line.includes('DirectShow video devices')) {
              inVideoDevices = true;
              continue;
            }
            if (line.includes('DirectShow audio devices')) {
              break;
            }
            if (inVideoDevices && line.includes(']  "')) {
              const deviceName = line.split('"')[1];
              if (deviceName) {
                devices.push(deviceName);
              }
            }
          }

          resolve(devices);
        } else {
          reject(new Error('无法获取设备列表'));
        }
      });
    });
  }

  createServer() {
    const { spawn, execSync } = require('child_process');
    const fs = require('fs');
    const path = require('path');
    if (global.process.platform === 'linux') {
      execSync(`sudo chmod 777 ${this.mediamtxPath}`);
      let mediamtxYml = path.join(this.basePath, 'ffmpeg', 'linux', 'mediamtx.yml');
      let localmediamtxYml = '/home/pi/mediamtx.yml';
      if (!fs.existsSync(localmediamtxYml)) {
        fs.copyFileSync(mediamtxYml, localmediamtxYml);
      }
    } else if (global.process.platform === 'win32') {
      let mediamtxYml = path.join(this.basePath, 'ffmpeg', 'windows', 'mediamtx.yml');
      let localmediamtxYml = path.join(process.cwd(), 'mediamtx.yml');
      if (!fs.existsSync(localmediamtxYml)) {
        fs.copyFileSync(mediamtxYml, localmediamtxYml);
      }
    }
    const mediamtxProcess = spawn(this.mediamtxPath, [], {
      windowsHide: true,
    });

    // process.stdout.on("data", (data) => {
    //  this.ktLog(`[MediaMTX stdout] ${data.toString()}`);
    // });
    mediamtxProcess.stderr.on('data', (data) => {
      this.ktLog(`[MediaMTX ERR] ${data.toString()}`);
    });
    mediamtxProcess.on('close', (code) => {
      this.ktLog(`MediaMTX 进程退出，代码 ${code}`);
      this.mediamtxProcess = null;
    });
    // 错误处理
    mediamtxProcess.on('error', (err) => {
      this.ktLog(`启动 MediaMTX 失败:${err.message}`);
      this.mediamtxProcess = null;
    });
    this.mediamtxProcess = mediamtxProcess;
  }

  createRtsp(cameraName, exitCallback) {
    const { spawn } = require('child_process');
    const ffmpegArgs = [
      '-f',
      global.process.platform === 'linux' ? 'v4l2' : 'dshow',
      '-i',
      global.process.platform === 'linux' ? `/dev/video0` : `video=${cameraName}`,

      // 视频编码优化
      '-c:v',
      'libx264',
      '-preset',
      'ultrafast',
      '-tune',
      'zerolatency',
      '-x264-params',
      'keyint=15:min-keyint=15:no-scenecut=1',

      // 分辨率/帧率控制
      '-s',
      '640x480', // 明确指定分辨率
      '-r',
      '25', // 固定帧率

      // 码率控制
      '-b:v',
      '2000k', // 基础码率
      '-maxrate',
      '2500k',
      '-bufsize',
      '1000k',

      // 传输协议优化
      '-rtsp_transport',
      'tcp', // 改用TCP更稳定
      '-muxdelay',
      '0.1',

      // 容器格式
      '-f',
      'rtsp',
      '-flags',
      'low_delay',

      // 输出地址
      `rtsp://${this.deviceIp}:${this.stateOptions.port}/${this.stateOptions.suffix}`,
    ];

    this.ktLog(`创建 rtsp 推流服务:${JSON.stringify(ffmpegArgs)}`);
    // 启动 FFmpeg 进程
    const ffmpegProcess = spawn(this.ffmpegPath, ffmpegArgs, {
      windowsHide: true,
    });
    // 日志处理
    ffmpegProcess.stderr.on('data', (data) => {
      // 实时输出 FFmpeg 日志
      process.stderr.write(data);
    });

    ffmpegProcess.on('close', (code) => {
      this.ktLog(`FFmpeg 进程退出，代码 ${code}`);
      if (exitCallback) exitCallback(ffmpegProcess.pid);
      this.ffmpegProcess = null;
    });

    // 错误处理
    ffmpegProcess.on('error', (err) => {
      this.ktLog(`启动 FFmpeg 失败:${err.message}`);
      if (exitCallback) exitCallback(ffmpegProcess.pid);
      this.ffmpegProcess = null;
    });
    this.ffmpegProcess = ffmpegProcess;
    return {
      rtsp: `rtsp://${this.deviceIp}:${this.stateOptions.port}/${this.stateOptions.suffix}`,
      rtmp: `rtmp://${this.deviceIp}:1935/${this.stateOptions.suffix}`,
      webRTC: `http://${this.deviceIp}:8889/${this.stateOptions.suffix}/`, //chrom 浏览器直接播放地址
      hls: `http://${this.deviceIp}:8888/${this.stateOptions.suffix}/index.m3u8`,
      httpFLV: `http://${this.deviceIp}:8888/${this.stateOptions.suffix}.flv`,
    };
  }

  async start(options, exitCallback) {
    try {
      this.deviceIp = options.localIp;
      this.stateOptions = { ...this.stateOptionsDefault, ...options };
      if (this.createdIng) return;
      if (this.mediamtxProcess && this.ffmpegProcess) return { state: true, rtsp: `rtsp://${this.deviceIp}:${options.port}/${options.suffix}` };
      this.createdIng = true;
      this.stop();
      this.ktLog(`创建 rtsp 服务`);
      let cameraList = [''];
      if (global.process.platform === 'win32') {
        cameraList = await this.getCameraList();
      }
      return new Promise((resolve) => {
        this.createServer();
        this.timer && clearTimeout(this.timer);
        this.timer = setTimeout(() => {
          const data = this.createRtsp(cameraList[0], exitCallback);
          this.timer = setTimeout(() => {
            this.timer = null;
            this.createdIng = false;
            if (this.ffmpegProcess && !this.ffmpegProcess.killed) {
              data.state = true;
            } else {
              data.state = false;
            }
            resolve(data);
          }, 3000);
        }, 500);
      });
    } catch (err) {
      this.createdIng = false;
      this.ktLog(`FFmpeg 创建 rtsp 流失败：${err.message}`);
      return {};
    }
  }

  stop() {
    try {
      if (this.mediamtxProcess) {
        this.mediamtxProcess.kill();
      }
      if (this.ffmpegProcess) {
        this.ffmpegProcess.kill();
      }
      this.mediamtxProcess = null;
      this.ffmpegProcess = null;
      const { execSync } = require('child_process');
      if (global.process.platform === 'win32') {
        try {
          execSync('taskkill /IM mediamtx.exe /F');
        } catch (err) {}
        execSync('taskkill /IM ffmpeg.exe /F');
      } else {
        try {
          execSync('killall  mediamtx');
        } catch (err) {}

        execSync('killall ffmpeg');
      }
    } catch (err) {
      this.ktLog(`kill ffmpeg mediamtx ${err.message}`);
    }
  }
  ktLog(message) {
    if (global.ktLog && global.ktLog.i) {
      global.ktLog.i(message);
    }
  }
}
module.exports = new RtspServer();
