import { autoResetRef, createInjectionState } from "@vueuse/core";
import { shallowRef, reactive, ref, computed } from "vue";
import { Mutex } from "async-mutex";
import {
  OscilloscopeFullConfig,
  OscilloscopeDataResponse,
} from "@/APIClient";
import { AuthManager } from "@/utils/AuthManager";
import { useAlertStore } from "@/components/Alert";
import { useRequiredInjection } from "@/utils/Common";

export type OscilloscopeDataType = {
  x: number[];
  y: number[] | number[][];
  xUnit: "s" | "ms" | "us" | "ns";
  yUnit: "V" | "mV" | "uV";
  adFrequency: number;
  adVpp: number;
  adMax: number;
  adMin: number;
};

// 默认配置
const DEFAULT_CONFIG: OscilloscopeFullConfig = new OscilloscopeFullConfig({
  captureEnabled: false,
  triggerLevel: 128,
  triggerRisingEdge: true,
  horizontalShift: 0,
  decimationRate: 50,
  autoRefreshRAM: false,
});

// 采样频率常量（后端返回）
const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(() => {
  const oscData = shallowRef<OscilloscopeDataType>();
  const alert = useRequiredInjection(useAlertStore);

  // 互斥锁
  const operationMutex = new Mutex();

  // 状态
  const isApplying = ref(false);
  const isCapturing = ref(false);

  // 配置
  const config = reactive<OscilloscopeFullConfig>(new OscilloscopeFullConfig({ ...DEFAULT_CONFIG }));

  // 采样点数（由后端数据决定）
  const sampleCount = ref(0);

  // 采样周期（ns），由adFrequency计算
  const samplePeriodNs = computed(() =>
    oscData.value?.adFrequency ? 1_000_000_000 / oscData.value.adFrequency : 200
  );

  // 应用配置
  const applyConfiguration = async () => {
    if (operationMutex.isLocked()) {
      alert.warn("有其他操作正在进行中，请稍后再试", 3000);
      return;
    }
    const release = await operationMutex.acquire();
    isApplying.value = true;
    try {
      const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
      const success = await client.initialize({ ...config });
      if (success) {
        alert.success("示波器配置已应用", 2000);
      } else {
        throw new Error("应用失败");
      }
    } catch (error) {
      alert.error("应用配置失败", 3000);
    } finally {
      isApplying.value = false;
      release();
    }
  };

  // 重置配置
  const resetConfiguration = () => {
    Object.assign(config, { ...DEFAULT_CONFIG });
    alert.info("配置已重置", 2000);
  };

  const clearOscilloscopeData = () => {
    oscData.value = undefined;
  }

  // 获取数据
  const getOscilloscopeData = async () => {
    try {
      const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
      const resp: OscilloscopeDataResponse = await client.getData();

      // 解析波形数据
      const binaryString = atob(resp.waveformData);
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }
      sampleCount.value = bytes.length;

      // 构建时间轴
      const x = Array.from(
        { length: bytes.length },
        (_, i) => (i * samplePeriodNs.value) / 1000 // us
      );
      const y = Array.from(bytes);

      oscData.value = {
        x,
        y,
        xUnit: "us",
        yUnit: "V",
        adFrequency: resp.adFrequency,
        adVpp: resp.adVpp,
        adMax: resp.adMax,
        adMin: resp.adMin,
      };
    } catch (error) {
      alert.error("获取示波器数据失败", 3000);
    }
  };

  // 定时器引用
  let refreshIntervalId: number | undefined;
  // 刷新间隔（毫秒），可根据需要调整
  const refreshIntervalMs = ref(1000);

  // 定时刷新函数
  const startAutoRefresh = () => {
    if (refreshIntervalId !== undefined) return;
    refreshIntervalId = window.setInterval(async () => {
      await refreshRAM();
      await getOscilloscopeData();
    }, refreshIntervalMs.value);
  };

  const stopAutoRefresh = () => {
    if (refreshIntervalId !== undefined) {
      clearInterval(refreshIntervalId);
      refreshIntervalId = undefined;
      isCapturing.value = false;
    }
  };

  // 启动捕获
  const startCapture = async () => {
    if (operationMutex.isLocked()) {
      alert.warn("有其他操作正在进行中，请稍后再试", 3000);
      return;
    }
    isCapturing.value = true;
    const release = await operationMutex.acquire();
    try {
      const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
      const started = await client.startCapture();
      if (!started) throw new Error("无法启动捕获");
      alert.info("开始捕获...", 2000);

      // 启动定时刷新
      startAutoRefresh();
    } catch (error) {
      alert.error("捕获失败", 3000);
      isCapturing.value = false;
      stopAutoRefresh();
    } finally {
      release();
    }
  };

  // 停止捕获
  const stopCapture = async () => {
    if (!isCapturing.value) {
      alert.warn("当前没有正在进行的捕获操作", 2000);
      return;
    }
    isCapturing.value = false;
    stopAutoRefresh();
    const release = await operationMutex.acquire();
    try {
      const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
      const stopped = await client.stopCapture();
      if (!stopped) throw new Error("无法停止捕获");
      alert.info("捕获已停止", 2000);
    } catch (error) {
      alert.error("停止捕获失败", 3000);
    } finally {
      release();
    }
  };

  // 更新触发参数
  const updateTrigger = async (level: number, risingEdge: boolean) => {
    const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
    try {
      const ok = await client.updateTrigger(level, risingEdge);
      if (ok) {
        config.triggerLevel = level;
        config.triggerRisingEdge = risingEdge;
        alert.success("触发参数已更新", 2000);
      } else {
        throw new Error();
      }
    } catch {
      alert.error("更新触发参数失败", 2000);
    }
  };

  // 更新采样参数
  const updateSampling = async (horizontalShift: number, decimationRate: number) => {
    const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
    try {
      const ok = await client.updateSampling(horizontalShift, decimationRate);
      if (ok) {
        config.horizontalShift = horizontalShift;
        config.decimationRate = decimationRate;
        alert.success("采样参数已更新", 2000);
      } else {
        throw new Error();
      }
    } catch {
      alert.error("更新采样参数失败", 2000);
    }
  };

  // 手动刷新RAM
  const refreshRAM = async () => {
    const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
    try {
      const ok = await client.refreshRAM();
      if (ok) {
        // alert.success("RAM已刷新", 2000);
      } else {
        throw new Error();
      }
    } catch {
      alert.error("刷新RAM失败", 2000);
    }
  };

  // 生成测试数据
  const generateTestData = () => {
    const freq = 5_000_000;
    const duration = 0.001; // 1ms
    const points = Math.floor(freq * duration);
    const x = Array.from({ length: points }, (_, i) => (i * 1_000_000_000 / freq) / 1000);
    const y = Array.from({ length: points }, (_, i) =>
      Math.floor(Math.sin(i * 0.01) * 127 + 128)
    );
    oscData.value = {
      x,
      y,
      xUnit: "us",
      yUnit: "V",
      adFrequency: freq,
      adVpp: 2.0,
      adMax: 255,
      adMin: 0,
    };
    alert.success("测试数据生成成功", 2000);
  };

  return {
    oscData,
    config,
    isApplying,
    isCapturing,
    sampleCount,
    samplePeriodNs,
    refreshIntervalMs,

    applyConfiguration,
    resetConfiguration,
    clearOscilloscopeData,
    getOscilloscopeData,
    startCapture,
    stopCapture,
    updateTrigger,
    updateSampling,
    refreshRAM,
    generateTestData,
  };
});

export { useProvideOscilloscope, useOscilloscopeState, DEFAULT_CONFIG };