/**
 * Text Video Agent API 测试文件
 */

import { textVideoAgentAPI, TextVideoAgentAPI } from '../src/services/textVideoAgentAPI'
import { TaskType, AspectRatio, VideoDuration } from '../src/services/textVideoAgentTypes'

// Mock fetch for testing
global.fetch = jest.fn()

describe('TextVideoAgentAPI', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  describe('基础功能测试', () => {
    test('健康检查', async () => {
      const mockResponse = {
        status: true,
        msg: 'Service is healthy'
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.healthCheck()
      
      expect(fetch).toHaveBeenCalledWith(
        expect.stringContaining('/health'),
        expect.any(Object)
      )
      expect(result).toEqual(mockResponse)
    })

    test('获取示例提示词', async () => {
      const mockResponse = {
        status: true,
        msg: 'Success',
        data: {
          prompts: ['示例提示词1', '示例提示词2']
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.getSamplePrompt(TaskType.VLOG)
      
      expect(fetch).toHaveBeenCalledWith(
        expect.stringContaining('/api/prompt/default?task_type=vlog'),
        expect.any(Object)
      )
      expect(result).toEqual(mockResponse)
    })
  })

  describe('图片生成测试', () => {
    test('同步生成图片', async () => {
      const mockResponse = {
        status: true,
        msg: 'Image generated successfully',
        data: {
          image_url: 'https://example.com/generated-image.jpg'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.generateImageSync({
        prompt: '测试图片生成',
        max_wait_time: 60
      })

      expect(result).toEqual(mockResponse)
      expect(result.data?.image_url).toBe('https://example.com/generated-image.jpg')
    })

    test('异步生成图片', async () => {
      const mockResponse = {
        status: true,
        msg: 'Task submitted',
        data: {
          task_id: 'test-task-123'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.generateImageAsync('测试异步图片生成')
      
      expect(result).toEqual(mockResponse)
      expect(result.data?.task_id).toBe('test-task-123')
    })

    test('带重试的图片生成', async () => {
      // 第一次失败
      ;(fetch as jest.Mock).mockRejectedValueOnce(new Error('Network error'))
      
      // 第二次成功
      const mockResponse = {
        status: true,
        msg: 'Image generated successfully',
        data: {
          image_url: 'https://example.com/generated-image.jpg'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.generateImageWithRetry({
        prompt: '测试重试机制',
        max_wait_time: 60
      }, 2)

      expect(fetch).toHaveBeenCalledTimes(2)
      expect(result).toEqual(mockResponse)
    })
  })

  describe('视频生成测试', () => {
    test('同步生成视频', async () => {
      const mockResponse = {
        status: true,
        msg: 'Video generated successfully',
        data: {
          video_url: 'https://example.com/generated-video.mp4'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.generateVideoSync({
        prompt: '测试视频生成',
        img_url: 'https://example.com/base-image.jpg',
        duration: '5'
      })

      expect(result).toEqual(mockResponse)
      expect(result.data?.video_url).toBe('https://example.com/generated-video.mp4')
    })

    test('异步生成视频', async () => {
      const mockResponse = {
        status: true,
        msg: 'Video task submitted',
        data: {
          task_id: 'video-task-456'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.generateVideoAsync({
        prompt: '测试异步视频生成',
        duration: '5'
      })

      expect(result).toEqual(mockResponse)
      expect(result.data?.task_id).toBe('video-task-456')
    })
  })

  describe('任务管理测试', () => {
    test('创建任务', async () => {
      const mockResponse = {
        status: true,
        msg: 'Task created successfully',
        data: {
          task_id: 'new-task-789'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.createTask({
        task_type: TaskType.VLOG,
        prompt: '测试任务创建',
        ar: AspectRatio.PORTRAIT
      })

      expect(result).toEqual(mockResponse)
      expect(result.data?.task_id).toBe('new-task-789')
    })

    test('查询任务状态', async () => {
      const mockResponse = {
        status: true,
        msg: 'Task status retrieved',
        data: {
          task_id: 'test-task-123',
          status: 'completed',
          progress: 100,
          result: {
            image_url: 'https://example.com/result.jpg'
          }
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.getTaskStatusAsync('test-task-123')

      expect(result).toEqual(mockResponse)
      expect(result.data?.status).toBe('completed')
    })
  })

  describe('文件操作测试', () => {
    test('文件上传', async () => {
      const mockResponse = {
        status: true,
        msg: 'File uploaded successfully',
        data: 'https://example.com/uploaded-file.jpg'
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' })
      const result = await textVideoAgentAPI.uploadFile(mockFile)

      expect(result).toEqual(mockResponse)
      expect(result.data).toBe('https://example.com/uploaded-file.jpg')
    })
  })

  describe('图片描述测试', () => {
    test('通过URL描述图片', async () => {
      const mockResponse = {
        status: true,
        msg: 'Image described successfully',
        data: {
          description: '这是一张美丽的风景照片'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const result = await textVideoAgentAPI.describeImageByUrl({
        image_url: 'https://example.com/image.jpg'
      })

      expect(result).toEqual(mockResponse)
      expect(result.data?.description).toBe('这是一张美丽的风景照片')
    })

    test('通过文件描述图片', async () => {
      const mockResponse = {
        status: true,
        msg: 'Image described successfully',
        data: {
          description: '这是一张人物照片'
        }
      }

      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => mockResponse
      })

      const mockFile = new File(['image content'], 'portrait.jpg', { type: 'image/jpeg' })
      const result = await textVideoAgentAPI.describeImageByFile({
        img_file: mockFile
      })

      expect(result).toEqual(mockResponse)
      expect(result.data?.description).toBe('这是一张人物照片')
    })
  })

  describe('高级功能测试', () => {
    test('端到端内容生成', async () => {
      // Mock 创建任务
      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          status: true,
          data: { task_id: 'end-to-end-task' }
        })
      })

      // Mock 图片生成
      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          status: true,
          data: { image_url: 'https://example.com/generated.jpg' }
        })
      })

      // Mock 视频生成
      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          status: true,
          data: { video_url: 'https://example.com/generated.mp4' }
        })
      })

      const result = await textVideoAgentAPI.generateContentEndToEnd(
        '测试端到端生成',
        {
          taskType: TaskType.VLOG,
          aspectRatio: AspectRatio.PORTRAIT,
          videoDuration: VideoDuration.MEDIUM,
          generateVideo: true
        }
      )

      expect(result).toEqual({
        imageUrl: 'https://example.com/generated.jpg',
        videoUrl: 'https://example.com/generated.mp4',
        taskId: 'end-to-end-task'
      })
    })

    test('轮询任务直到完成', async () => {
      // 第一次查询 - 进行中
      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          status: true,
          data: { status: 'running', progress: 50 }
        })
      })

      // 第二次查询 - 完成
      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          status: true,
          data: { 
            status: 'completed', 
            progress: 100,
            result: { image_url: 'https://example.com/final.jpg' }
          }
        })
      })

      const progressCallback = jest.fn()
      
      const result = await textVideoAgentAPI.pollTaskUntilComplete(
        'test-task-id',
        100, // 快速轮询用于测试
        5000, // 5秒超时
        progressCallback
      )

      expect(fetch).toHaveBeenCalledTimes(2)
      expect(progressCallback).toHaveBeenCalledTimes(2)
      expect(result.data?.status).toBe('completed')
    })
  })

  describe('错误处理测试', () => {
    test('网络错误处理', async () => {
      ;(fetch as jest.Mock).mockRejectedValueOnce(new Error('Network error'))

      await expect(textVideoAgentAPI.healthCheck()).rejects.toThrow('Network error')
    })

    test('HTTP错误处理', async () => {
      ;(fetch as jest.Mock).mockResolvedValueOnce({
        ok: false,
        status: 500,
        json: async () => ({ error: 'Internal server error' })
      })

      await expect(textVideoAgentAPI.healthCheck()).rejects.toThrow('HTTP error! status: 500')
    })

    test('参数验证', async () => {
      await expect(
        textVideoAgentAPI.describeImageByUrl({} as any)
      ).rejects.toThrow('image_url is required')

      await expect(
        textVideoAgentAPI.describeImageByFile({} as any)
      ).rejects.toThrow('img_file is required')
    })
  })

  describe('自定义配置测试', () => {
    test('自定义API端点', () => {
      const customAPI = new TextVideoAgentAPI('https://custom-endpoint.com')
      expect(customAPI).toBeInstanceOf(TextVideoAgentAPI)
    })
  })
})

// 集成测试（需要真实API）
describe('集成测试 (需要真实API)', () => {
  // 这些测试需要真实的API端点，通常在CI/CD环境中跳过
  const shouldRunIntegrationTests = process.env.RUN_INTEGRATION_TESTS === 'true'

  test.skipIf(!shouldRunIntegrationTests)('真实健康检查', async () => {
    const result = await textVideoAgentAPI.healthCheck()
    expect(result.status).toBe(true)
  })

  test.skipIf(!shouldRunIntegrationTests)('真实图片生成', async () => {
    const result = await textVideoAgentAPI.generateImageSync({
      prompt: '一朵美丽的花',
      max_wait_time: 60
    })
    
    expect(result.status).toBe(true)
    expect(result.data?.image_url).toBeDefined()
  }, 120000) // 2分钟超时
})

export {}
