/**
 * Cloudflare Stream API 封装
 *
 * 使用方式：
 * 1. 直接调用 Cloudflare API（需要 API Token，适合后端代理）
 * 2. 通过后端代理调用（推荐，避免暴露 Token）
 *
 * API 文档：https://developers.cloudflare.com/stream/
 */

import axios, { type AxiosInstance } from 'axios'
import type {
  CloudflareVideo,
  CloudflareLiveInput,
  CloudflareLiveOutput,
  CloudflareApiResponse,
  CloudflareListResponse,
  CreateLiveInputParams,
  CreateUploadUrlParams,
  DirectUploadResponse,
  VideoPlaybackInfo
} from '@/types/cloudflare'

// Cloudflare Stream 配置
export interface CloudflareStreamConfig {
  accountId: string // Cloudflare Account ID
  apiToken?: string // API Token（直接调用时需要）
  customerSubdomain?: string // 客户子域名，如 customer-xxx
  baseUrl?: string // 自定义 API 基础 URL（用于后端代理）
}

class CloudflareStreamApi {
  private client: AxiosInstance

  private config: CloudflareStreamConfig

  constructor(config: CloudflareStreamConfig) {
    this.config = config

    // 创建 axios 实例
    this.client = axios.create({
      baseURL: config.baseUrl || `https://api.cloudflare.com/client/v4/accounts/${config.accountId}/stream`,
      timeout: 30000,
      headers: {
        'Content-Type': 'application/json',
        ...(config.apiToken ? { Authorization: `Bearer ${config.apiToken}` } : {})
      }
    })

    // 响应拦截器
    this.client.interceptors.response.use(
      (response) => response.data,
      (error) => {
        console.error('Cloudflare Stream API Error:', error.response?.data || error.message)
        return Promise.reject(error)
      }
    )
  }

  /**
   * 获取客户播放域名
   */
  getCustomerDomain(): string {
    return this.config.customerSubdomain
      ? `customer-${this.config.customerSubdomain}.cloudflarestream.com`
      : `customer-${this.config.accountId}.cloudflarestream.com`
  }

  // ==================== 视频管理 ====================

  /**
   * 获取视频列表
   */
  async listVideos(params?: {
    after?: string
    before?: string
    include_counts?: boolean
    search?: string
    limit?: number
    asc?: boolean
    status?: string
  }): Promise<CloudflareListResponse<CloudflareVideo>> {
    return this.client.get('', { params })
  }

  /**
   * 获取视频详情
   */
  async getVideo(videoId: string): Promise<CloudflareApiResponse<CloudflareVideo>> {
    return this.client.get(`/${videoId}`)
  }

  /**
   * 删除视频
   */
  async deleteVideo(videoId: string): Promise<CloudflareApiResponse<null>> {
    return this.client.delete(`/${videoId}`)
  }

  /**
   * 更新视频元数据
   */
  async updateVideo(
    videoId: string,
    data: {
      meta?: Record<string, any>
      allowedOrigins?: string[]
      requireSignedURLs?: boolean
      scheduledDeletion?: string
      uploadExpiry?: string
    }
  ): Promise<CloudflareApiResponse<CloudflareVideo>> {
    return this.client.post(`/${videoId}`, data)
  }

  /**
   * 从 URL 复制视频
   */
  async copyFromUrl(url: string, meta?: Record<string, any>): Promise<CloudflareApiResponse<CloudflareVideo>> {
    return this.client.post('/copy', { url, meta })
  }

  /**
   * 裁剪视频
   */
  async clipVideo(params: {
    clippedFromVideoUID: string
    startTimeSeconds: number
    endTimeSeconds: number
    meta?: Record<string, any>
  }): Promise<CloudflareApiResponse<CloudflareVideo>> {
    return this.client.post('/clip', params)
  }

  // ==================== 上传管理 ====================

  /**
   * 创建直接上传 URL（TUS 协议）
   */
  async createDirectUploadUrl(
    params?: CreateUploadUrlParams
  ): Promise<CloudflareApiResponse<DirectUploadResponse['result']>> {
    return this.client.post('/direct_upload', params || {})
  }

  /**
   * 使用 TUS 协议上传视频
   * 注意：需要先安装 tus-js-client：npm install tus-js-client
   */
  async uploadWithTus(file: File, uploadUrl: string, onProgress?: (progress: number) => void): Promise<void> {
    // 动态导入 tus-js-client（需要先安装：npm install tus-js-client）
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const tusClient = (await import('tus-js-client' as any)) as any
    const Upload = tusClient.Upload || tusClient.default?.Upload

    if (!Upload) {
      throw new Error('tus-js-client not installed. Run: npm install tus-js-client')
    }

    return new Promise((resolve, reject) => {
      const upload = new Upload(file, {
        endpoint: uploadUrl,
        retryDelays: [0, 3000, 5000, 10000, 20000],
        metadata: {
          filename: file.name,
          filetype: file.type
        },
        onError: (error: Error) => {
          console.error('Upload failed:', error)
          reject(error)
        },
        onProgress: (bytesUploaded: number, bytesTotal: number) => {
          const percentage = Math.round((bytesUploaded / bytesTotal) * 100)
          onProgress?.(percentage)
        },
        onSuccess: () => {
          resolve()
        }
      })

      upload.start()
    })
  }

  // ==================== 播放相关 ====================

  /**
   * 获取视频播放信息
   */
  getPlaybackInfo(videoId: string): VideoPlaybackInfo {
    const domain = this.getCustomerDomain()
    return {
      uid: videoId,
      preview: `https://${domain}/${videoId}/watch`,
      thumbnail: `https://${domain}/${videoId}/thumbnails/thumbnail.jpg`,
      playback: {
        hls: `https://${domain}/${videoId}/manifest/video.m3u8`,
        dash: `https://${domain}/${videoId}/manifest/video.mpd`
      },
      iframe: `https://${domain}/${videoId}/iframe`
    }
  }

  /**
   * 生成带时间戳的缩略图 URL
   */
  getThumbnailUrl(
    videoId: string,
    options?: {
      time?: string // 时间，如 "1s", "5m30s"
      height?: number // 高度
      width?: number // 宽度
      fit?: 'crop' | 'clip' | 'scale' | 'fill'
    }
  ): string {
    const domain = this.getCustomerDomain()
    const params = new URLSearchParams()
    if (options?.time) params.set('time', options.time)
    if (options?.height) params.set('height', options.height.toString())
    if (options?.width) params.set('width', options.width.toString())
    if (options?.fit) params.set('fit', options.fit)
    const queryString = params.toString()
    return `https://${domain}/${videoId}/thumbnails/thumbnail.jpg${queryString ? `?${queryString}` : ''}`
  }

  /**
   * 生成动图预览 URL
   */
  getAnimatedThumbnailUrl(
    videoId: string,
    options?: {
      start?: string // 开始时间
      end?: string // 结束时间
      height?: number
      width?: number
      fit?: 'crop' | 'clip' | 'scale' | 'fill'
      fps?: number
    }
  ): string {
    const domain = this.getCustomerDomain()
    const params = new URLSearchParams()
    if (options?.start) params.set('start', options.start)
    if (options?.end) params.set('end', options.end)
    if (options?.height) params.set('height', options.height.toString())
    if (options?.width) params.set('width', options.width.toString())
    if (options?.fit) params.set('fit', options.fit)
    if (options?.fps) params.set('fps', options.fps.toString())
    const queryString = params.toString()
    return `https://${domain}/${videoId}/thumbnails/thumbnail.gif${queryString ? `?${queryString}` : ''}`
  }

  // ==================== 直播管理 ====================

  /**
   * 获取直播输入列表
   */
  async listLiveInputs(): Promise<CloudflareListResponse<CloudflareLiveInput>> {
    return this.client.get('/live_inputs')
  }

  /**
   * 创建直播输入
   */
  async createLiveInput(params?: CreateLiveInputParams): Promise<CloudflareApiResponse<CloudflareLiveInput>> {
    return this.client.post('/live_inputs', params || {})
  }

  /**
   * 获取直播输入详情
   */
  async getLiveInput(liveInputId: string): Promise<CloudflareApiResponse<CloudflareLiveInput>> {
    return this.client.get(`/live_inputs/${liveInputId}`)
  }

  /**
   * 更新直播输入
   */
  async updateLiveInput(
    liveInputId: string,
    params: CreateLiveInputParams
  ): Promise<CloudflareApiResponse<CloudflareLiveInput>> {
    return this.client.put(`/live_inputs/${liveInputId}`, params)
  }

  /**
   * 删除直播输入
   */
  async deleteLiveInput(liveInputId: string): Promise<CloudflareApiResponse<null>> {
    return this.client.delete(`/live_inputs/${liveInputId}`)
  }

  /**
   * 获取直播输入的播放信息
   */
  getLivePlaybackInfo(liveInputId: string): VideoPlaybackInfo {
    const domain = this.getCustomerDomain()
    return {
      uid: liveInputId,
      preview: `https://${domain}/${liveInputId}/watch`,
      thumbnail: `https://${domain}/${liveInputId}/thumbnails/thumbnail.jpg`,
      playback: {
        hls: `https://${domain}/${liveInputId}/manifest/video.m3u8`,
        dash: `https://${domain}/${liveInputId}/manifest/video.mpd`
      },
      iframe: `https://${domain}/${liveInputId}/iframe`
    }
  }

  // ==================== 直播输出（转推） ====================

  /**
   * 获取直播输出列表
   */
  async listLiveOutputs(liveInputId: string): Promise<CloudflareListResponse<CloudflareLiveOutput>> {
    return this.client.get(`/live_inputs/${liveInputId}/outputs`)
  }

  /**
   * 创建直播输出（转推到其他平台）
   */
  async createLiveOutput(
    liveInputId: string,
    params: {
      url: string
      streamKey: string
      enabled?: boolean
    }
  ): Promise<CloudflareApiResponse<CloudflareLiveOutput>> {
    return this.client.post(`/live_inputs/${liveInputId}/outputs`, params)
  }

  /**
   * 删除直播输出
   */
  async deleteLiveOutput(liveInputId: string, outputId: string): Promise<CloudflareApiResponse<null>> {
    return this.client.delete(`/live_inputs/${liveInputId}/outputs/${outputId}`)
  }

  // ==================== 录像管理 ====================

  /**
   * 获取直播录像列表
   */
  async listLiveRecordings(liveInputId: string): Promise<CloudflareListResponse<CloudflareVideo>> {
    return this.client.get(`/live_inputs/${liveInputId}/videos`)
  }
}

// 创建默认实例（需要在使用前配置）
let streamApiInstance: CloudflareStreamApi | null = null

/**
 * 初始化 Cloudflare Stream API
 */
export function initCloudflareStream(config: CloudflareStreamConfig): CloudflareStreamApi {
  streamApiInstance = new CloudflareStreamApi(config)
  return streamApiInstance
}

/**
 * 获取 Cloudflare Stream API 实例
 */
export function useCloudflareStream(): CloudflareStreamApi {
  if (!streamApiInstance) {
    throw new Error('Cloudflare Stream API not initialized. Call initCloudflareStream first.')
  }
  return streamApiInstance
}

export { CloudflareStreamApi }
export default CloudflareStreamApi
