interface ReplicateModel {
  url: string
  owner: string
  name: string
  description?: string
  visibility: string
  github_url?: string
  paper_url?: string
  license_url?: string
  run_count: number
  cover_image_url?: string
  default_example?: Record<string, unknown>
  latest_version?: {
    id: string
    created_at: string
    cog_version: string
    openapi_schema: {
      components: {
        schemas: {
          Input: Record<string, unknown>
          Output: Record<string, unknown>
        }
      }
    }
  }
}

interface ReplicateResponse {
  next?: string
  previous?: string
  results: ReplicateModel[]
}

export class ReplicateService {
  private apiToken: string
  private baseUrl = 'https://api.replicate.com/v1'

  constructor() {
    this.apiToken = process.env.REPLICATE_API_TOKEN || ''
    if (!this.apiToken) {
      throw new Error('REPLICATE_API_TOKEN environment variable is required')
    }
  }

  async getAvailableModels(): Promise<ReplicateModel[]> {
    try {
      const response = await fetch(`${this.baseUrl}/models`, {
        headers: {
          'Authorization': `Token ${this.apiToken}`,
          'Content-Type': 'application/json',
        },
      })

      if (!response.ok) {
        throw new Error(`Replicate API error: ${response.status} ${response.statusText}`)
      }

      const data: ReplicateResponse = await response.json()
      return data.results || []
    } catch (error) {
      console.error('Error fetching Replicate models:', error)
      throw error
    }
  }

  // 搜索特定类型的模型（图片、视频、音频生成）
  async searchModelsByType(query: string): Promise<ReplicateModel[]> {
    try {
      const response = await fetch(`${this.baseUrl}/models`, {
        method: 'QUERY',
        headers: {
          'Authorization': `Token ${this.apiToken}`,
          'Content-Type': 'text/plain',
        },
        body: query,
      })

      if (!response.ok) {
        throw new Error(`Replicate API error: ${response.status} ${response.statusText}`)
      }

      const data: ReplicateResponse = await response.json()
      return data.results || []
    } catch (error) {
      console.error('Error searching Replicate models:', error)
      throw error
    }
  }

  // 获取图片生成模型
  async getImageGenerationModels(): Promise<ReplicateModel[]> {
    const queries = ['image generation', 'stable diffusion', 'flux', 'midjourney']
    const allModels: ReplicateModel[] = []
    
    for (const query of queries) {
      try {
        const models = await this.searchModelsByType(query)
        allModels.push(...models)
      } catch (error) {
        console.warn(`Failed to search for ${query}:`, error)
      }
    }
    
    // 去重并过滤图片生成模型
    const uniqueModels = this.deduplicateModels(allModels)
    return this.filterImageModels(uniqueModels)
  }

  // 获取视频生成模型
  async getVideoGenerationModels(): Promise<ReplicateModel[]> {
    const queries = ['video generation', 'video', 'runway', 'pika']
    const allModels: ReplicateModel[] = []
    
    for (const query of queries) {
      try {
        const models = await this.searchModelsByType(query)
        allModels.push(...models)
      } catch (error) {
        console.warn(`Failed to search for ${query}:`, error)
      }
    }
    
    const uniqueModels = this.deduplicateModels(allModels)
    return this.filterVideoModels(uniqueModels)
  }

  // 获取音频生成模型
  async getAudioGenerationModels(): Promise<ReplicateModel[]> {
    const queries = ['audio generation', 'music generation', 'sound', 'musicgen']
    const allModels: ReplicateModel[] = []
    
    for (const query of queries) {
      try {
        const models = await this.searchModelsByType(query)
        allModels.push(...models)
      } catch (error) {
        console.warn(`Failed to search for ${query}:`, error)
      }
    }
    
    const uniqueModels = this.deduplicateModels(allModels)
    return this.filterAudioModels(uniqueModels)
  }

  // 将 Replicate 模型转换为我们数据库的格式
  transformModelForDB(model: ReplicateModel, outputType: 'image' | 'video' | 'audio') {
    return {
      modelId: `${model.owner}/${model.name}`,
      name: model.name,
      provider: model.owner,
      serviceProvider: 'replicate',
      outputType,
      description: model.description || null,
      maxTokens: null, // Replicate 模型通常不使用 token 限制
      inputCostPer1k: null, // 需要从其他地方获取价格信息
      outputCostPer1k: null,
      supportedFeatures: {
        visibility: model.visibility,
        run_count: model.run_count,
        github_url: model.github_url,
        paper_url: model.paper_url,
        license_url: model.license_url,
      },
      metadata: {
        url: model.url,
        cover_image_url: model.cover_image_url,
        default_example: model.default_example,
        latest_version: model.latest_version,
      },
    }
  }

  private deduplicateModels(models: ReplicateModel[]): ReplicateModel[] {
    const seen = new Set<string>()
    return models.filter(model => {
      const key = `${model.owner}/${model.name}`
      if (seen.has(key)) {
        return false
      }
      seen.add(key)
      return true
    })
  }

  private filterImageModels(models: ReplicateModel[]): ReplicateModel[] {
    return models.filter(model => {
      const name = model.name.toLowerCase()
      const description = (model.description || '').toLowerCase()
      
      return (
        name.includes('image') ||
        name.includes('diffusion') ||
        name.includes('flux') ||
        name.includes('sdxl') ||
        name.includes('dalle') ||
        description.includes('image') ||
        description.includes('generate') ||
        description.includes('diffusion')
      )
    })
  }

  private filterVideoModels(models: ReplicateModel[]): ReplicateModel[] {
    return models.filter(model => {
      const name = model.name.toLowerCase()
      const description = (model.description || '').toLowerCase()
      
      return (
        name.includes('video') ||
        name.includes('runway') ||
        name.includes('pika') ||
        name.includes('animate') ||
        description.includes('video') ||
        description.includes('animate') ||
        description.includes('motion')
      )
    })
  }

  private filterAudioModels(models: ReplicateModel[]): ReplicateModel[] {
    return models.filter(model => {
      const name = model.name.toLowerCase()
      const description = (model.description || '').toLowerCase()
      
      return (
        name.includes('audio') ||
        name.includes('music') ||
        name.includes('sound') ||
        name.includes('musicgen') ||
        name.includes('bark') ||
        description.includes('audio') ||
        description.includes('music') ||
        description.includes('sound') ||
        description.includes('speech')
      )
    })
  }

  private extractProvider(modelId: string): string {
    return modelId.split('/')[0] || 'Unknown'
  }
}
