import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals';
import request from 'supertest';
import app from '../index';
import db from '../config/database';
import AuthService from '../services/AuthService';
import ProductService from '../services/ProductService';
import OrderService from '../services/OrderService';

describe('Integration Test Cases', () => {
  // 模拟认证服务
  let authService: AuthService;
  let authToken: string;

  beforeEach(async () => {
    authService = new AuthService();
    
    // 生成测试令牌
    authToken = 'test-token';
    
    // 模拟数据库连接
    jest.spyOn(db, 'raw').mockResolvedValue({ rows: [] });
  });

  // API集成测试
  describe('API Integration Tests', () => {
    it('should authenticate user and return token', async () => {
      const response = await request(app)
        .post('/api/auth/login')
        .send({
          username: 'testuser',
          password: 'password123'
        });

      expect(response.status).toBe(200);
      expect(response.body.success).toBe(true);
      expect(response.body.token).toBeDefined();
    });

    it('should get user profile with valid token', async () => {
      const response = await request(app)
        .get('/api/users/profile')
        .set('Authorization', `Bearer ${authToken}`);

      expect(response.status).toBe(200);
      expect(response.body.user).toBeDefined();
    });

    it('should create product via API', async () => {
      const productData = {
        title: 'Integration Test Product',
        description: 'Test Product for Integration',
        price: 199.99,
        cost_price: 100.00,
        stock: 50,
        sku: 'INT-001',
        category: 'Electronics',
        brand: 'Test Brand',
        platform: 'Amazon',
        product_id: 'AMZ-INT-001'
      };

      const response = await request(app)
        .post('/api/products')
        .set('Authorization', `Bearer ${authToken}`)
        .send(productData);

      expect(response.status).toBe(200);
      expect(response.body.success).toBe(true);
      expect(response.body.productId).toBeDefined();
    });

    it('should get product list', async () => {
      const response = await request(app)
        .get('/api/products')
        .set('Authorization', `Bearer ${authToken}`)
        .query({ limit: 10, offset: 0 });

      expect(response.status).toBe(200);
      expect(Array.isArray(response.body.products)).toBe(true);
    });

    it('should create order via API', async () => {
      const orderData = {
        platform: 'Amazon',
        platform_order_id: 'AMZ-ORDER-INT-001',
        customer_name: 'Integration Test Customer',
        customer_email: 'customer@example.com',
        shipping_address: '123 Test St',
        subtotal: 199.99,
        shipping_fee: 10.00,
        total: 209.99,
        items: [
          {
            product_id: '1',
            quantity: 1,
            unit_price: 199.99
          }
        ]
      };

      const response = await request(app)
        .post('/api/orders')
        .set('Authorization', `Bearer ${authToken}`)
        .send(orderData);

      expect(response.status).toBe(200);
      expect(response.body.success).toBe(true);
      expect(response.body.orderId).toBeDefined();
    });

    it('should get order list', async () => {
      const response = await request(app)
        .get('/api/orders')
        .set('Authorization', `Bearer ${authToken}`)
        .query({ status: 'PENDING', limit: 10 });

      expect(response.status).toBe(200);
      expect(Array.isArray(response.body.orders)).toBe(true);
    });

    it('should create advertisement via API', async () => {
      const adData = {
        name: 'Integration Test Ad',
        campaign_id: '1',
        ad_group_id: '1',
        product_id: '1',
        platform: 'Google',
        budget: 200.00,
        bid: 1.50,
        ad_type: 'SEARCH'
      };

      const response = await request(app)
        .post('/api/ads')
        .set('Authorization', `Bearer ${authToken}`)
        .send(adData);

      expect(response.status).toBe(200);
      expect(response.body.success).toBe(true);
      expect(response.body.adId).toBeDefined();
    });

    it('should get advertisement metrics', async () => {
      const response = await request(app)
        .get('/api/ads/metrics')
        .set('Authorization', `Bearer ${authToken}`)
        .query({ adId: '1', startDate: '2026-01-01', endDate: '2026-03-18' });

      expect(response.status).toBe(200);
      expect(response.body.metrics).toBeDefined();
    });
  });

  // 业务流程集成测试
  describe('Business Process Integration Tests', () => {
    it('should complete order fulfillment process', async () => {
      // 1. 创建订单
      const orderService = new OrderService();
      const orderData = {
        tenant_id: '1',
        shop_id: '1',
        platform: 'Amazon',
        platform_order_id: 'AMZ-ORDER-PROCESS-001',
        customer_name: 'Test Customer',
        subtotal: 99.99,
        shipping_fee: 5.00,
        total: 104.99,
        items: [
          {
            product_id: '1',
            quantity: 1,
            unit_price: 99.99
          }
        ]
      };

      const orderResult = await orderService.createOrder(orderData);
      expect(orderResult.success).toBe(true);
      expect(orderResult.orderId).toBeDefined();

      // 2. 更新订单状态为已付款
      const updateResult = await orderService.updateOrderStatus(orderResult.orderId!, 'PAID');
      expect(updateResult.success).toBe(true);

      // 3. 更新订单状态为已发货
      const shipResult = await orderService.updateOrderStatus(orderResult.orderId!, 'SHIPPED');
      expect(shipResult.success).toBe(true);

      // 4. 更新订单状态为已完成
      const completeResult = await orderService.updateOrderStatus(orderResult.orderId!, 'COMPLETED');
      expect(completeResult.success).toBe(true);
    });

    it('should handle product lifecycle', async () => {
      const productService = new ProductService();
      
      // 1. 创建商品
      const productData = {
        title: 'Lifecycle Test Product',
        price: 149.99,
        cost_price: 75.00,
        stock: 100,
        sku: 'LIFE-001',
        category: 'Electronics',
        brand: 'Test Brand',
        tenant_id: '1',
        shop_id: '1',
        platform: 'Amazon',
        product_id: 'AMZ-LIFE-001'
      };

      const createResult = await productService.createProduct(productData);
      expect(createResult.success).toBe(true);
      expect(createResult.productId).toBeDefined();

      // 2. 获取商品信息
      const product = await productService.getProductById(createResult.productId!);
      expect(product).toBeDefined();
      expect(product.id).toBe(createResult.productId);

      // 3. 更新商品库存
      const stockResult = await productService.updateStock(createResult.productId!, 80);
      expect(stockResult.success).toBe(true);

      // 4. 更新商品价格
      const updateResult = await productService.updateProduct(createResult.productId!, { price: 129.99 });
      expect(updateResult.success).toBe(true);
    });

    it('should process payment and update order', async () => {
      // 模拟支付流程
      const processPayment = async (orderId: string, amount: number) => {
        // 模拟支付处理
        await new Promise(resolve => setTimeout(resolve, 100));
        return { success: true, transactionId: 'TXN-001' };
      };

      const orderId = '1';
      const amount = 100.00;

      const paymentResult = await processPayment(orderId, amount);
      expect(paymentResult.success).toBe(true);
      expect(paymentResult.transactionId).toBe('TXN-001');

      // 更新订单状态
      const orderService = new OrderService();
      const updateResult = await orderService.updateOrderStatus(orderId, 'PAID');
      expect(updateResult.success).toBe(true);
    });
  });

  // 数据库集成测试
  describe('Database Integration Tests', () => {
    it('should perform database transactions', async () => {
      // 模拟数据库事务
      const transactionResult = await db.transaction(async (trx) => {
        // 创建用户
        const [userId] = await trx('cf_user').insert({
          id: 'test-user-1',
          username: 'testuser',
          email: 'test@example.com',
          password_hash: 'hash',
          tenant_id: '1'
        });

        // 创建商品
        const [productId] = await trx('cf_product').insert({
          id: 'test-product-1',
          title: 'Test Product',
          price: 99.99,
          tenant_id: '1',
          shop_id: '1'
        });

        return { userId, productId };
      });

      expect(transactionResult.userId).toBeDefined();
      expect(transactionResult.productId).toBeDefined();
    });

    it('should query database with joins', async () => {
      // 模拟联合查询
      const queryResult = await db('cf_order')
        .join('cf_order_item', 'cf_order.id', '=', 'cf_order_item.order_id')
        .join('cf_product', 'cf_order_item.product_id', '=', 'cf_product.id')
        .select(
          'cf_order.id as order_id',
          'cf_order.total',
          'cf_product.title as product_title',
          'cf_order_item.quantity'
        )
        .where('cf_order.tenant_id', '=', '1');

      expect(Array.isArray(queryResult)).toBe(true);
    });

    it('should handle database migrations', async () => {
      // 模拟数据库迁移检查
      const hasTable = await db.schema.hasTable('cf_user');
      expect(hasTable).toBe(true);

      const hasProductTable = await db.schema.hasTable('cf_product');
      expect(hasProductTable).toBe(true);

      const hasOrderTable = await db.schema.hasTable('cf_order');
      expect(hasOrderTable).toBe(true);
    });
  });

  // 服务间集成测试
  describe('Service Integration Tests', () => {
    it('should integrate AuthService with UserService', async () => {
      // 模拟用户认证和信息获取
      const authResult = await authService.authenticate('testuser', 'password123');
      expect(authResult.success).toBe(true);
      expect(authResult.token).toBeDefined();

      // 模拟用户信息获取
      const userService = new UserService();
      const user = await userService.getUserById('1');
      expect(user).toBeDefined();
      expect(user.username).toBe('testuser');
    });

    it('should integrate ProductService with OrderService', async () => {
      const productService = new ProductService();
      const orderService = new OrderService();

      // 创建商品
      const productResult = await productService.createProduct({
        title: 'Integration Product',
        price: 50.00,
        cost_price: 25.00,
        stock: 100,
        sku: 'INT-PROD-001',
        tenant_id: '1',
        shop_id: '1',
        platform: 'Amazon',
        product_id: 'AMZ-INT-001'
      });

      expect(productResult.success).toBe(true);

      // 创建包含该商品的订单
      const orderResult = await orderService.createOrder({
        tenant_id: '1',
        shop_id: '1',
        platform: 'Amazon',
        platform_order_id: 'AMZ-ORDER-SVC-001',
        customer_name: 'Service Test Customer',
        subtotal: 50.00,
        shipping_fee: 5.00,
        total: 55.00,
        items: [
          {
            product_id: productResult.productId!,
            quantity: 1,
            unit_price: 50.00
          }
        ]
      });

      expect(orderResult.success).toBe(true);
    });
  });

  // 清理测试
  afterEach(() => {
    jest.clearAllMocks();
  });
});

// 性能集成测试
describe('Performance Integration Tests', () => {
  it('should handle concurrent API requests', async () => {
    const requestCount = 5;
    const requests = [];

    for (let i = 0; i < requestCount; i++) {
      requests.push(
        request(app)
          .get('/api/products')
          .set('Authorization', `Bearer ${authToken}`)
          .query({ limit: 5 })
      );
    }

    const responses = await Promise.all(requests);
    expect(responses.length).toBe(requestCount);
    responses.forEach(response => {
      expect(response.status).toBe(200);
    });
  });

  it('should handle database performance', async () => {
    const startTime = Date.now();
    
    // 模拟数据库查询
    const result = await db('cf_product')
      .where('tenant_id', '=', '1')
      .limit(100);
    
    const endTime = Date.now();
    const duration = endTime - startTime;
    
    expect(duration).toBeLessThan(1000); // 期望查询在1秒内完成
  });

  it('should handle large payloads', async () => {
    const largeProductData = {
      title: 'Large Product Data Test',
      description: ''.repeat(1000), // 1000字符描述
      price: 999.99,
      attributes: {
        specs: ''.repeat(500),
        features: ''.repeat(500)
      },
      images: Array(10).fill({ url: 'https://example.com/image.jpg' })
    };

    const response = await request(app)
      .post('/api/products')
      .set('Authorization', `Bearer ${authToken}`)
      .send(largeProductData);

    expect(response.status).toBe(200);
    expect(response.body.success).toBe(true);
  });
});

// 错误处理集成测试
describe('Error Handling Integration Tests', () => {
  it('should handle invalid API requests', async () => {
    const response = await request(app)
      .post('/api/auth/login')
      .send({}); // 空请求体

    expect(response.status).toBe(400);
    expect(response.body.success).toBe(false);
    expect(response.body.error).toBeDefined();
  });

  it('should handle unauthorized access', async () => {
    const response = await request(app)
      .get('/api/users/profile'); // 无授权头

    expect(response.status).toBe(401);
    expect(response.body.success).toBe(false);
    expect(response.body.error).toBe('Unauthorized');
  });

  it('should handle resource not found', async () => {
    const response = await request(app)
      .get('/api/products/999999')
      .set('Authorization', `Bearer ${authToken}`);

    expect(response.status).toBe(404);
    expect(response.body.success).toBe(false);
    expect(response.body.error).toBe('Product not found');
  });

  it('should handle database errors', async () => {
    // 模拟数据库错误
    jest.spyOn(db, 'select').mockRejectedValue(new Error('Database error'));

    const response = await request(app)
      .get('/api/products')
      .set('Authorization', `Bearer ${authToken}`);

    expect(response.status).toBe(500);
    expect(response.body.success).toBe(false);
    expect(response.body.error).toBe('Internal server error');
  });
});
