/**
 * L1 集成测试 — form-management 实例可见性 RBAC（Bucket F / 矩阵 #94）
 *
 * 锁定 PR-2 的可见性门修复（instance.service.assertInstanceVisibility）：
 *   - 申请人（createdBy）可见 ✓
 *   - 提交人（submittedBy，与 createdBy 不同的代提交场景）可见 ✓
 *   - 当前活动审批人（ApprovalTask.assignee）可见 ✓
 *   - 历史处理人（ApprovalTaskLog.operatorId）可见 ✓
 *   - Administrator 全可见 ✓
 *   - 路人 form:use 用户访问别人的实例 → 404（不暴露存在性）✗
 *
 * 暂未覆盖（schema 暂无字段）：
 *   - CC 抄送可见性（FormInstance 暂无 ccUserIds 字段）
 */

import { INestApplication } from '@nestjs/common';
import request from 'supertest';
import { PrismaService } from '@/core/database/prisma/prisma.service';
import { createTestApp } from '../../helpers/app.helper';
import { cleanupByPrefix } from '../../helpers/cleanup.helper';
import { createAdminUser } from '../../helpers/factories/user.factory';
import {
  cleanupFormManagementTestData,
  createMinimalApprovalInstance,
  createPlainFormUser,
  createTestFormDefinition,
  createTestFormInstance,
  fakeApprovalInstanceId,
  TestFormDefinition,
} from './_helpers';

describe('form-management instance visibility RBAC - L1', () => {
  let app: INestApplication;
  let prisma: PrismaService;

  // 三类身份：admin（全可见）/ owner（申请人）/ stranger（路人 form:use）
  let adminToken: string;
  let ownerToken: string;
  let ownerId: string;
  let strangerToken: string;
  let strangerId: string;
  let definition: TestFormDefinition;

  beforeAll(async () => {
    process.env.NODE_ENV = 'test';
    app = await createTestApp();
    prisma = app.get<PrismaService>(PrismaService);
  });

  beforeEach(async () => {
    const suffix = `${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;

    const admin = await createAdminUser({
      username: `t_fmrbac_admin_${suffix}`,
      email: `t_fmrbac_admin_${suffix}@example.com`,
      password: 'Admin@123',
      displayName: 't_FmRbac Admin',
    });
    const owner = await createPlainFormUser(prisma, {
      username: `t_fmrbac_owner_${suffix}`,
      email: `t_fmrbac_owner_${suffix}@example.com`,
      password: 'Admin@123',
      displayName: 't_FmRbac Owner',
    });
    const stranger = await createPlainFormUser(prisma, {
      username: `t_fmrbac_str_${suffix}`,
      email: `t_fmrbac_str_${suffix}@example.com`,
      password: 'Admin@123',
      displayName: 't_FmRbac Stranger',
    });
    ownerId = owner.id;
    strangerId = stranger.id;

    const adminLogin = await request(app.getHttpServer())
      .post('/api/v1/auth/login')
      .send({ username: admin.username, password: 'Admin@123' })
      .expect(200);
    adminToken = adminLogin.body.data.accessToken as string;

    const ownerLogin = await request(app.getHttpServer())
      .post('/api/v1/auth/login')
      .send({ username: owner.username, password: 'Admin@123' })
      .expect(200);
    ownerToken = ownerLogin.body.data.accessToken as string;

    const strangerLogin = await request(app.getHttpServer())
      .post('/api/v1/auth/login')
      .send({ username: stranger.username, password: 'Admin@123' })
      .expect(200);
    strangerToken = strangerLogin.body.data.accessToken as string;

    definition = await createTestFormDefinition(prisma, {
      prefix: 't_fmrbac',
      createdBy: ownerId,
      requiresApproval: false,
    });
  });

  afterEach(async () => {
    await cleanupFormManagementTestData(prisma);
    await cleanupByPrefix(prisma);
  });

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

  describe('申请人（createdBy）可见', () => {
    it('owner 创建并访问自己的实例 → 200', async () => {
      const inst = await createTestFormInstance(prisma, {
        definition,
        createdBy: ownerId,
        status: 'DRAFT',
      });
      await request(app.getHttpServer())
        .get(`/api/v1/form-management/instances/${inst.id}`)
        .set('Authorization', `Bearer ${ownerToken}`)
        .set('X-Region-Id', 'CN')
        .expect(200);
    });
  });

  describe('Administrator 全可见', () => {
    it('admin 访问别人的实例 → 200', async () => {
      const inst = await createTestFormInstance(prisma, {
        definition,
        createdBy: ownerId,
        status: 'PENDING_APPROVAL',
      });
      await request(app.getHttpServer())
        .get(`/api/v1/form-management/instances/${inst.id}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .set('X-Region-Id', 'CN')
        .expect(200);
    });
  });

  describe('路人用户访问别人的实例 → 404（不泄露存在性）', () => {
    it('stranger 访问 owner 的实例 → 404', async () => {
      const inst = await createTestFormInstance(prisma, {
        definition,
        createdBy: ownerId,
        status: 'PENDING_APPROVAL',
      });

      // 控制器返回 404 InstanceNotFoundException —— 与 region 不匹配同样路径
      await request(app.getHttpServer())
        .get(`/api/v1/form-management/instances/${inst.id}`)
        .set('Authorization', `Bearer ${strangerToken}`)
        .set('X-Region-Id', 'CN')
        .expect(404);
    });

    it('field-access 端点同样应用可见性门', async () => {
      const inst = await createTestFormInstance(prisma, {
        definition,
        createdBy: ownerId,
        status: 'DRAFT',
      });
      await request(app.getHttpServer())
        .get(`/api/v1/form-management/instances/${inst.id}/field-access`)
        .set('Authorization', `Bearer ${strangerToken}`)
        .set('X-Region-Id', 'CN')
        .expect(404);
    });
  });

  describe('当前活动审批人（ApprovalTask.assignee）可见', () => {
    it('stranger 是 assignee → 可见', async () => {
      const fakeApprovalId = fakeApprovalInstanceId();
      const inst = await createTestFormInstance(prisma, {
        definition,
        createdBy: ownerId,
        status: 'PENDING_APPROVAL',
        approvalInstanceId: fakeApprovalId,
        approvalStatus: 'RUNNING',
      });

      await createMinimalApprovalInstance(prisma, {
        approvalInstanceId: fakeApprovalId,
        formInstanceId: inst.id,
        formBusinessKey: inst.businessKey,
        initiatorId: ownerId,
        suffix: `cur_${Date.now()}`,
        assigneeUserId: strangerId,
      });

      await request(app.getHttpServer())
        .get(`/api/v1/form-management/instances/${inst.id}`)
        .set('Authorization', `Bearer ${strangerToken}`)
        .set('X-Region-Id', 'CN')
        .expect(200);
    });
  });

  describe('历史处理人（ApprovalTaskLog.operatorId）可见', () => {
    it('stranger 在 ApprovalTaskLog 留过操作记录 → 可见，即使任务已 close', async () => {
      const fakeApprovalId = fakeApprovalInstanceId();
      const inst = await createTestFormInstance(prisma, {
        definition,
        createdBy: ownerId,
        status: 'APPROVED',
        approvalInstanceId: fakeApprovalId,
        approvalStatus: 'COMPLETED',
      });

      await createMinimalApprovalInstance(prisma, {
        approvalInstanceId: fakeApprovalId,
        formInstanceId: inst.id,
        formBusinessKey: inst.businessKey,
        initiatorId: ownerId,
        suffix: `hist_${Date.now()}`,
        // assignee=undefined → 任务已 close，stranger 仅在 history log 里
        historyOperatorIds: [strangerId],
      });

      await request(app.getHttpServer())
        .get(`/api/v1/form-management/instances/${inst.id}`)
        .set('Authorization', `Bearer ${strangerToken}`)
        .set('X-Region-Id', 'CN')
        .expect(200);
    });
  });

  describe('提交人（submittedBy）可见', () => {
    it('stranger 不是 createdBy 但是 submittedBy → 可见', async () => {
      const inst = await createTestFormInstance(prisma, {
        definition,
        createdBy: ownerId,
        status: 'SUBMITTED',
      });
      // 造代提交场景
      await prisma.formInstance.update({
        where: { id: inst.id },
        data: { submittedBy: strangerId, submittedAt: new Date() },
      });

      await request(app.getHttpServer())
        .get(`/api/v1/form-management/instances/${inst.id}`)
        .set('Authorization', `Bearer ${strangerToken}`)
        .set('X-Region-Id', 'CN')
        .expect(200);
    });
  });
});
