/**
 * 分类管理API测试
 * TDD: 先写测试，再实现功能
 */

const request = require('supertest');
const express = require('express');

// 模拟Express应用
const app = express();
app.use(express.json());

// 测试数据
const testCategories = [
  { name: '测试一级分类1', parent_id: null, level: 1 },
  { name: '测试一级分类2', parent_id: null, level: 1 },
];

describe('分类管理API测试', () => {
  
  // 测试1: 获取分类树
  describe('GET /api/categories/tree', () => {
    test('应该返回分类树结构', async () => {
      const response = await request(app)
        .get('/api/categories/tree')
        .expect(200);
      
      expect(response.body.success).toBe(true);
      expect(Array.isArray(response.body.data)).toBe(true);
      // 每个一级分类应该有children属性
      if (response.body.data.length > 0) {
        expect(response.body.data[0]).toHaveProperty('children');
      }
    });
    
    test('应该支持按层级筛选', async () => {
      const response = await request(app)
        .get('/api/categories/tree?level=1')
        .expect(200);
      
      expect(response.body.success).toBe(true);
      // 返回的都是一级分类
      response.body.data.forEach(cat => {
        expect(cat.level).toBe(1);
      });
    });
  });
  
  // 测试2: 创建分类
  describe('POST /api/categories', () => {
    test('应该能创建一级分类', async () => {
      const newCategory = {
        name: '新材料分类',
        parent_id: null,
        level: 1,
        description: '测试描述'
      };
      
      const response = await request(app)
        .post('/api/categories')
        .send(newCategory)
        .expect(200);
      
      expect(response.body.success).toBe(true);
      expect(response.body.data).toHaveProperty('id');
      expect(response.body.data.name).toBe(newCategory.name);
    });
    
    test('应该能在指定父分类下创建二级分类', async () => {
      // 先创建父分类
      const parentResponse = await request(app)
        .post('/api/categories')
        .send({ name: '父分类', parent_id: null, level: 1 });
      
      const parentId = parentResponse.body.data.id;
      
      // 创建子分类
      const childCategory = {
        name: '子分类',
        parent_id: parentId,
        level: 2
      };
      
      const response = await request(app)
        .post('/api/categories')
        .send(childCategory)
        .expect(200);
      
      expect(response.body.success).toBe(true);
      expect(response.body.data.parent_id).toBe(parentId);
      expect(response.body.data.level).toBe(2);
    });
    
    test('分类名称不能为空', async () => {
      const response = await request(app)
        .post('/api/categories')
        .send({ name: '', parent_id: null, level: 1 })
        .expect(400);
      
      expect(response.body.success).toBe(false);
      expect(response.body.message).toContain('名称');
    });
    
    test('同一父分类下不能有重名子分类', async () => {
      // 创建父分类
      const parent = await request(app)
        .post('/api/categories')
        .send({ name: '唯一父分类', parent_id: null, level: 1 });
      
      // 创建第一个子分类
      await request(app)
        .post('/api/categories')
        .send({ name: '同名子分类', parent_id: parent.body.data.id, level: 2 });
      
      // 尝试创建同名子分类
      const response = await request(app)
        .post('/api/categories')
        .send({ name: '同名子分类', parent_id: parent.body.data.id, level: 2 })
        .expect(400);
      
      expect(response.body.success).toBe(false);
    });
  });
  
  // 测试3: 更新分类
  describe('PUT /api/categories/:id', () => {
    test('应该能更新分类名称', async () => {
      // 先创建分类
      const createResponse = await request(app)
        .post('/api/categories')
        .send({ name: '原名称', parent_id: null, level: 1 });
      
      const categoryId = createResponse.body.data.id;
      
      // 更新分类
      const response = await request(app)
        .put(`/api/categories/${categoryId}`)
        .send({ name: '新名称' })
        .expect(200);
      
      expect(response.body.success).toBe(true);
      
      // 验证更新
      const getResponse = await request(app)
        .get(`/api/categories/${categoryId}`)
        .expect(200);
      
      expect(getResponse.body.data.name).toBe('新名称');
    });
    
    test('不能将分类设置为自己的子分类', async () => {
      // 创建父分类
      const parent = await request(app)
        .post('/api/categories')
        .send({ name: '父', parent_id: null, level: 1 });
      
      // 创建子分类
      const child = await request(app)
        .post('/api/categories')
        .send({ name: '子', parent_id: parent.body.data.id, level: 2 });
      
      // 尝试将父分类的parent_id设为子分类（循环引用）
      const response = await request(app)
        .put(`/api/categories/${parent.body.data.id}`)
        .send({ parent_id: child.body.data.id })
        .expect(400);
      
      expect(response.body.success).toBe(false);
    });
  });
  
  // 测试4: 删除分类
  describe('DELETE /api/categories/:id', () => {
    test('应该能删除空分类', async () => {
      // 创建分类
      const createResponse = await request(app)
        .post('/api/categories')
        .send({ name: '待删除', parent_id: null, level: 1 });
      
      const categoryId = createResponse.body.data.id;
      
      // 删除分类
      const response = await request(app)
        .delete(`/api/categories/${categoryId}`)
        .expect(200);
      
      expect(response.body.success).toBe(true);
      
      // 验证已删除
      const getResponse = await request(app)
        .get(`/api/categories/${categoryId}`)
        .expect(404);
    });
    
    test('删除一级分类应该级联删除二级分类', async () => {
      // 创建父分类
      const parent = await request(app)
        .post('/api/categories')
        .send({ name: '父', parent_id: null, level: 1 });
      
      // 创建子分类
      const child = await request(app)
        .post('/api/categories')
        .send({ name: '子', parent_id: parent.body.data.id, level: 2 });
      
      // 删除父分类
      await request(app)
        .delete(`/api/categories/${parent.body.data.id}`)
        .expect(200);
      
      // 验证子分类也被删除
      await request(app)
        .get(`/api/categories/${child.body.data.id}`)
        .expect(404);
    });
    
    test('有商品的分类不应该被删除', async () => {
      // 创建分类
      const category = await request(app)
        .post('/api/categories')
        .send({ name: '有商品的分类', parent_id: null, level: 1 });
      
      // 在该分类下创建商品（模拟）
      // ... 创建商品逻辑
      
      // 尝试删除分类
      const response = await request(app)
        .delete(`/api/categories/${category.body.data.id}`)
        .expect(400);
      
      expect(response.body.success).toBe(false);
      expect(response.body.message).toContain('商品');
    });
  });
  
  // 测试5: 批量导入时自动创建分类
  describe('批量导入分类处理', () => {
    test('导入时应该自动创建不存在的一级分类', async () => {
      const importData = {
        products: [
          {
            name: '测试商品',
            category_level1: '新一级分类',
            category_level2: '新二级分类'
          }
        ]
      };
      
      const response = await request(app)
        .post('/api/products/batch-import')
        .send(importData)
        .expect(200);
      
      expect(response.body.success).toBe(true);
      
      // 验证分类已创建
      const categories = await request(app)
        .get('/api/categories/tree')
        .expect(200);
      
      const level1Exists = categories.body.data.some(
        cat => cat.name === '新一级分类'
      );
      expect(level1Exists).toBe(true);
    });
    
    test('导入时应该自动创建不存在的二级分类', async () => {
      // 先创建一级分类
      await request(app)
        .post('/api/categories')
        .send({ name: '已有的一级', parent_id: null, level: 1 });
      
      // 导入带有新二级分类的商品
      const importData = {
        products: [
          {
            name: '测试商品2',
            category_level1: '已有的一级',
            category_level2: '新的二级'
          }
        ]
      };
      
      await request(app)
        .post('/api/products/batch-import')
        .send(importData)
        .expect(200);
      
      // 验证二级分类已创建
      const categories = await request(app)
        .get('/api/categories/tree')
        .expect(200);
      
      const parent = categories.body.data.find(
        cat => cat.name === '已有的一级'
      );
      expect(parent).toBeTruthy();
      expect(parent.children).toBeDefined();
      
      const level2Exists = parent.children.some(
        child => child.name === '新的二级'
      );
      expect(level2Exists).toBe(true);
    });
  });
});

// 运行测试
if (require.main === module) {
  const { execSync } = require('child_process');
  try {
    execSync('npx jest test-category-api.spec.js --verbose', {
      cwd: __dirname,
      stdio: 'inherit'
    });
  } catch (e) {
    process.exit(1);
  }
}

module.exports = { app };
