/**
 * IAM 后台 - Role × DataScope 绑定矩阵
 */
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 { setupIntegrationTest } from '../../helpers/test-setup.helper';

describe('IAM Admin - RoleDataScopes API', () => {
  let app: INestApplication;
  let prisma: PrismaService;
  let adminToken: string;

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

  beforeEach(async () => {
    const ctx = await setupIntegrationTest(app, prisma);
    adminToken = ctx.adminToken;
  });

  afterEach(async () => {
    await cleanupDatabase(prisma);
  });

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

  async function aTestRole() {
    return prisma.role.create({
      data: {
        code: `ROLE_TEST_${Date.now()}`,
        name: 'role test',
        description: 'rds test',
        isBuiltIn: false,
        enabled: true,
      },
    });
  }

  async function aTestScope() {
    return prisma.dataScope.create({
      data: {
        code: `SCOPE_TEST_${Date.now()}`,
        name: 'rds scope',
        scopeType: 'ORGANIZATION',
        isBuiltIn: false,
      },
    });
  }

  it('[IAM-ADMIN-RDS-001] POST 绑定成功，落审计', async () => {
    const role = await aTestRole();
    const scope = await aTestScope();

    const res = await request(app.getHttpServer())
      .post('/api/v1/iam/role-data-scopes')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({ roleId: role.id, dataScopeId: scope.id, resource: 'purchase_order' })
      .expect(201);

    expect(res.body.data.roleId).toBe(role.id);

    const audits = await prisma.iamAuditLog.findMany({
      where: { resource: 'RoleDataScope', action: 'CREATE', targetId: res.body.data.id },
    });
    expect(audits.length).toBe(1);
  });

  it('[IAM-ADMIN-RDS-002] 重复绑定被拒（roleId+dataScopeId+resource 唯一）', async () => {
    const role = await aTestRole();
    const scope = await aTestScope();

    await request(app.getHttpServer())
      .post('/api/v1/iam/role-data-scopes')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({ roleId: role.id, dataScopeId: scope.id, resource: '*' })
      .expect(201);

    await request(app.getHttpServer())
      .post('/api/v1/iam/role-data-scopes')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({ roleId: role.id, dataScopeId: scope.id, resource: '*' })
      .expect(409);
  });

  it('[IAM-ADMIN-RDS-003] DELETE 解绑后再绑定可成功', async () => {
    const role = await aTestRole();
    const scope = await aTestScope();

    const created = await request(app.getHttpServer())
      .post('/api/v1/iam/role-data-scopes')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({ roleId: role.id, dataScopeId: scope.id, resource: '*' })
      .expect(201);

    await request(app.getHttpServer())
      .delete(`/api/v1/iam/role-data-scopes/${created.body.data.id}`)
      .set('Authorization', `Bearer ${adminToken}`)
      .expect(200);

    await request(app.getHttpServer())
      .post('/api/v1/iam/role-data-scopes')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({ roleId: role.id, dataScopeId: scope.id, resource: '*' })
      .expect(201);
  });

  it('[IAM-ADMIN-RDS-004] GET ?roleId= 返回该角色的所有绑定', async () => {
    const role = await aTestRole();
    const scope = await aTestScope();

    await request(app.getHttpServer())
      .post('/api/v1/iam/role-data-scopes')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({ roleId: role.id, dataScopeId: scope.id, resource: '*' })
      .expect(201);

    const res = await request(app.getHttpServer())
      .get(`/api/v1/iam/role-data-scopes?roleId=${role.id}`)
      .set('Authorization', `Bearer ${adminToken}`)
      .expect(200);

    expect(res.body.data.length).toBe(1);
    expect(res.body.data[0].dataScope.code).toBe(scope.code);
  });

  it('[IAM-ADMIN-RDS-005] 不存在的 role 报 404', async () => {
    const scope = await aTestScope();
    await request(app.getHttpServer())
      .post('/api/v1/iam/role-data-scopes')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({
        roleId: '00000000-0000-0000-0000-000000000000',
        dataScopeId: scope.id,
        resource: '*',
      })
      .expect(404);
  });
});
