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）
 *
 * 浏览器策略：音频播放需要用户交互后才允许。
 * 默认开启轮询，音频在用户首次交互后自动解锁。
 */

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

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

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

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

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

// ============ 状态 ============

/** 是否启用提醒 */
const enabled = ref(true);

/** 是否正在轮询 */
let polling = false;

/** 定时器 ID */
let timerId: ReturnType<typeof setInterval> | null = null;

/** 上次记录的最新订单 ID */
let lastOrderId: number | undefined = undefined;

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

/** 是否已初始化（首次查询记录基准值，不触发提醒） */
let initialized = false;

/** 用户交互解锁音频的监听器（一次性） */
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();
  // 起始音量 0
  gainNode.gain.setValueAtTime(0, now);
  // 快速上升到 0.5（攻击阶段）
  gainNode.gain.linearRampToValueAtTime(0.5, now + 0.01);
  // 然后指数衰减到 0（释放阶段）
  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() {
  // 尝试初始化音频上下文（如果已解锁则生效，未解锁则静默失败）
  initAudioContext();
  playDingSound();
  speak(SPEECH_TEXT);
}

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

/**
 * 查询最新订单，检测是否有新订单
 */
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;
    }

    // 比较 orderId：如果变了且新 orderId 更大，说明有新订单
    if (
      currentOrderId !== lastOrderId &&
      (lastOrderId === undefined || (currentOrderId ?? 0) > lastOrderId)
    ) {
      // 有新订单！
      triggerNotify();
    }

    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;
  }
}

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

/**
 * 新订单提醒组合式函数
 *
 * 用法：
 * ```ts
 * const { enabled, toggle } = useOrderNotify();
 * // 用户点击开关时调用 toggle(true/false)
 * ```
 */
export function useOrderNotify() {
  // 组件挂载时自动启动（默认开启）
  onMounted(() => {
    // 注册用户交互解锁音频监听器
    registerAudioUnlock();
    // 自动开始轮询
    startPolling();
  });

  // 组件卸载时自动清理
  onBeforeUnmount(() => {
    stopPolling();
    // 清理交互监听器
    if (unlockHandler) {
      document.removeEventListener('click', unlockHandler);
      document.removeEventListener('keydown', unlockHandler);
      unlockHandler = null;
    }
  });

  /**
   * 切换提醒开关
   * @param value 是否启用
   */
  const toggle = (value: boolean) => {
    enabled.value = value;
    if (value) {
      // 用户交互触发，初始化音频上下文
      initAudioContext();
      startPolling();
    } else {
      stopPolling();
    }
  };

  /**
   * 测试提醒（用户点击测试按钮时调用）
   */
  const testNotify = () => {
    initAudioContext();
    triggerNotify();
  };

  return {
    enabled,
    toggle,
    testNotify
  };
}
