import type { AccountInput, AccountStatus, CheckedAccount, CheckResult } from '../types'
import type { ChatGPTCheckResponse } from './types'

/**
 * ChatGPT API 检查端点
 * 通过 nginx 代理访问，避免 CORS 问题
 * 原始 API: https://chatgpt.com/backend-api/accounts/check/v4-2023-04-27
 */
const CHATGPT_CHECK_API = '/api/chatgpt/accounts/check/v4-2023-04-27'

/**
 * HTTP 状态码到账号状态的映射
 * 根据 requirements.md A3 定义:
 * - HTTP 200 → active (账号正常)
 * - HTTP 401 → token_expired (Token 已过期)
 * - HTTP 403 → banned (账号被封禁)
 * - 其他 → error (网络错误等)
 */
function mapHttpStatusToAccountStatus(httpStatus: number): AccountStatus {
  switch (httpStatus) {
    case 200:
      return 'active'
    case 401:
      return 'token_expired'
    case 403:
      return 'banned'
    default:
      return 'error'
  }
}

/**
 * 获取 HTTP 状态码对应的错误消息
 */
function getErrorMessageForStatus(httpStatus: number, statusText: string): string | undefined {
  switch (httpStatus) {
    case 200:
      return undefined
    case 401:
      return 'Token 已过期'
    case 403:
      return '账号已被封禁'
    default:
      return `HTTP ${httpStatus}: ${statusText}`
  }
}

/**
 * ChatGPT API 客户端
 * 用于检查 ChatGPT 账号状态
 */
export class ChatGPTClient {
  private baseUrl: string

  constructor(baseUrl: string = '') {
    this.baseUrl = baseUrl
  }

  /**
   * 检查单个账号状态
   * @param token - ChatGPT access_token
   * @returns CheckResult 包含状态、account_id、plan_type 等信息
   *
   * API: GET https://chatgpt.com/backend-api/accounts/check/v4-2023-04-27
   * Headers: Authorization: Bearer {token}
   *
   * 状态映射 (requirements.md A3):
   * - HTTP 200 → active
   * - HTTP 401 → token_expired
   * - HTTP 403 → banned
   * - 其他 → error
   */
  async checkAccount(token: string): Promise<CheckResult> {
    // 处理空 token 的情况
    if (!token || token.trim() === '') {
      return {
        status: 'error',
        error: '缺少 token',
      }
    }

    try {
      const response = await fetch(`${this.baseUrl}${CHATGPT_CHECK_API}`, {
        method: 'GET',
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      })

      const status = mapHttpStatusToAccountStatus(response.status)
      const errorMessage = getErrorMessageForStatus(response.status, response.statusText)

      if (response.status === 200) {
        try {
          const data: ChatGPTCheckResponse = await response.json()
          const accountInfo = data.accounts?.[0]

          if (accountInfo) {
            return {
              status: 'active',
              accountId: accountInfo.account_id,
              planType: accountInfo.entitlement?.subscription_plan || 'free',
            }
          }

          // 200 响应但没有账号信息
          return {
            status: 'active',
            accountId: undefined,
            planType: 'unknown',
          }
        } catch {
          // JSON 解析失败，但 HTTP 200 仍视为 active
          return {
            status: 'active',
            accountId: undefined,
            planType: 'unknown',
          }
        }
      }

      return {
        status,
        error: errorMessage,
      }
    } catch (error) {
      return {
        status: 'error',
        error: error instanceof Error ? error.message : '网络错误',
      }
    }
  }

  /**
   * 批量检查账号（带并发控制）
   * @param accounts - 待检查的账号列表
   * @param options.concurrency - 并发数量（默认 20）
   * @param options.onProgress - 进度回调，每检查完一个账号调用一次
   * @returns 检查完成的账号列表
   *
   * 使用队列 + Promise 实现并发控制，确保任意时刻活跃请求数 ≤ concurrency
   */
  async batchCheck(
    accounts: AccountInput[],
    options: {
      concurrency: number
      onProgress?: (result: CheckedAccount, index: number) => void
    }
  ): Promise<CheckedAccount[]> {
    const { concurrency, onProgress } = options

    // 空数组直接返回
    if (accounts.length === 0) {
      return []
    }

    const results: CheckedAccount[] = new Array(accounts.length)
    const queue: number[] = [...Array(accounts.length).keys()]
    let activeCount = 0
    let completedCount = 0

    return new Promise((resolve) => {
      const processNext = () => {
        // 所有任务完成
        if (completedCount === accounts.length) {
          resolve(results)
          return
        }

        // 启动新任务，直到达到并发限制或队列为空
        while (activeCount < concurrency && queue.length > 0) {
          const index = queue.shift()!
          activeCount++

          // 异步处理单个账号
          this.processAccount(accounts[index], index)
            .then((checkedAccount) => {
              results[index] = checkedAccount
              onProgress?.(checkedAccount, index)
            })
            .finally(() => {
              activeCount--
              completedCount++
              // 继续处理下一个
              processNext()
            })
        }
      }

      // 开始处理
      processNext()
    })
  }

  /**
   * 处理单个账号检查
   * @private
   */
  private async processAccount(account: AccountInput, index: number): Promise<CheckedAccount> {
    const checkResult = await this.checkAccount(account.token)

    return {
      ...account,
      id: index,
      status: checkResult.status,
      accountId: checkResult.accountId,
      planType: checkResult.planType,
      error: checkResult.error,
    }
  }
}

/**
 * 解析账号状态为中文描述
 */
export function getStatusText(status: AccountStatus): string {
  const statusMap: Record<AccountStatus, string> = {
    pending: '待检查',
    checking: '检查中',
    active: '正常',
    banned: '封禁',
    token_expired: '过期',
    error: '错误',
  }
  return statusMap[status] || status
}

/**
 * 获取状态对应的颜色类名
 */
export function getStatusColor(status: AccountStatus): string {
  const colorMap: Record<AccountStatus, string> = {
    pending: 'gray',
    checking: 'blue',
    active: 'green',
    banned: 'red',
    token_expired: 'orange',
    error: 'yellow',
  }
  return colorMap[status] || 'gray'
}

/**
 * 创建 ChatGPT 客户端实例
 * @param baseUrl - 可选的基础 URL，默认为空（使用相对路径）
 */
export function createChatGPTClient(baseUrl: string = ''): ChatGPTClient {
  return new ChatGPTClient(baseUrl)
}

// 导出默认客户端实例（使用相对路径，通过 nginx 代理）
export const chatGPTClient = new ChatGPTClient()
