const fs = require("fs");
const path = require("path");
const { localGet, localSave } = require("./lib/unit");
const logger = require("./lib/logger");

// 默认编码器配置
const defaultEncoderConfig = {
  enabled: false,
  gpioAPin: 5,  // 固定为GPIO5
  gpioBPin: 6,  // 固定为GPIO6
  ppr: 100,     // 每转脉冲数
  mode: "x4",   // 编码器模式
  intervalMs: 1000, // 更新间隔
  pollIntervalMs: 2,
  forcePolling: false,
  glitchUs: 0,
  invert: false,
  gpioBackend: "",
  gpiodChip: "gpiochip0",
  gpiodLineA: null,
  gpiodLineB: null,
  gpiodBias: "as-is",
  gpiodActiveLow: false,
  wheelDiameterMm: 65,
  wheelCircumferenceMm: 0,
  speedUnit: "km/h",
  speedLabel: "车速",
  rpmLabel: "转速",
  directionLabel: "方向",
  showRpm: true,
  showDirection: false,
};

const encoderConfigPath = path.resolve(__dirname, "encoder.config.json");

// 加载编码器配置
const loadEncoderConfig = () => {
  const fileConfig = localGet(encoderConfigPath);
  const merged = { ...defaultEncoderConfig, ...fileConfig };
  if (!fs.existsSync(encoderConfigPath)) {
    localSave(encoderConfigPath, merged);
  }
  return merged;
};

// 归一化速度单位
const normalizeSpeedUnit = (unit) => {
  const key = String(unit || "").toLowerCase();
  if (["mps", "m/s", "ms"].includes(key)) return "m/s";
  if (["kmh", "km/h", "kph"].includes(key)) return "km/h";
  if (["mph"].includes(key)) return "mph";
  return "km/h";
};

// 根据RPM计算速度
const calcSpeedFromRpm = (rpm, config) => {
  const diameterMm = Number(config.wheelDiameterMm) || 0;
  const circumferenceMm = Number(config.wheelCircumferenceMm) || 0;
  const circumferenceM = (circumferenceMm > 0 ? circumferenceMm : Math.PI * diameterMm) / 1000;
  if (!circumferenceM || !Number.isFinite(circumferenceM)) {
    return { speed: 0, unit: normalizeSpeedUnit(config.speedUnit) };
  }

  const speedMps = (rpm * circumferenceM) / 60;
  const unit = normalizeSpeedUnit(config.speedUnit);
  if (unit === "m/s") return { speed: speedMps, unit };
  if (unit === "mph") return { speed: speedMps * 2.236936, unit };
  return { speed: speedMps * 3.6, unit };
};

let encoderInstance = null;
let encoderConfig = loadEncoderConfig();

// 编码器类
class EncoderModule {
  constructor() {
    this.encoder = null;
    this.handler = null;
    this.isRunning = false;
  }

  // 启动编码器
  async start(config, handler) {
    if (this.isRunning) {
      this.stop();
    }

    if (!config.enabled) {
      logger.info("编码器未启用，跳过启动");
      return;
    }

    try {
      // 检查GPIO引脚是否可用
      let GpioLib;
      try {
        GpioLib = require('onoff').Gpio;
      } catch (e) {
        logger.warn("GPIO库不可用，编码器功能已禁用");
        return;
      }

      // 检查GPIO引脚是否能够正确初始化
      try {
        // 初始化两个GPIO引脚
        const gpioA = new GpioLib(config.gpioAPin, 'in', 'both');
        const gpioB = new GpioLib(config.gpioBPin, 'in', 'both');

        // 简单的物理编码器检测：监测引脚状态变化
        let lastStateA = gpioA.readSync();
        let lastStateB = gpioB.readSync();
        let hasActivity = false;
        
        // 检测5秒内是否有引脚活动
        const activityCheckInterval = setInterval(() => {
          const currentStateA = gpioA.readSync();
          const currentStateB = gpioB.readSync();
          
          if (currentStateA !== lastStateA || currentStateB !== lastStateB) {
            hasActivity = true;
          }
          
          lastStateA = currentStateA;
          lastStateB = currentStateB;
        }, 100); // 每100ms检查一次

        setTimeout(() => {
          clearInterval(activityCheckInterval);
          gpioA.unexport();
          gpioB.unexport();
          
          if (!hasActivity) {
            logger.warn(`GPIO引脚(${config.gpioAPin}, ${config.gpioBPin})上未检测到编码器活动，编码器功能已禁用`);
            return; // 没有检测到活动，禁用编码器
          }
          
          logger.info(`在GPIO引脚(${config.gpioAPin}, ${config.gpioBPin})上检测到活动，编码器功能将被启用`);
          // 这里可以继续实现编码器逻辑（如果有可用库的话）
        }, 5000); // 5秒检测期
        
      } catch (gpioError) {
        logger.warn(`GPIO引脚不可用 (${config.gpioAPin}, ${config.gpioBPin}): ${gpioError.message}，编码器功能已禁用`);
        return;
      }

      this.handler = handler;
      this.isRunning = true;
      logger.info(`编码器监测启动，GPIO引脚: A-${config.gpioAPin}, B-${config.gpioBPin}`);

    } catch (error) {
      logger.warn("编码器启动失败，功能已禁用: " + error.message);
      return; // 直接返回，不使用模拟模式
    }
  }



  // 停止编码器
  stop() {
    if (this.encoder) {
      this.encoder.removeAllListeners();
      this.encoder = null;
    }
    
    this.handler = null;
    this.isRunning = false;
    logger.info("编码器已停止");
  }

  // 更新配置
  updateConfig(newConfig) {
    encoderConfig = { ...encoderConfig, ...newConfig };
    localSave(encoderConfigPath, encoderConfig);
    
    // 如果编码器正在运行，重启它
    if (this.isRunning) {
      this.start(encoderConfig, this.handler);
    }
  }

  // 获取当前配置
  getConfig() {
    return encoderConfig;
  }

  // 获取状态
  getStatus() {
    return {
      isRunning: this.isRunning,
      config: this.getConfig()
    };
  }
}

// 创建单例实例
const encoderModule = new EncoderModule();

// 导出API
module.exports = {
  encoderModule,
  loadEncoderConfig,
  calcSpeedFromRpm,
  normalizeSpeedUnit,
  defaultEncoderConfig
};