// Image Generation API service import { BASE_URL } from '@/lib/config/api' export interface ImageGenerationRequest { style: 'cartoon' | 'realistic' | 'minimal' priority: 'normal' | 'high' | 'low' width: number height: number replicateModel: string options: { useGeminiCache: boolean useImageCache: boolean maxRetries: number learnerLevel: string scenario: string visualPreferences: string[] } } export interface GenerationStatus { requestId: string overallStatus: string currentStage?: string stages: { gemini: { status: string startedAt?: string completedAt?: string processingTimeMs?: number cost?: number generatedDescription?: string } replicate: { status: string startedAt?: string completedAt?: string processingTimeMs?: number cost?: number model?: string modelVersion?: string progress?: string } } totalCost?: number completedAt?: string result?: { imageUrl: string imageId: string qualityScore?: number dimensions?: { width: number height: number } fileSize?: number } } export interface ApiResponse { success: boolean data?: T error?: string details?: string } class ImageGenerationService { private baseUrl = BASE_URL private async makeRequest(url: string, options: RequestInit = {}): Promise> { const token = localStorage.getItem('auth_token') const response = await fetch(`${this.baseUrl}${url}`, { headers: { 'Content-Type': 'application/json', 'Authorization': token ? `Bearer ${token}` : '', ...options.headers, }, ...options, }) if (!response.ok) { const errorData = await response.json().catch(() => ({ error: 'Network error' })) throw new Error(errorData.error || errorData.details || `HTTP ${response.status}`) } return response.json() } // 啟動圖片生成 async generateImage(flashcardId: string, request?: Partial): Promise> { const defaultRequest: ImageGenerationRequest = { style: 'cartoon', priority: 'normal', width: 512, height: 512, replicateModel: 'ideogram-v2a-turbo', options: { useGeminiCache: true, useImageCache: true, maxRetries: 3, learnerLevel: 'B1', scenario: 'daily', visualPreferences: ['colorful', 'simple'] }, ...request } return this.makeRequest(`/api/ImageGeneration/flashcards/${flashcardId}/generate`, { method: 'POST', body: JSON.stringify(defaultRequest) }) } // 查詢生成狀態 async getGenerationStatus(requestId: string): Promise> { return this.makeRequest(`/api/ImageGeneration/requests/${requestId}/status`) } // 取消生成 async cancelGeneration(requestId: string): Promise> { return this.makeRequest(`/api/ImageGeneration/requests/${requestId}/cancel`, { method: 'POST' }) } // 輪詢直到完成 async pollUntilComplete( requestId: string, onProgress?: (status: GenerationStatus) => void, timeoutMinutes = 5 ): Promise { const startTime = Date.now() const timeout = timeoutMinutes * 60 * 1000 while (Date.now() - startTime < timeout) { try { const result = await this.getGenerationStatus(requestId) if (!result.success || !result.data) { throw new Error(result.error || 'Failed to get status') } const status = result.data // 呼叫進度回調 if (onProgress) { onProgress(status) } // 檢查是否完成 if (status.overallStatus === 'completed') { return status } // 檢查是否失敗 if (status.overallStatus === 'failed') { throw new Error('圖片生成失敗') } // 等待 2 秒後再次檢查 await new Promise(resolve => setTimeout(resolve, 2000)) } catch (error) { console.error('輪詢狀態時發生錯誤:', error) throw error } } throw new Error('圖片生成超時') } } export const imageGenerationService = new ImageGenerationService()