import { ref, onMounted, onBeforeUnmount } from 'vue';
import { pageShopOrder } from '@/api/shop/shopOrder';
import type { ShopOrder } from '@/api/shop/shopOrder/model';

/**
 * 新订单提醒 - 轮询检测 + 声音/语音播报
 *
 * 原理：
 * 1. 定时轮询 pageShopOrder（只查最新 1 条）
 * 2. 与上次记录的 orderId 比较，不同则说明有新订单
 * 3. 播放"叮"声（Web Audio API） + 语音播报"您有一条新的订单"（Speech Synthesis API）
 * 4. 同时触发 onNewOrder 回调，通知调用方刷新页面数据
 *
 * 浏览器策略：音频播放需要用户交互后才允许。
 * 默认开启轮询，音频在用户首次交互后自动解锁。
 *
 * **实例安全**：每次调用 useOrderNotify() 创建独立实例，
 * 多个页面可同时使用而不冲突。AudioContext 在模块级共享。
 */

// ============ 配置 ============

/** 轮询间隔（毫秒） */
const POLL_INTERVAL = 60_000;

/** 叮声频率（Hz），880 = 高音叮 */
const DING_FREQUENCY = 880;

/** 叮声持续时间（秒） */
const DING_DURATION = 0.3;

/** 语音播报文案 */
const SPEECH_TEXT = '您有一条新的订单';

// ============ 模块级共享状态（音频相关） ============

/** 音频上下文（模块级共享，延迟创建，需用户交互后） */
let audioCtx: AudioContext | null = null;

/** 用户交互解锁音频的监听器（模块级，全局只注册一次） */
let unlockHandler: (() => void) | null = null;

// ============ 声音播放 ============

/**
 * 初始化 AudioContext（必须在用户交互后调用才能生效）
 */
function initAudioContext() {
  if (!audioCtx) {
    try {
      audioCtx = new (window.AudioContext ||
        (window as any).webkitAudioContext)();
    } catch (e) {
      console.warn('[订单提醒] AudioContext 创建失败:', e);
      return;
    }
  }
  // 如果上下文被暂停（浏览器策略），尝试恢复
  if (audioCtx.state === 'suspended') {
    audioCtx.resume();
  }
}

/**
 * 注册用户交互监听器，首次交互时解锁音频
 * 浏览器策略：音频播放需要用户交互后才允许，注册一次性监听器自动解锁
 * 全局只注册一次，多实例共享
 */
function registerAudioUnlock() {
  if (unlockHandler) return;

  unlockHandler = () => {
    initAudioContext();
    // 解锁后移除监听器
    if (unlockHandler) {
      document.removeEventListener('click', unlockHandler);
      document.removeEventListener('keydown', unlockHandler);
      unlockHandler = null;
    }
  };

  document.addEventListener('click', unlockHandler, { once: true });
  document.addEventListener('keydown', unlockHandler, { once: true });
}

/**
 * 播放"叮"声 - 使用 Web Audio API 生成，无需音频文件
 */
function playDingSound() {
  if (!audioCtx) return;

  const now = audioCtx.currentTime;

  // 创建振荡器
  const oscillator = audioCtx.createOscillator();
  oscillator.type = 'sine';
  oscillator.frequency.setValueAtTime(DING_FREQUENCY, now);

  // 创建增益节点（控制音量包络）
  const gainNode = audioCtx.createGain();
  gainNode.gain.setValueAtTime(0, now);
  gainNode.gain.linearRampToValueAtTime(0.5, now + 0.01);
  gainNode.gain.exponentialRampToValueAtTime(0.001, now + DING_DURATION);

  // 连接：振荡器 → 增益 → 输出
  oscillator.connect(gainNode);
  gainNode.connect(audioCtx.destination);

  // 播放
  oscillator.start(now);
  oscillator.stop(now + DING_DURATION);
}

/**
 * 语音播报 - 使用浏览器原生 Speech Synthesis API
 */
function speak(text: string) {
  if (!('speechSynthesis' in window)) return;

  // 取消可能正在进行的播报
  window.speechSynthesis.cancel();

  const utterance = new SpeechSynthesisUtterance(text);
  utterance.lang = 'zh-CN';
  utterance.rate = 1;
  utterance.pitch = 1;
  utterance.volume = 1;

  window.speechSynthesis.speak(utterance);
}

/**
 * 触发提醒：叮声 + 语音播报 + 通知回调
 */
function triggerNotify(onNewOrderCallback: (() => void) | null) {
  initAudioContext();
  playDingSound();
  speak(SPEECH_TEXT);
  if (onNewOrderCallback) {
    onNewOrderCallback();
  }
}

// ============ 对外接口 ============

/**
 * 新订单提醒组合式函数
 *
 * 用法：
 * ```ts
 * const { enabled, toggle, testNotify } = useOrderNotify({
 *   onNewOrder: () => reload()
 * });
 * ```
 *
 * @param options.onNewOrder 检测到新订单时的回调（通常用于刷新页面数据）
 */
export function useOrderNotify(options?: { onNewOrder?: () => void }) {
  // ============ 实例级状态 ============
  const enabled = ref(true);
  let polling = false;
  let timerId: ReturnType<typeof setInterval> | null = null;
  let lastOrderId: number | undefined = undefined;
  let initialized = false;
  let onNewOrderCallback: (() => void) | null = options?.onNewOrder ?? null;

  // ============ 轮询逻辑 ============

  async function checkNewOrder() {
    try {
      const result = await pageShopOrder({
        page: 1,
        limit: 1,
        type: 0
      });

      const latestOrder: ShopOrder | undefined = result?.list?.[0];

      if (!latestOrder) {
        lastOrderId = undefined;
        return;
      }

      const currentOrderId = latestOrder.orderId;

      if (!initialized) {
        lastOrderId = currentOrderId;
        initialized = true;
        return;
      }

      if (
        currentOrderId !== lastOrderId &&
        (lastOrderId === undefined || (currentOrderId ?? 0) > lastOrderId)
      ) {
        triggerNotify(onNewOrderCallback);
      }

      lastOrderId = currentOrderId;
    } catch (error) {
      console.warn('[订单提醒] 轮询查询失败:', error);
    }
  }

  function startPolling() {
    if (polling) return;
    polling = true;
    initialized = false;

    checkNewOrder();
    timerId = setInterval(checkNewOrder, POLL_INTERVAL);
  }

  function stopPolling() {
    polling = false;
    if (timerId) {
      clearInterval(timerId);
      timerId = null;
    }
  }

  // ============ 生命周期 ============

  onMounted(() => {
    registerAudioUnlock();
    startPolling();
  });

  onBeforeUnmount(() => {
    stopPolling();
    onNewOrderCallback = null;
  });

  // ============ 对外方法 ============

  const toggle = (value: boolean) => {
    enabled.value = value;
    if (value) {
      initAudioContext();
      startPolling();
    } else {
      stopPolling();
    }
  };

  const testNotify = () => {
    initAudioContext();
    triggerNotify(onNewOrderCallback);
  };

  return {
    enabled,
    toggle,
    testNotify
  };
}
