/**
 * 穿搭生成功能测试
 * 测试新实现的重试机制、多商品生成和并发执行功能
 */

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { OutfitImageService } from '../services/outfitImageService';
import type { OutfitImageGenerationRequest } from '../types/outfitImage';

// Mock Tauri invoke
vi.mock('@tauri-apps/api/core', () => ({
  invoke: vi.fn()
}));

describe('OutfitImageService', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('重试机制', () => {
    it('应该能够重试失败的生成任务', async () => {
      const { invoke } = await import('@tauri-apps/api/core');
      const mockInvoke = vi.mocked(invoke);
      
      mockInvoke.mockResolvedValueOnce(undefined);

      await OutfitImageService.retryOutfitImageGeneration('test-record-id');

      expect(mockInvoke).toHaveBeenCalledWith('retry_outfit_image_generation', {
        recordId: 'test-record-id'
      });
    });

    it('重试失败时应该抛出错误', async () => {
      const { invoke } = await import('@tauri-apps/api/core');
      const mockInvoke = vi.mocked(invoke);
      
      mockInvoke.mockRejectedValueOnce(new Error('重试失败'));

      await expect(
        OutfitImageService.retryOutfitImageGeneration('test-record-id')
      ).rejects.toThrow('重试穿搭图片生成任务失败');
    });
  });

  describe('批量生成', () => {
    it('应该能够批量创建多个生成任务', async () => {
      const { invoke } = await import('@tauri-apps/api/core');
      const mockInvoke = vi.mocked(invoke);
      
      // Mock 创建任务的返回值
      mockInvoke
        .mockResolvedValueOnce('record-1')
        .mockResolvedValueOnce('record-2')
        .mockResolvedValueOnce('record-3');

      const requests: OutfitImageGenerationRequest[] = [
        {
          model_id: 'model-1',
          model_image_id: 'image-1',
          product_image_paths: ['product-1.jpg']
        },
        {
          model_id: 'model-1',
          model_image_id: 'image-1',
          product_image_paths: ['product-2.jpg']
        },
        {
          model_id: 'model-1',
          model_image_id: 'image-1',
          product_image_paths: ['product-3.jpg']
        }
      ];

      const recordIds = await OutfitImageService.createBatchOutfitImageTasks(requests);

      expect(recordIds).toEqual(['record-1', 'record-2', 'record-3']);
      expect(mockInvoke).toHaveBeenCalledTimes(3);
    });

    it('应该能够批量执行多个生成任务', async () => {
      const { invoke } = await import('@tauri-apps/api/core');
      const mockInvoke = vi.mocked(invoke);
      
      mockInvoke.mockResolvedValue(undefined);

      const recordIds = ['record-1', 'record-2', 'record-3'];
      await OutfitImageService.executeBatchOutfitImageTasks(recordIds);

      expect(mockInvoke).toHaveBeenCalledTimes(3);
      expect(mockInvoke).toHaveBeenCalledWith('execute_outfit_image_task', {
        recordId: 'record-1'
      });
      expect(mockInvoke).toHaveBeenCalledWith('execute_outfit_image_task', {
        recordId: 'record-2'
      });
      expect(mockInvoke).toHaveBeenCalledWith('execute_outfit_image_task', {
        recordId: 'record-3'
      });
    });

    it('应该能够一键批量生成穿搭图片', async () => {
      const { invoke } = await import('@tauri-apps/api/core');
      const mockInvoke = vi.mocked(invoke);
      
      // Mock 创建和执行任务
      mockInvoke
        .mockResolvedValueOnce('record-1')
        .mockResolvedValueOnce('record-2')
        .mockResolvedValueOnce(undefined)
        .mockResolvedValueOnce(undefined);

      const requests: OutfitImageGenerationRequest[] = [
        {
          model_id: 'model-1',
          model_image_id: 'image-1',
          product_image_paths: ['product-1.jpg']
        },
        {
          model_id: 'model-1',
          model_image_id: 'image-1',
          product_image_paths: ['product-2.jpg']
        }
      ];

      const recordIds = await OutfitImageService.batchGenerateOutfitImages(requests);

      expect(recordIds).toEqual(['record-1', 'record-2']);
      expect(mockInvoke).toHaveBeenCalledTimes(4); // 2次创建 + 2次执行
    });
  });

  describe('并发执行', () => {
    it('批量任务应该并发执行而不是串行', async () => {
      const { invoke } = await import('@tauri-apps/api/core');
      const mockInvoke = vi.mocked(invoke);
      
      let callOrder: number[] = [];
      let callCount = 0;

      mockInvoke.mockImplementation(async () => {
        const currentCall = ++callCount;
        callOrder.push(currentCall);
        // 模拟异步延迟
        await new Promise(resolve => setTimeout(resolve, 10));
        return `record-${currentCall}`;
      });

      const requests: OutfitImageGenerationRequest[] = [
        { model_id: 'model-1', model_image_id: 'image-1', product_image_paths: ['product-1.jpg'] },
        { model_id: 'model-1', model_image_id: 'image-1', product_image_paths: ['product-2.jpg'] },
        { model_id: 'model-1', model_image_id: 'image-1', product_image_paths: ['product-3.jpg'] }
      ];

      const startTime = Date.now();
      await OutfitImageService.createBatchOutfitImageTasks(requests);
      const endTime = Date.now();

      // 并发执行应该比串行执行快
      // 如果是串行执行，3个任务每个10ms延迟应该需要至少30ms
      // 如果是并发执行，应该接近10ms
      expect(endTime - startTime).toBeLessThan(25);
      expect(callOrder).toEqual([1, 2, 3]);
    });
  });
});
