import { vi } from 'vitest';

/**
 * 创建HTTP服务mock
 */
export function createHttpServiceMock() {
  return {
    get: vi.fn().mockResolvedValue({ data: {}, status: 200 }),
    post: vi.fn().mockResolvedValue({ data: {}, status: 201 }),
    put: vi.fn().mockResolvedValue({ data: {}, status: 200 }),
    delete: vi.fn().mockResolvedValue({ data: {}, status: 204 }),
    patch: vi.fn().mockResolvedValue({ data: {}, status: 200 }),
  };
}

/**
 * 创建认证服务mock
 */
export function createAuthServiceMock() {
  return {
    verifyToken: vi.fn().mockResolvedValue({ userId: 1, username: 'testuser' }),
    generateToken: vi.fn().mockReturnValue('mock-jwt-token'),
    refreshToken: vi.fn().mockResolvedValue({ accessToken: 'new-token', refreshToken: 'new-refresh-token' }),
    invalidateToken: vi.fn().mockResolvedValue(undefined),
  };
}

/**
 * 创建邮件服务mock
 */
export function createEmailServiceMock() {
  return {
    sendWelcomeEmail: vi.fn().mockResolvedValue({ success: true }),
    sendPasswordResetEmail: vi.fn().mockResolvedValue({ success: true }),
    sendNotification: vi.fn().mockResolvedValue({ success: true }),
  };
}

/**
 * 创建文件存储服务mock
 */
export function createStorageServiceMock() {
  return {
    uploadFile: vi.fn().mockResolvedValue({ url: 'https://example.com/file.jpg', key: 'file-key' }),
    deleteFile: vi.fn().mockResolvedValue({ success: true }),
    getFileUrl: vi.fn().mockReturnValue('https://example.com/file.jpg'),
    listFiles: vi.fn().mockResolvedValue([]),
  };
}

/**
 * 创建支付服务mock
 */
export function createPaymentServiceMock() {
  return {
    createPaymentIntent: vi.fn().mockResolvedValue({ clientSecret: 'pi_mock_secret', id: 'pi_mock_id' }),
    confirmPayment: vi.fn().mockResolvedValue({ success: true, transactionId: 'txn_mock_id' }),
    refundPayment: vi.fn().mockResolvedValue({ success: true, refundId: 'ref_mock_id' }),
  };
}

/**
 * 创建短信服务mock
 */
export function createSmsServiceMock() {
  return {
    sendVerificationCode: vi.fn().mockResolvedValue({ success: true, messageId: 'sms_mock_id' }),
    sendNotification: vi.fn().mockResolvedValue({ success: true, messageId: 'sms_mock_id' }),
  };
}

/**
 * 创建第三方API服务mock
 */
export function createThirdPartyApiMock() {
  return {
    call: vi.fn().mockResolvedValue({ success: true, data: {} }),
    validate: vi.fn().mockResolvedValue({ valid: true, errors: [] }),
    webhook: vi.fn().mockResolvedValue({ received: true }),
  };
}

/**
 * 模拟网络延迟
 */
export function mockNetworkDelay(delayMs: number) {
  return new Promise(resolve => setTimeout(resolve, delayMs));
}

/**
 * 模拟HTTP错误响应
 */
export function mockHttpError(status: number, message: string) {
  return {
    response: {
      status,
      data: { error: message }
    }
  };
}

/**
 * 模拟超时错误
 */
export function mockTimeoutError() {
  return new Error('Request timeout');
}

/**
 * 模拟网络断开错误
 */
export function mockNetworkError() {
  return new Error('Network error');
}

/**
 * 服务mock工具类
 */
export class ServiceMocks {
  static http = createHttpServiceMock();
  static auth = createAuthServiceMock();
  static email = createEmailServiceMock();
  static storage = createStorageServiceMock();
  static payment = createPaymentServiceMock();
  static sms = createSmsServiceMock();
  static thirdParty = createThirdPartyApiMock();

  /**
   * 重置所有mock
   */
  static resetAll() {
    Object.values(this).forEach(service => {
      if (service && typeof service === 'object') {
        Object.values(service).forEach(mock => {
          if (mock && typeof mock === 'function' && 'mockClear' in mock) {
            (mock as any).mockClear();
          }
        });
      }
    });
  }

  /**
   * 设置所有mock为成功状态
   */
  static setupForSuccess() {
    this.resetAll();
    // 所有mock默认已经是成功状态
  }

  /**
   * 设置所有mock为失败状态
   */
  static setupForFailure() {
    this.resetAll();
    Object.values(this.http).forEach(mock => mock.mockRejectedValue(mockNetworkError()));
    Object.values(this.auth).forEach(mock => mock.mockRejectedValue(new Error('Auth failed')));
    Object.values(this.email).forEach(mock => mock.mockRejectedValue(new Error('Email failed')));
    Object.values(this.storage).forEach(mock => mock.mockRejectedValue(new Error('Storage failed')));
    Object.values(this.payment).forEach(mock => mock.mockRejectedValue(new Error('Payment failed')));
    Object.values(this.sms).forEach(mock => mock.mockRejectedValue(new Error('SMS failed')));
    Object.values(this.thirdParty).forEach(mock => mock.mockRejectedValue(new Error('Third party failed')));
  }
}