/**
 * Regions API Integration Tests
 * 
 * 基于 HTTP API 的真正集成测试
 * 
 * 测试内容：
 * - 区域 CRUD 操作
 * - 区域列表查询
 * - 区域统计信息
 * - 代码唯一性约束
 * 
 * 基于文档: docs/modules/organization/07-api.md (Section 4: 区域管理)
 * 
 * @version v2.1
 */

import { INestApplication } from '@nestjs/common';
import request from 'supertest';
import { PrismaService } from '@/core/database/prisma/prisma.service';
import { cleanupDatabase } from '../../helpers/cleanup.helper';
import { createTestApp } from '../../helpers/app.helper';
import { setupIntegrationTestWithOrganization } from '../../helpers/test-setup.helper';

describe('Regions API Integration Tests', () => {
  let app: INestApplication;
  let prisma: PrismaService;
  let adminToken: string;

  beforeAll(async () => {
    app = await createTestApp();
    prisma = app.get<PrismaService>(PrismaService);
  });

  beforeEach(async () => {
    // 🎯 使用统一的测试设置辅助函数
    const context = await setupIntegrationTestWithOrganization(app, prisma, {
      createOrganization: true,
    });
    
    adminToken = context.adminToken;
  });

  afterAll(async () => {
    await cleanupDatabase(prisma);
    await app.close();
  });

  describe('GET /api/v1/regions - 查询区域列表', () => {
    beforeEach(async () => {
      // 创建测试区域
      await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: 'CN',
          name: '中国',
          nameEn: 'China',
          nameZh: '中国',
          timezone: 'Asia/Shanghai',
          currency: 'CNY',
          locale: 'zh-CN',
        });

      await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: 'US',
          name: '美国',
          nameEn: 'United States',
          nameZh: '美国',
          timezone: 'America/New_York',
          currency: 'USD',
          locale: 'en-US',
        });
    });

    it('[API-REGION-001] 应该返回区域列表', async () => {
      const response = await request(app.getHttpServer())
        .get('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(200);

      expect(response.body.success).toBe(true);
      expect(Array.isArray(response.body.data)).toBe(true);
      expect(response.body.data.length).toBeGreaterThan(0);
      expect(response.body.data[0]).toHaveProperty('id');
      expect(response.body.data[0]).toHaveProperty('code');
      expect(response.body.data[0]).toHaveProperty('name');
      expect(response.body.data[0]).toHaveProperty('timezone');
    });
  });

  describe('POST /api/v1/regions - 创建区域', () => {
    it('[API-REGION-002] 应该成功创建区域', async () => {
      const createDto = {
        code: 'UAE',
        name: '阿联酋',
        nameEn: 'United Arab Emirates',
        nameZh: '阿联酋',
        timezone: 'Asia/Dubai',
        currency: 'AED',
        locale: 'ar-AE',
      };

      const response = await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send(createDto)
        .expect(201);

      expect(response.body.success).toBe(true);
      expect(response.body.data).toHaveProperty('id');
      expect(response.body.data.code).toBe('UAE');
      expect(response.body.data.name).toBe('阿联酋');
      expect(response.body.data.isActive).toBe(true);

      // 验证数据库
      const region = await prisma.region.findUnique({
        where: { id: response.body.data.id },
      });

      expect(region).toBeDefined();
      expect(region!.code).toBe('UAE');
    });

    it('[API-REGION-003] 区域代码重复应返回409', async () => {
      // 先创建一个区域
      await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: 'CN',
          name: '中国',
          timezone: 'Asia/Shanghai',
        })
        .expect(201);

      // 尝试创建相同代码的区域
      const response = await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: 'CN', // 相同代码
          name: '中国2',
          timezone: 'Asia/Shanghai',
        })
        .expect(409);

      expect(response.body.success).toBe(false);
      expect(JSON.stringify(response.body.error)).toContain('CODE_EXISTS');
    });

    it('[API-REGION-004] 缺少必填字段应返回400', async () => {
      const response = await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          // 缺少 code 和 name
          timezone: 'Asia/Shanghai',
        })
        .expect(400);

      expect(response.body.success).toBe(false);
    });
  });

  describe('GET /api/v1/regions/:id - 查询区域详情', () => {
    let regionId: string;

    beforeEach(async () => {
      const uniqueCode = `DETAIL_${Date.now()}_${Math.random().toString(36).substring(7)}`;
      const createResponse = await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: uniqueCode,
          name: '中国',
          timezone: 'Asia/Shanghai',
        });

      regionId = createResponse.body.data.id;
    });

    it('[API-REGION-005] 应该返回区域详情', async () => {
      const response = await request(app.getHttpServer())
        .get(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(200);

      expect(response.body.success).toBe(true);
      expect(response.body.data).toHaveProperty('id', regionId);
      expect(response.body.data).toHaveProperty('code');
      expect(response.body.data).toHaveProperty('name', '中国');
    });

    it('[API-REGION-006] 区域不存在应返回404', async () => {
      const response = await request(app.getHttpServer())
        .get('/api/v1/regions/00000000-0000-0000-0000-000000000000')
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(404);

      expect(response.body.success).toBe(false);
    });
  });

  describe('PUT /api/v1/regions/:id - 更新区域', () => {
    let regionId: string;

    beforeEach(async () => {
      const uniqueCode = `CN_${Date.now()}_${Math.random().toString(36).substring(7)}`;
      const createResponse = await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: uniqueCode,
          name: '中国',
          timezone: 'Asia/Shanghai',
        });

      regionId = createResponse.body.data.id;
    });

    it('[API-REGION-007] 应该成功更新区域信息', async () => {
      const updateDto = {
        name: '中华人民共和国',
        nameEn: 'People\'s Republic of China',
      };

      const response = await request(app.getHttpServer())
        .patch(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .send(updateDto)
        .expect(200);

      expect(response.body.success).toBe(true);
      expect(response.body.data.name).toBe('中华人民共和国');
      expect(response.body.data.nameEn).toBe('People\'s Republic of China');

      // 验证数据库
      const region = await prisma.region.findUnique({
        where: { id: regionId },
      });

      expect(region!.name).toBe('中华人民共和国');
    });

    it('[API-REGION-008] 不能修改区域代码', async () => {
      // 尝试修改代码（会被忽略，因为 DTO 中可能没有 code 字段）
      const response = await request(app.getHttpServer())
        .patch(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: 'NEW_CODE', // 尝试修改代码
          name: '修改后的名字',
        })
        .expect(200);

      expect(response.body.success).toBe(true);
      
      // 验证代码没有被修改
      const region = await prisma.region.findUnique({
        where: { id: regionId },
      });
      
      expect(region!.code).not.toBe('NEW_CODE'); // 代码保持原值
      expect(region!.name).toBe('修改后的名字'); // 名字已修改
    });
  });

  describe('DELETE /api/v1/regions/:id - 删除区域', () => {
    let regionId: string;

    beforeEach(async () => {
      const uniqueCode = `DEL_${Date.now()}_${Math.random().toString(36).substring(7)}`;
      const createResponse = await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: uniqueCode,
          name: '测试区域',
          timezone: 'Asia/Shanghai',
        });

      regionId = createResponse.body.data.id;
    });

    it('[API-REGION-009] 应该成功删除区域', async () => {
      await request(app.getHttpServer())
        .delete(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(200);

      // 验证已软删除（deletedAt 不为 null）
      const region = await prisma.region.findUnique({
        where: { id: regionId },
      });

      expect(region).toBeDefined();
      expect(region!.deletedAt).not.toBeNull();
    });

    it('[API-REGION-010] 有关联组织时不能删除', async () => {
      // 直接通过数据库创建使用该区域的组织
      await prisma.organization.create({
        data: {
          code: `ORG_WITH_REGION_${Date.now()}`,
          name: 'Organization with Region',
          status: 'ACTIVE',
          primaryRegionId: regionId,
        },
      });

      // 尝试删除区域
      const response = await request(app.getHttpServer())
        .delete(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(409);

      expect(response.body.success).toBe(false);
      // 错误消息应包含相关信息
      expect(response.body.error.message).toBeDefined();
    });
  });

  describe('完整业务流程测试', () => {
    it('[API-REGION-FLOW-001] 应该完成完整的区域管理流程', async () => {
      // 1. 创建区域
      const createResponse = await request(app.getHttpServer())
        .post('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          code: 'UAE',
          name: '阿联酋',
          nameEn: 'United Arab Emirates',
          timezone: 'Asia/Dubai',
          currency: 'AED',
        })
        .expect(201);

      const regionId = createResponse.body.data.id;

      // 2. 查询区域详情
      const detailResponse = await request(app.getHttpServer())
        .get(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(200);

      expect(detailResponse.body.data.code).toBe('UAE');

      // 3. 更新区域
      await request(app.getHttpServer())
        .patch(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          nameZh: '阿拉伯联合酋长国',
        })
        .expect(200);

      // 4. 查询列表
      const listResponse = await request(app.getHttpServer())
        .get('/api/v1/regions')
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(200);

      expect(listResponse.body.data.length).toBeGreaterThan(0);

      // 5. 删除区域
      await request(app.getHttpServer())
        .delete(`/api/v1/regions/${regionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(200);

      console.log('✅ 区域管理完整流程测试通过');
    });
  });
});

