/**
 * 通用APP深度链接工具类
 * 支持媒体服务器（Plex、Jellyfin、Emby）和豆瓣的APP跳转和网页跳转
 *
 * 深度链接格式参考：
 * - Plex: https://forums.plex.tv/t/plex-mobile-app-deep-linking/123456
 * - Emby: https://emby.media/support/articles/Deep-Linking.html
 * - Jellyfin: https://jellyfin.org/docs/general/administration/deep-linking
 * - 豆瓣: 官方搜索格式
 */

import { isMobileDevice, isIOSDevice, isAndroidDevice } from '@/@core/utils'

// APP类型
export type AppType = 'plex' | 'jellyfin' | 'emby' | 'trimemedia' | 'douban'

// 深度链接配置
interface DeepLinkConfig {
  appScheme: string
  webUrl: string
  timeout: number
}

// 各APP的深度链接配置
const DEEP_LINK_CONFIGS: Record<AppType, DeepLinkConfig> = {
  plex: {
    appScheme: 'plex://',
    webUrl: 'https://app.plex.tv',
    timeout: 2000,
  },
  jellyfin: {
    appScheme: 'jellyfin://',
    webUrl: 'https://jellyfin.org',
    timeout: 2000,
  },
  emby: {
    appScheme: 'emby://',
    webUrl: 'https://emby.media',
    timeout: 2000,
  },
  trimemedia: {
    appScheme: 'trimemedia://',
    webUrl: 'https://trimemedia.com',
    timeout: 2000,
  },
  douban: {
    appScheme: 'douban://',
    webUrl: 'https://movie.douban.com',
    timeout: 2000,
  },
}

// 豆瓣APP跳转参数
interface DoubanAppParams {
  doubanId: string
  mediaType?: string
  title?: string
  year?: string
  fallbackUrl?: string
}

/**
 * 尝试跳转到APP，如果失败则跳转到网页
 * @param appType APP类型
 * @param params 跳转参数
 */
export async function openApp(appType: AppType, params: string | DoubanAppParams, fallbackUrl?: string): Promise<void> {
  // 如果不是移动设备，直接使用网页链接
  if (!isMobileDevice()) {
    const webUrl = getWebUrl(appType, params, fallbackUrl)
    window.open(webUrl, '_blank')
    return
  }

  const config = DEEP_LINK_CONFIGS[appType]
  if (!config) {
    console.warn(`不支持的APP类型: ${appType}`)
    const webUrl = getWebUrl(appType, params, fallbackUrl)
    window.open(webUrl, '_blank')
    return
  }

  // 构建APP深度链接
  const appUrl = buildDeepLinkUrl(appType, params)

  console.log(`构建${appType}深度链接:`, {
    params,
    deepLinkUrl: appUrl,
  })

  // 尝试跳转到APP
  try {
    await attemptAppLaunch(appUrl, config.timeout)
  } catch (error) {
    console.log(`${appType} APP跳转失败，使用网页链接: ${error}`)
    // APP跳转失败，使用网页链接
    const webUrl = getWebUrl(appType, params, fallbackUrl)
    window.open(webUrl, '_blank')
  }
}

/**
 * 获取网页链接
 * @param appType APP类型
 * @param params 参数
 * @param fallbackUrl 备用链接
 */
function getWebUrl(appType: AppType, params: string | DoubanAppParams, fallbackUrl?: string): string {
  if (fallbackUrl) return fallbackUrl

  const config = DEEP_LINK_CONFIGS[appType]

  switch (appType) {
    case 'douban':
      const doubanParams = params as DoubanAppParams
      return `${config.webUrl}/subject/${doubanParams.doubanId}`
    default:
      return typeof params === 'string' ? params : config.webUrl
  }
}

/**
 * 构建深度链接URL
 * @param appType APP类型
 * @param params 参数
 */
function buildDeepLinkUrl(appType: AppType, params: string | DoubanAppParams): string {
  switch (appType) {
    case 'plex':
      return buildPlexDeepLink(params as string)

    case 'jellyfin':
      return buildJellyfinDeepLink(params as string)

    case 'emby':
      return buildEmbyDeepLink(params as string)

    case 'trimemedia':
      return buildTrimemediaDeepLink(params as string)

    case 'douban':
      return buildDoubanDeepLink(params as DoubanAppParams)

    default:
      return typeof params === 'string' ? params : ''
  }
}

/**
 * 构建Plex深度链接
 * 参考: https://forums.plex.tv/t/plex-mobile-app-deep-linking/123456
 *
 * 后台API返回格式：
 * - 媒体库: web/index.html#!/media/{machineIdentifier}/com.plexapp.plugins.library?source={library.key}&X-Plex-Token={token}
 * - 媒体项: web/index.html#!/server/{machineIdentifier}/details?key={item_id}&X-Plex-Token={token}
 *
 * Plex官方APP URL格式：
 * plex://play/?metadataKey=/library/metadata/$SOME_ID&server=$SERVER_ID
 * 例如: plex://play/?metadataKey=/library/metadata/123&server=456
 *
 * @param playUrl 播放链接
 */
function buildPlexDeepLink(playUrl: string): string {
  try {
    const url = new URL(playUrl)

    // 提取媒体ID、机器标识符、库ID等
    let mediaId: string | null = null
    let machineIdentifier: string | null = null
    let libraryKey: string | null = null
    let librarySectionId: string | null = null
    let plexToken: string | null = null

    // 提取X-Plex-Token
    const tokenMatch = playUrl.match(/X-Plex-Token=([^&]+)/)
    if (tokenMatch) {
      plexToken = tokenMatch[1]
      console.log('提取Plex Token:', { plexToken })
    }

    // 格式1: 后台API返回的媒体库格式
    // web/index.html#!/media/{machineIdentifier}/com.plexapp.plugins.library?source={library.key}&X-Plex-Token={token}
    const mediaLibraryMatch = playUrl.match(/\/media\/([^\/]+)\/com\.plexapp\.plugins\.library\?source=([^&]+)/)
    if (mediaLibraryMatch) {
      machineIdentifier = mediaLibraryMatch[1]
      libraryKey = mediaLibraryMatch[2]
      console.log('Plex后台API媒体库格式匹配:', { machineIdentifier, libraryKey })

      // 从library.key中提取section ID
      // library.key格式通常是: library://video-section/1 或类似格式
      const sectionMatch = libraryKey.match(/section\/(\d+)/)
      if (sectionMatch) {
        librarySectionId = sectionMatch[1]
        console.log('从library.key提取section ID:', { librarySectionId })
      }
    }

    // 格式2: 后台API返回的媒体项格式
    // web/index.html#!/server/{machineIdentifier}/details?key={item_id}&X-Plex-Token={token}
    const serverDetailsMatch = playUrl.match(/\/server\/([^\/]+)\/details\?key=([^&]+)/)
    if (serverDetailsMatch) {
      machineIdentifier = serverDetailsMatch[1]
      const keyValue = serverDetailsMatch[2]
      console.log('Plex后台API媒体项格式匹配:', { machineIdentifier, keyValue })

      // 从key中提取媒体ID
      // key格式可能是: /library/metadata/1668 或直接是 1668
      const metadataMatch = keyValue.match(/\/library\/metadata\/(\d+)/)
      if (metadataMatch) {
        mediaId = metadataMatch[1]
        console.log('从key提取媒体ID:', { mediaId })
      } else if (/^\d+$/.test(keyValue)) {
        // 如果key本身就是数字，直接使用
        mediaId = keyValue
        console.log('key本身就是媒体ID:', { mediaId })
      }
    }

    // 构建深度链接 - 使用新的官方格式
    if (mediaId && machineIdentifier) {
      // plex://play/?metadataKey=/library/metadata/$SOME_ID&server=$SERVER_ID
      let deepLink = `plex://play/?metadataKey=/library/metadata/${mediaId}&server=${machineIdentifier}`
      if (plexToken) {
        deepLink += `&X-Plex-Token=${plexToken}`
      }
      console.log('Plex深度链接构建成功:', {
        originalUrl: playUrl,
        machineIdentifier,
        libraryKey,
        librarySectionId,
        mediaId,
        plexToken,
        deepLink,
      })
      return deepLink
    }

    // 如果有媒体ID但没有机器标识符，尝试使用旧的格式作为降级
    if (mediaId) {
      let deepLink = `plex://library/metadata/${mediaId}`
      if (plexToken) {
        deepLink += `?X-Plex-Token=${plexToken}`
      }
      console.log('Plex深度链接构建成功(降级格式):', {
        originalUrl: playUrl,
        mediaId,
        plexToken,
        deepLink,
      })
      return deepLink
    }

    // 如果有库ID，尝试使用库ID
    if (librarySectionId) {
      // http://[PMS_IP_Address]:32400/library/sections/29/all?X-Plex-Token=YourTokenGoesHere
      let libraryLink = `plex://library/sections/${librarySectionId}/all`
      if (plexToken) {
        libraryLink += `?X-Plex-Token=${plexToken}`
      }
      console.log('Plex库深度链接构建成功:', {
        originalUrl: playUrl,
        librarySectionId,
        plexToken,
        libraryLink,
      })
      return libraryLink
    }

    // 如果无法提取媒体ID，尝试使用机器标识符
    if (machineIdentifier) {
      // http://[PMS_IP_Address]:32400/library/sections?X-Plex-Token=YourTokenGoesHere
      let fallbackLink = `plex://library/sections`
      if (plexToken) {
        fallbackLink += `?X-Plex-Token=${plexToken}`
      }
      console.log('Plex深度链接构建失败，使用机器标识符:', {
        originalUrl: playUrl,
        machineIdentifier,
        plexToken,
        fallbackLink,
      })
      return fallbackLink
    }

    // 最后的降级方案
    console.log('Plex深度链接构建失败，使用原始URL:', {
      originalUrl: playUrl,
    })
    return `plex://${playUrl}`
  } catch (error) {
    console.warn('构建Plex深度链接失败:', error)
    return `plex://${playUrl}`
  }
}

/**
 * 构建Jellyfin深度链接
 * 参考: https://jellyfin.org/docs/general/administration/deep-linking
 * @param playUrl 播放链接
 */
function buildJellyfinDeepLink(playUrl: string): string {
  try {
    const url = new URL(playUrl)
    const serverAddress = url.hostname + (url.port ? `:${url.port}` : '')

    // 提取媒体ID、库ID、serverId
    let mediaId: string | null = null
    let libraryId: string | null = null
    let serverId: string | null = null

    // 格式1: /details?id={item_id}&serverId={serverid}
    const detailsMatch = playUrl.match(/\/details\?id=([^&]+)&serverId=([^&]+)/)
    if (detailsMatch) {
      mediaId = detailsMatch[1]
      serverId = detailsMatch[2]
    }

    // 格式2: /movies.html?topParentId={libraryId}
    const moviesMatch = playUrl.match(/\/movies\.html\?topParentId=([^&]+)/)
    if (moviesMatch) {
      libraryId = moviesMatch[1]
    }
    // 格式3: /tv.html?topParentId={libraryId}
    const tvMatch = playUrl.match(/\/tv\.html\?topParentId=([^&]+)/)
    if (tvMatch) {
      libraryId = tvMatch[1]
    }
    // 格式4: /library.html?topParentId={libraryId}
    const libMatch = playUrl.match(/\/library\.html\?topParentId=([^&]+)/)
    if (libMatch) {
      libraryId = libMatch[1]
    }

    // 兼容原有格式：?id=xxx
    if (!mediaId) {
      const idMatch = playUrl.match(/[?&]id=([^&]+)/)
      if (idMatch) {
        mediaId = idMatch[1]
      }
    }

    // 兼容原有格式：/items/xxx
    if (!mediaId) {
      const itemsMatch = playUrl.match(/\/items\/([^\/\?]+)/)
      if (itemsMatch) {
        mediaId = itemsMatch[1]
      }
    }

    // 构建深度链接
    if (mediaId) {
      let deepLink = `jellyfin://${serverAddress}/item/${mediaId}`
      if (serverId) {
        deepLink += `?serverId=${serverId}`
      }
      console.log('Jellyfin深度链接构建成功:', {
        originalUrl: playUrl,
        serverAddress,
        mediaId,
        serverId,
        deepLink,
      })
      return deepLink
    }
    if (libraryId) {
      const deepLink = `jellyfin://${serverAddress}/library/${libraryId}`
      console.log('Jellyfin库深度链接构建成功:', {
        originalUrl: playUrl,
        serverAddress,
        libraryId,
        deepLink,
      })
      return deepLink
    }

    // 如果无法提取ID，尝试直接使用服务器地址
    const fallbackLink = `jellyfin://${serverAddress}`
    console.log('Jellyfin深度链接构建失败，使用服务器地址:', {
      originalUrl: playUrl,
      serverAddress,
      fallbackLink,
    })
    return fallbackLink
  } catch (error) {
    console.warn('构建Jellyfin深度链接失败:', error)
    return `jellyfin://${playUrl}`
  }
}

/**
 * 构建Emby深度链接
 * 参考: https://emby.media/support/articles/Deep-Linking.html
 * iOS格式: emby://items?serverId={SERVER_ID}&itemId={ITEM_ID}
 * Android格式: emby://{服务器地址}/item/{媒体ID}
 * @param playUrl 播放链接
 */
function buildEmbyDeepLink(playUrl: string): string {
  try {
    const url = new URL(playUrl)
    const serverAddress = url.hostname + (url.port ? `:${url.port}` : '')

    // 尝试多种格式提取媒体ID
    let mediaId: string | null = null
    let serverId: string | null = null

    // 格式1: /web/index.html#!/item?id=xxx&context=home&serverId=xxx (后台返回的格式)
    const itemHashMatch = playUrl.match(/\/item\?id=([^&]+)/)
    if (itemHashMatch) {
      mediaId = itemHashMatch[1]
      // 提取serverId
      const serverIdMatch = playUrl.match(/serverId=([^&]+)/)
      if (serverIdMatch) {
        serverId = serverIdMatch[1]
      }
    }

    // 格式2: /web/index.html#!/videos?serverId=xxx&parentId=xxx (后台返回的格式)
    const videosHashMatch = playUrl.match(/\/videos\?serverId=([^&]+)&parentId=([^&]+)/)
    if (videosHashMatch) {
      // 对于videos格式，我们使用parentId作为媒体ID
      mediaId = videosHashMatch[2]
      serverId = videosHashMatch[1]
    }

    // 格式3: ?id=xxx (通用格式)
    if (!mediaId) {
      const idMatch = playUrl.match(/[?&]id=([^&]+)/)
      if (idMatch) {
        mediaId = idMatch[1]
      }
    }

    // 格式4: /itemdetails.html?id=xxx
    if (!mediaId) {
      const itemMatch = playUrl.match(/\/itemdetails\.html\?id=([^&]+)/)
      if (itemMatch) {
        mediaId = itemMatch[1]
      }
    }

    // 格式5: /items/xxx
    if (!mediaId) {
      const itemsMatch = playUrl.match(/\/items\/([^\/\?]+)/)
      if (itemsMatch) {
        mediaId = itemsMatch[1]
      }
    }

    // 格式6: /item/xxx (路径格式)
    if (!mediaId) {
      const itemPathMatch = playUrl.match(/\/item\/([^\/\?]+)/)
      if (itemPathMatch) {
        mediaId = itemPathMatch[1]
      }
    }

    if (mediaId) {
      let deepLink: string

      // 根据设备类型使用不同的深度链接格式
      if (isIOSDevice()) {
        // iOS格式: emby://items?serverId={SERVER_ID}&itemId={ITEM_ID}
        if (serverId) {
          deepLink = `emby://items?serverId=${serverId}&itemId=${mediaId}`
        } else {
          // 如果没有serverId，尝试使用服务器地址作为serverId
          deepLink = `emby://items?serverId=${serverAddress}&itemId=${mediaId}`
        }
      } else {
        // Android格式: emby://{服务器地址}/item/{媒体ID}
        deepLink = `emby://${serverAddress}/item/${mediaId}`
        if (serverId) {
          deepLink += `?serverId=${serverId}`
        }
      }

      console.log('Emby深度链接构建成功:', {
        originalUrl: playUrl,
        serverAddress,
        mediaId,
        serverId,
        deviceType: isIOSDevice() ? 'iOS' : 'Android',
        deepLink,
      })
      return deepLink
    }

    // 如果无法提取媒体ID，尝试直接使用服务器地址
    // 这会打开Emby APP的主界面
    const fallbackLink = `emby://${serverAddress}`
    console.log('Emby深度链接构建失败，使用服务器地址:', {
      originalUrl: playUrl,
      serverAddress,
      fallbackLink,
    })
    return fallbackLink
  } catch (error) {
    console.warn('构建Emby深度链接失败:', error)
    return playUrl
  }
}

/**
 * 构建Trimemedia深度链接
 * @param playUrl 播放链接
 */
function buildTrimemediaDeepLink(playUrl: string): string {
  try {
    const url = new URL(playUrl)
    const serverAddress = url.hostname + (url.port ? `:${url.port}` : '')

    // 提取媒体ID
    let mediaId: string | null = null

    // 尝试从URL路径中提取媒体ID
    const pathMatch = playUrl.match(/\/item\/([^\/\?]+)/)
    if (pathMatch) {
      mediaId = pathMatch[1]
    }

    // 尝试从查询参数中提取媒体ID
    if (!mediaId) {
      const idMatch = playUrl.match(/[?&]id=([^&]+)/)
      if (idMatch) {
        mediaId = idMatch[1]
      }
    }

    // 构建深度链接
    if (mediaId) {
      const deepLink = `trimemedia://${serverAddress}/item/${mediaId}`
      console.log('Trimemedia深度链接构建成功:', {
        originalUrl: playUrl,
        serverAddress,
        mediaId,
        deepLink,
      })
      return deepLink
    }

    // 如果无法提取媒体ID，尝试直接使用服务器地址
    const fallbackLink = `trimemedia://${serverAddress}`
    console.log('Trimemedia深度链接构建失败，使用服务器地址:', {
      originalUrl: playUrl,
      serverAddress,
      fallbackLink,
    })
    return fallbackLink
  } catch (error) {
    console.warn('构建Trimemedia深度链接失败:', error)
    return playUrl
  }
}

/**
 * 构建豆瓣深度链接
 * 使用豆瓣App官方支持的搜索格式
 * @param params 豆瓣参数
 */
function buildDoubanDeepLink(params: DoubanAppParams): string {
  const { title, year } = params

  // 使用豆瓣App官方支持的搜索格式
  // 格式：douban:///search?q={query}
  const searchQuery = `${title || ''} ${year || ''}`.trim()
  const deepLink = `douban:///search?q=${encodeURIComponent(searchQuery)}`

  console.log('豆瓣深度链接构建成功:', {
    params,
    searchQuery,
    deepLink,
  })

  return deepLink
}

/**
 * 尝试启动APP
 * @param appUrl APP深度链接
 * @param timeout 超时时间
 */
async function attemptAppLaunch(appUrl: string, timeout: number): Promise<void> {
  return new Promise((resolve, reject) => {
    // 创建一个隐藏的iframe来尝试启动APP
    const iframe = document.createElement('iframe')
    iframe.style.display = 'none'
    iframe.src = appUrl

    // 设置超时
    const timeoutId = setTimeout(() => {
      document.body.removeChild(iframe)
      reject(new Error('APP启动超时'))
    }, timeout)

    // 监听页面可见性变化，如果用户切换到APP，说明启动成功
    const handleVisibilityChange = () => {
      if (document.hidden) {
        clearTimeout(timeoutId)
        document.removeEventListener('visibilitychange', handleVisibilityChange)
        document.body.removeChild(iframe)
        resolve()
      }
    }

    document.addEventListener('visibilitychange', handleVisibilityChange)

    // 添加到页面并尝试启动
    document.body.appendChild(iframe)

    // 对于iOS，还需要尝试window.location
    if (isIOSDevice()) {
      try {
        window.location.href = appUrl
      } catch (error) {
        console.log('iOS window.location跳转失败:', error)
      }
    }
  })
}

/**
 * 根据播放链接自动检测媒体服务器类型并跳转
 * @param playUrl 播放链接
 * @param fallbackUrl 备用网页链接
 * @param serverType 媒体服务器类型（可选，优先使用此参数）
 */
export async function openMediaServerWithAutoDetect(
  playUrl: string,
  fallbackUrl?: string,
  serverType?: string,
): Promise<void> {
  let detectedServerType: AppType | null = null

  // 优先使用传入的 serverType 参数
  if (serverType) {
    const type = serverType.toLowerCase()
    if (type === 'plex' || type === 'jellyfin' || type === 'emby' || type === 'trimemedia') {
      detectedServerType = type as AppType
    }
  }

  // 如果没有传入 serverType 或类型不支持，则从URL中检测
  if (!detectedServerType) {
    const url = playUrl.toLowerCase()

    if (url.includes('plex') || url.includes('plex.tv')) {
      detectedServerType = 'plex'
    } else if (url.includes('jellyfin')) {
      detectedServerType = 'jellyfin'
    } else if (url.includes('emby')) {
      detectedServerType = 'emby'
    }
  }

  if (detectedServerType) {
    await openApp(detectedServerType, playUrl, fallbackUrl)
  } else {
    // 无法检测到服务器类型，直接使用网页链接
    window.open(fallbackUrl || playUrl, '_blank')
  }
}

/**
 * 打开豆瓣APP
 * @param doubanId 豆瓣ID
 * @param mediaType 媒体类型（电影/电视剧）
 * @param title 媒体标题
 * @param year 媒体年份
 * @param fallbackUrl 备用网页链接
 */
export async function openDoubanApp(
  doubanId: string,
  mediaType?: string,
  title?: string,
  year?: string,
  fallbackUrl?: string,
): Promise<void> {
  const params: DoubanAppParams = {
    doubanId,
    mediaType,
    title,
    year,
    fallbackUrl,
  }

  await openApp('douban', params, fallbackUrl)
}

/**
 * 获取APP的下载链接
 * @param appType APP类型
 */
export function getAppDownloadUrl(appType: AppType): string {
  switch (appType) {
    case 'plex':
      return 'https://www.plex.tv/apps/'
    case 'jellyfin':
      return 'https://jellyfin.org/downloads/'
    case 'emby':
      return 'https://emby.media/download.html'
    case 'trimemedia':
      return 'https://trimemedia.com/download'
    case 'douban':
      return 'https://www.douban.com/doubanapp/'
    default:
      return ''
  }
}

/**
 * 检查是否安装了特定的APP
 * 注意：由于浏览器安全限制，无法直接检测APP是否安装
 * 这个方法主要用于提示用户
 */
export function checkAppInstalled(appType: AppType): boolean {
  // 由于浏览器安全限制，无法直接检测APP是否安装
  // 这里可以根据用户代理或其他信息进行推测
  // 目前返回false，让系统总是尝试跳转
  return false
}
