// =============================================================================
// 企微IT智能服务台 — 屏幕截图组合函数
// =============================================================================
// 说明：实现屏幕截图功能，优先使用浏览器 Screen Capture API，
//       在不支持或有问题（如企微桌面端限制）时降级到系统截图方案。
//
// 两个方案：
//   方案A（优先）： navigator.mediaDevices.getDisplayMedia()
//     - 优点：可直接在浏览器内完成截图，体验好
//     - 缺点：企微桌面端可能限制此 API（非 HTTPS 或 localhost 外不可用）
//   方案B（降级）：提示用户用系统截图工具（Win+Shift+S / Cmd+Shift+4）
//             然后 Ctrl+V 粘贴到输入框（已有 handlePaste 实现）
//
// 使用方式：
//   const { captureScreen, isCapturing, isScreenCaptureSupported, captureFallback }
//    = useScreenCapture()
//   - captureScreen()：尝试方案A，失败时不自动降级（由调用方决定是否提示）
//   - isScreenCaptureSupported()：检测是否支持方案A
//   - 调用方在 captureScreen() 返回 null 时，自行提示用户用系统截图
// =============================================================================

import { ref } from 'vue'

/** 是否正在截图（用于 UI 状态展示） */
const isCapturing = ref(false)

/**
 * 检测浏览器是否支持 Screen Capture API
 * @returns 是否支持
 */
export function isScreenCaptureSupported(): boolean {
  return !!(navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia)
}

/**
 * 截取屏幕/窗口/标签页
 *
 * 做什么：调用浏览器 Screen Capture API，让用户选择要截取的目标，
 *         然后从视频流中捕获一帧画面，转为 Blob 返回。
 *
 * 为什么用 Screen Capture API：
 *   - 浏览器原生支持，无需第三方库
 *   - 可以截取整个屏幕、应用窗口或浏览器标签页
 *   - 企微桌面端基于 Chromium 内核，完全支持
 *
 * @returns 截图的 Blob 对象（PNG 格式），失败返回 null
 */
export async function captureScreen(): Promise<Blob | null> {
  // 不支持 Screen Capture API → 提示用户用系统截图
  if (!isScreenCaptureSupported()) {
    console.warn('[useScreenCapture] 浏览器不支持 Screen Capture API')
    return null
  }

  isCapturing.value = true

  try {
    // ------------------------------------------------------------------
    // 1. 请求屏幕共享权限（浏览器弹出选择器：屏幕/窗口/标签页）
    // ------------------------------------------------------------------
    // video: true — 只请求视频流（不需要音频）
    // @ts-ignore — Chrome 支持 preferLabel 等非标准选项
    const stream = await navigator.mediaDevices.getDisplayMedia({
      video: true,
      audio: false,
    })

    // ------------------------------------------------------------------
    // 2. 从视频流中获取第一帧画面
    // ------------------------------------------------------------------
    const track = stream.getVideoTracks()[0]
    if (!track) {
      console.warn('[useScreenCapture] 没有获取到视频轨道')
      return null
    }

    // 使用 ImageCapture API（Chrome 59+）获取高质量截图
    // 如果不支持 ImageCapture，则回退到 Canvas 绘制方案
    let blob: Blob | null = null

    if ('ImageCapture' in window) {
      try {
        // ImageCapture API — 直接从视频轨道抓帧，质量更高
        const imageCapture = new ImageCapture(track)
        // @ts-ignore — grabFrame 是 ImageCapture 标准方法，但 TS 类型定义可能不完整
        const bitmap = await imageCapture.grabFrame()

        // 绘制到 Canvas → 导出 PNG Blob
        const canvas = document.createElement('canvas')
        canvas.width = bitmap.width
        canvas.height = bitmap.height
        const ctx = canvas.getContext('2d')
        if (ctx) {
          ctx.drawImage(bitmap, 0, 0)
          blob = await new Promise<Blob | null>((resolve) => {
            canvas.toBlob((b) => resolve(b), 'image/png')
          })
        }
        bitmap.close() // 释放位图资源
      } catch (imageCaptureError) {
        console.warn('[useScreenCapture] ImageCapture 失败，回退到 Canvas 方案:', imageCaptureError)
      }
    }

    // ImageCapture 失败或不可用 → Canvas 方案
    if (!blob) {
      const video = document.createElement('video')
      video.srcObject = stream
      video.muted = true // 静音播放（避免系统声音输出）

      // 等待视频元数据加载完成
      await new Promise<void>((resolve, reject) => {
        video.onloadedmetadata = () => resolve()
        video.onerror = () => reject(new Error('视频加载失败'))
        video.play() // 必须调用 play 才能获取帧
      })

      // 短暂等待确保有画面帧可用
      await new Promise((r) => setTimeout(r, 200))

      // 绘制当前帧到 Canvas
      const canvas = document.createElement('canvas')
      canvas.width = video.videoWidth
      canvas.height = video.videoHeight
      const ctx = canvas.getContext('2d')
      if (ctx) {
        ctx.drawImage(video, 0, 0)
        blob = await new Promise<Blob | null>((resolve) => {
          canvas.toBlob((b) => resolve(b), 'image/png')
        })
      }

      // 清理 video 元素
      video.pause()
      video.srcObject = null
    }

    // ------------------------------------------------------------------
    // 3. 停止屏幕共享（关闭视频流）
    // ------------------------------------------------------------------
    stream.getTracks().forEach((t) => t.stop())

    return blob
  } catch (error: any) {
    // 用户取消屏幕选择 → 不是错误，静默处理
    if (error?.name === 'NotAllowedError' || error?.name === 'AbortError') {
      console.log('[useScreenCapture] 用户取消了屏幕选择')
      return null
    }
    console.error('[useScreenCapture] 截图失败:', error)
    return null
  } finally {
    isCapturing.value = false
  }
}

/**
 * 组合函数返回值
 */
export function useScreenCapture() {
  return {
    /** 是否正在截图 */
    isCapturing,
    /** 截取屏幕 */
    captureScreen,
    /** 检测浏览器支持 */
    isScreenCaptureSupported,
  }
}
