import type { INestApplication } from '@nestjs/common';
import { NotFoundException } from '@nestjs/common';
import request from 'supertest';
import { Role, UploadAssetType } from '../../../src/generated/prisma/enums.js';
import { PrismaService } from '../../../src/prisma.service.js';
import {
  E2E_SEED_CREDENTIALS,
  E2E_SEED_PASSWORD,
} from '../fixtures/e2e-roles.js';
import { expectSuccessEnvelope } from './e2e-http.helper.js';

export interface E2ESeedFixtures {
  hospitalAId: number;
  hospitalBId: number;
  departmentA1Id: number;
  departmentA2Id: number;
  departmentB1Id: number;
  groupA1Id: number;
  groupA2Id: number;
  groupB1Id: number;
  catalogs: {
    adjustableValveId: number;
    highPressureValveId: number;
  };
  users: {
    systemAdminId: number;
    hospitalAdminAId: number;
    directorAId: number;
    leaderAId: number;
    doctorAId: number;
    doctorA2Id: number;
    doctorA3Id: number;
    doctorBId: number;
    engineerAId: number;
    engineerBId: number;
  };
  patients: {
    patientA1Id: number;
    patientA2Id: number;
    patientA3Id: number;
    patientB1Id: number;
  };
  devices: {
    deviceA1Id: number;
    deviceA2Id: number;
    deviceA3Id: number;
    deviceA4InactiveId: number;
    deviceB1Id: number;
  };
}

interface SeedUserScope {
  id: number;
  hospitalId: number | null;
  departmentId: number | null;
  groupId: number | null;
}

const OPEN_IDS = {
  systemAdmin: 'seed-system-admin-openid',
  hospitalAdminA: 'seed-hospital-admin-a-openid',
  hospitalAdminB: 'seed-hospital-admin-b-openid',
  directorA: 'seed-director-a-openid',
  leaderA: 'seed-leader-a-openid',
  doctorA: 'seed-doctor-a-openid',
  doctorA2: 'seed-doctor-a2-openid',
  doctorA3: 'seed-doctor-a3-openid',
  doctorB: 'seed-doctor-b-openid',
  engineerA: 'seed-engineer-a-openid',
  engineerB: 'seed-engineer-b-openid',
} as const;

const FIXTURE_NAMES = {
  hospitalA: 'Seed Hospital A',
  hospitalB: 'Seed Hospital B',
  departmentA1: 'Neurosurgery-A1',
  departmentA2: 'Cardiology-A2',
  departmentB1: 'Neurosurgery-B1',
  groupA1: 'Shift-A1',
  groupA2: 'Shift-A2',
  groupB1: 'Shift-B1',
  adjustableCatalog: 'SEED-ADJUSTABLE-VALVE',
  highPressureCatalog: 'SEED-HIGH-PRESSURE-VALVE',
} as const;

const EXTRA_PHONES = {
  hospitalAdminB: '13800001101',
  doctorA2: '13800001204',
  doctorA3: '13800001304',
  doctorB: '13800001104',
  engineerB: '13800001105',
} as const;

const SHARED_PATIENT_IDENTITY = {
  phone: '13800002001',
  idCard: '110101199001010011',
} as const;

export async function ensureE2EFixtures(
  app: INestApplication,
  prisma: PrismaService,
): Promise<E2ESeedFixtures> {
  const existingSystemAdmin = await prisma.user.findFirst({
    where: {
      phone: E2E_SEED_CREDENTIALS[Role.SYSTEM_ADMIN].phone,
      role: Role.SYSTEM_ADMIN,
    },
    select: { id: true },
  });

  if (!existingSystemAdmin) {
    await bootstrapFixturesViaApi(app, prisma);
  }

  try {
    return await loadSeedFixtures(prisma);
  } catch (error) {
    await repairFixturesViaApi(app, prisma);
    return loadSeedFixtures(prisma);
  }
}

async function bootstrapFixturesViaApi(
  app: INestApplication,
  prisma: PrismaService,
) {
  const server = app.getHttpServer();

  await createSystemAdmin(server);
  const systemAdminToken = await loginByCredential(server, {
    phone: E2E_SEED_CREDENTIALS[Role.SYSTEM_ADMIN].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.SYSTEM_ADMIN,
  });

  const hospitalA = await createWithToken(
    server,
    systemAdminToken,
    '/b/organization/hospitals',
    { name: FIXTURE_NAMES.hospitalA },
  );
  const hospitalB = await createWithToken(
    server,
    systemAdminToken,
    '/b/organization/hospitals',
    { name: FIXTURE_NAMES.hospitalB },
  );

  const hospitalAdminA = await createWithToken(
    server,
    systemAdminToken,
    '/users',
    {
      name: 'Seed Hospital Admin A',
      phone: E2E_SEED_CREDENTIALS[Role.HOSPITAL_ADMIN].phone,
      password: E2E_SEED_PASSWORD,
      role: Role.HOSPITAL_ADMIN,
      hospitalId: hospitalA.id,
      openId: OPEN_IDS.hospitalAdminA,
    },
  );
  await createWithToken(server, systemAdminToken, '/users', {
    name: 'Seed Hospital Admin B',
    phone: EXTRA_PHONES.hospitalAdminB,
    password: E2E_SEED_PASSWORD,
    role: Role.HOSPITAL_ADMIN,
    hospitalId: hospitalB.id,
    openId: OPEN_IDS.hospitalAdminB,
  });

  const engineerA = await createWithToken(server, systemAdminToken, '/users', {
    name: 'Seed Engineer A',
    phone: E2E_SEED_CREDENTIALS[Role.ENGINEER].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.ENGINEER,
    hospitalId: hospitalA.id,
    openId: OPEN_IDS.engineerA,
  });
  const engineerB = await createWithToken(server, systemAdminToken, '/users', {
    name: 'Seed Engineer B',
    phone: EXTRA_PHONES.engineerB,
    password: E2E_SEED_PASSWORD,
    role: Role.ENGINEER,
    hospitalId: hospitalB.id,
    openId: OPEN_IDS.engineerB,
  });

  await patchWithToken(
    server,
    systemAdminToken,
    `/b/users/${engineerA.id}/assign-engineer-hospital`,
    { hospitalId: hospitalA.id },
  );
  await patchWithToken(
    server,
    systemAdminToken,
    `/b/users/${engineerB.id}/assign-engineer-hospital`,
    { hospitalId: hospitalB.id },
  );

  const hospitalAdminAToken = await loginByCredential(server, {
    phone: hospitalAdminA.phone,
    password: E2E_SEED_PASSWORD,
    role: Role.HOSPITAL_ADMIN,
    hospitalId: hospitalA.id,
  });
  const hospitalAdminBToken = await loginByCredential(server, {
    phone: EXTRA_PHONES.hospitalAdminB,
    password: E2E_SEED_PASSWORD,
    role: Role.HOSPITAL_ADMIN,
    hospitalId: hospitalB.id,
  });

  const departmentA1 = await createWithToken(
    server,
    hospitalAdminAToken,
    '/b/organization/departments',
    {
      name: FIXTURE_NAMES.departmentA1,
      hospitalId: hospitalA.id,
    },
  );
  const departmentA2 = await createWithToken(
    server,
    hospitalAdminAToken,
    '/b/organization/departments',
    {
      name: FIXTURE_NAMES.departmentA2,
      hospitalId: hospitalA.id,
    },
  );
  const departmentB1 = await createWithToken(
    server,
    hospitalAdminBToken,
    '/b/organization/departments',
    {
      name: FIXTURE_NAMES.departmentB1,
      hospitalId: hospitalB.id,
    },
  );

  const groupA1 = await createWithToken(
    server,
    hospitalAdminAToken,
    '/b/organization/groups',
    {
      name: FIXTURE_NAMES.groupA1,
      departmentId: departmentA1.id,
    },
  );
  const groupA2 = await createWithToken(
    server,
    hospitalAdminAToken,
    '/b/organization/groups',
    {
      name: FIXTURE_NAMES.groupA2,
      departmentId: departmentA2.id,
    },
  );
  const groupB1 = await createWithToken(
    server,
    hospitalAdminBToken,
    '/b/organization/groups',
    {
      name: FIXTURE_NAMES.groupB1,
      departmentId: departmentB1.id,
    },
  );

  const directorA = await createWithToken(
    server,
    hospitalAdminAToken,
    '/users',
    {
      name: 'Seed Director A',
      phone: E2E_SEED_CREDENTIALS[Role.DIRECTOR].phone,
      password: E2E_SEED_PASSWORD,
      role: Role.DIRECTOR,
      hospitalId: hospitalA.id,
      departmentId: departmentA1.id,
      openId: OPEN_IDS.directorA,
    },
  );
  await createWithToken(server, hospitalAdminAToken, '/users', {
    name: 'Seed Leader A',
    phone: E2E_SEED_CREDENTIALS[Role.LEADER].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.LEADER,
    hospitalId: hospitalA.id,
    departmentId: departmentA1.id,
    groupId: groupA1.id,
    openId: OPEN_IDS.leaderA,
  });
  const doctorA = await createWithToken(server, hospitalAdminAToken, '/users', {
    name: 'Seed Doctor A',
    phone: E2E_SEED_CREDENTIALS[Role.DOCTOR].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: hospitalA.id,
    departmentId: departmentA1.id,
    groupId: groupA1.id,
    openId: OPEN_IDS.doctorA,
  });
  const doctorA2 = await createWithToken(
    server,
    hospitalAdminAToken,
    '/users',
    {
      name: 'Seed Doctor A2',
      phone: EXTRA_PHONES.doctorA2,
      password: E2E_SEED_PASSWORD,
      role: Role.DOCTOR,
      hospitalId: hospitalA.id,
      departmentId: departmentA1.id,
      groupId: groupA1.id,
      openId: OPEN_IDS.doctorA2,
    },
  );
  const doctorA3 = await createWithToken(
    server,
    hospitalAdminAToken,
    '/users',
    {
      name: 'Seed Doctor A3',
      phone: EXTRA_PHONES.doctorA3,
      password: E2E_SEED_PASSWORD,
      role: Role.DOCTOR,
      hospitalId: hospitalA.id,
      departmentId: departmentA2.id,
      groupId: groupA2.id,
      openId: OPEN_IDS.doctorA3,
    },
  );
  const doctorB = await createWithToken(server, hospitalAdminBToken, '/users', {
    name: 'Seed Doctor B',
    phone: EXTRA_PHONES.doctorB,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: hospitalB.id,
    departmentId: departmentB1.id,
    groupId: groupB1.id,
    openId: OPEN_IDS.doctorB,
  });

  await bootstrapDictionaries(server, systemAdminToken);

  const adjustableCatalog = await createWithToken(
    server,
    systemAdminToken,
    '/b/devices/catalogs',
    {
      modelCode: FIXTURE_NAMES.adjustableCatalog,
      manufacturer: 'Seed MedTech',
      name: 'Seed 可调压分流阀',
      isValve: true,
      pressureLevels: ['0.5', '1', '1.5'],
      notes: 'Seed 全局可调压目录样例',
    },
  );
  await createWithToken(server, systemAdminToken, '/b/devices/catalogs', {
    modelCode: FIXTURE_NAMES.highPressureCatalog,
    manufacturer: 'Seed MedTech',
    name: 'Seed 高压挡位阀',
    isValve: true,
    pressureLevels: ['10', '20', '30'],
    notes: 'Seed 高压挡位目录样例',
  });

  const doctorAToken = await loginByCredential(server, {
    phone: doctorA.phone,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: hospitalA.id,
  });
  const doctorA2Token = await loginByCredential(server, {
    phone: EXTRA_PHONES.doctorA2,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: hospitalA.id,
  });
  const doctorA3Token = await loginByCredential(server, {
    phone: EXTRA_PHONES.doctorA3,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: hospitalA.id,
  });
  const doctorBToken = await loginByCredential(server, {
    phone: EXTRA_PHONES.doctorB,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: hospitalB.id,
  });
  const engineerAToken = await loginByCredential(server, {
    phone: E2E_SEED_CREDENTIALS[Role.ENGINEER].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.ENGINEER,
    hospitalId: hospitalA.id,
  });

  const patientA1 = await createWithToken(server, doctorAToken, '/b/patients', {
    name: 'Seed Patient A1',
    inpatientNo: 'ZYH-A-0001',
    projectName: '脑积水随访项目-A',
    phone: SHARED_PATIENT_IDENTITY.phone,
    idCard: SHARED_PATIENT_IDENTITY.idCard,
    doctorId: doctorA.id,
    initialSurgery: {
      surgeryDate: '2024-06-01T08:00:00.000Z',
      surgeryName: '首次脑室腹腔分流术',
      preOpPressure: 24,
      primaryDisease: '先天性脑积水',
      hydrocephalusTypes: ['交通性'],
      notes: '首台手术',
      devices: [
        {
          implantCatalogId: adjustableCatalog.id,
          shuntMode: 'VPS',
          proximalPunctureAreas: ['额角'],
          valvePlacementSites: ['耳后'],
          distalShuntDirection: '腹腔',
          initialPressure: '1',
          implantNotes: 'Seed A1 弃用历史设备',
          labelImageUrl: 'https://seed.example.com/labels/a1-004.jpg',
        },
      ],
    },
  });

  const oldDeviceId = patientA1.devices?.[0]?.id;
  if (!oldDeviceId) {
    throw new Error('failed to create seed old device');
  }

  const revisionA1 = await createWithToken(
    server,
    doctorAToken,
    `/b/patients/${patientA1.id}/surgeries`,
    {
      surgeryDate: '2025-09-10T08:00:00.000Z',
      surgeryName: '分流系统翻修术',
      preOpPressure: 18,
      primaryDisease: '分流功能障碍',
      hydrocephalusTypes: ['交通性', '高压性'],
      previousShuntSurgeryDate: '2024-06-01T08:00:00.000Z',
      preOpMaterials: [
        {
          type: 'IMAGE',
          url: 'https://seed.example.com/a1-ct-preop.png',
          name: 'Seed A1 术前 CT',
        },
      ],
      notes: '二次手术，保留原设备历史',
      abandonedDeviceIds: [oldDeviceId],
      devices: [
        {
          implantCatalogId: adjustableCatalog.id,
          shuntMode: 'VPS',
          proximalPunctureAreas: ['额角'],
          valvePlacementSites: ['耳后'],
          distalShuntDirection: '腹腔',
          initialPressure: '1',
          implantNotes: 'Seed A1 当前在用设备',
          labelImageUrl: 'https://seed.example.com/labels/a1-001.jpg',
        },
      ],
    },
  );

  const patientA2 = await createWithToken(
    server,
    doctorA2Token,
    '/b/patients',
    {
      name: 'Seed Patient A2',
      inpatientNo: 'ZYH-A-0002',
      projectName: '脑积水随访项目-A',
      phone: '13800002002',
      idCard: '110101199002020022',
      doctorId: doctorA2.id,
      initialSurgery: {
        surgeryDate: '2025-12-15T08:00:00.000Z',
        surgeryName: '脑室腹腔分流术',
        preOpPressure: 20,
        primaryDisease: '肿瘤相关脑积水',
        hydrocephalusTypes: ['梗阻性'],
        devices: [
          {
            implantCatalogId: adjustableCatalog.id,
            shuntMode: 'VPS',
            proximalPunctureAreas: ['枕角'],
            valvePlacementSites: ['胸前'],
            distalShuntDirection: '腹腔',
            initialPressure: '1',
            implantNotes: 'Seed A2 当前在用设备',
            labelImageUrl: 'https://seed.example.com/labels/a2-002.jpg',
          },
        ],
      },
    },
  );

  await createWithToken(server, doctorA3Token, '/b/patients', {
    name: 'Seed Patient A3',
    inpatientNo: 'ZYH-A-0003',
    projectName: '脑积水随访项目-A',
    phone: '13800002003',
    idCard: '110101199003030033',
    doctorId: doctorA3.id,
    initialSurgery: {
      surgeryDate: '2025-11-20T08:00:00.000Z',
      surgeryName: '脑室腹腔分流术',
      preOpPressure: 21,
      primaryDisease: '外伤后脑积水',
      hydrocephalusTypes: ['交通性'],
      devices: [
        {
          implantCatalogId: adjustableCatalog.id,
          shuntMode: 'LPS',
          proximalPunctureAreas: ['腰穿'],
          valvePlacementSites: ['腰背部'],
          distalShuntDirection: '腹腔',
          initialPressure: '1',
          implantNotes: 'Seed A3 当前在用设备',
          labelImageUrl: 'https://seed.example.com/labels/a3-003.jpg',
        },
      ],
    },
  });

  const patientB1 = await createWithToken(server, doctorBToken, '/b/patients', {
    name: 'Seed Patient B1',
    inpatientNo: 'ZYH-B-0001',
    projectName: '脑积水随访项目-B',
    phone: SHARED_PATIENT_IDENTITY.phone,
    idCard: SHARED_PATIENT_IDENTITY.idCard,
    doctorId: doctorB.id,
    initialSurgery: {
      surgeryDate: '2025-10-05T08:00:00.000Z',
      surgeryName: '脑室腹腔分流术',
      preOpPressure: 23,
      primaryDisease: '出血后脑积水',
      hydrocephalusTypes: ['高压性'],
      devices: [
        {
          implantCatalogId: adjustableCatalog.id,
          shuntMode: 'VPS',
          proximalPunctureAreas: ['额角'],
          valvePlacementSites: ['耳后'],
          distalShuntDirection: '腹腔',
          initialPressure: '1',
          implantNotes: 'Seed B1 当前在用设备',
          labelImageUrl: 'https://seed.example.com/labels/b1-001.jpg',
        },
      ],
    },
  });

  const deviceA1Id = revisionA1.devices?.[0]?.id;
  const deviceB1Id = patientB1.devices?.[0]?.id;
  if (!deviceA1Id || !deviceB1Id) {
    throw new Error('failed to create seed active devices');
  }

  const publishedA = await createWithToken(
    server,
    doctorAToken,
    '/b/tasks/publish',
    {
      items: [
        {
          deviceId: deviceA1Id,
          targetPressure: '1.5',
        },
      ],
    },
  );

  await createWithToken(server, engineerAToken, '/b/tasks/accept', {
    taskId: publishedA.id,
  });

  const engineerProofAsset = await ensureTaskCompletionAsset(
    prisma,
    hospitalA.id,
    engineerA.id,
    'seed-bootstrap-engineer-proof-a',
  );
  await createWithToken(
    server,
    engineerAToken,
    '/b/tasks/complete',
    buildTaskCompletionPayload(publishedA.id, engineerProofAsset),
  );

  await createWithToken(server, doctorBToken, '/b/tasks/publish', {
    items: [
      {
        deviceId: deviceB1Id,
        targetPressure: '1.5',
      },
    ],
  });

  // 防止未使用变量被误删，保留显式访问。
  void patientA2;
}

async function repairFixturesViaApi(
  app: INestApplication,
  prisma: PrismaService,
) {
  const server = app.getHttpServer();
  const systemAdminToken = await loginByCredential(server, {
    phone: E2E_SEED_CREDENTIALS[Role.SYSTEM_ADMIN].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.SYSTEM_ADMIN,
  });

  const hospitalAdminA = await requireUserScope(
    prisma,
    OPEN_IDS.hospitalAdminA,
  );
  const doctorA = await requireUserScope(prisma, OPEN_IDS.doctorA);
  const doctorA2 = await requireUserScope(prisma, OPEN_IDS.doctorA2);
  const doctorA3 = await requireUserScope(prisma, OPEN_IDS.doctorA3);
  const doctorB = await requireUserScope(prisma, OPEN_IDS.doctorB);
  const engineerA = await requireUserScope(prisma, OPEN_IDS.engineerA);

  if (
    hospitalAdminA.hospitalId == null ||
    doctorA.hospitalId == null ||
    doctorB.hospitalId == null ||
    engineerA.hospitalId == null ||
    doctorA.id == null ||
    doctorA2.id == null ||
    doctorA3.id == null ||
    doctorB.id == null ||
    engineerA.id == null
  ) {
    throw new NotFoundException('Seed user scope is incomplete');
  }

  const adjustableCatalog = await ensureCatalogViaApi(
    prisma,
    server,
    systemAdminToken,
    {
      modelCode: FIXTURE_NAMES.adjustableCatalog,
      manufacturer: 'Seed MedTech',
      name: 'Seed 可调压分流阀',
      isValve: true,
      pressureLevels: ['0.5', '1', '1.5'],
      notes: 'Seed 全局可调压目录样例',
    },
  );
  await ensureCatalogViaApi(prisma, server, systemAdminToken, {
    modelCode: FIXTURE_NAMES.highPressureCatalog,
    manufacturer: 'Seed MedTech',
    name: 'Seed 高压挡位阀',
    isValve: true,
    pressureLevels: ['10', '20', '30'],
    notes: 'Seed 高压挡位目录样例',
  });

  const doctorAToken = await loginByCredential(server, {
    phone: E2E_SEED_CREDENTIALS[Role.DOCTOR].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: doctorA.hospitalId,
  });
  const doctorA2Token = await loginByCredential(server, {
    phone: EXTRA_PHONES.doctorA2,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: doctorA.hospitalId,
  });
  const doctorA3Token = await loginByCredential(server, {
    phone: EXTRA_PHONES.doctorA3,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: doctorA.hospitalId,
  });
  const doctorBToken = await loginByCredential(server, {
    phone: EXTRA_PHONES.doctorB,
    password: E2E_SEED_PASSWORD,
    role: Role.DOCTOR,
    hospitalId: doctorB.hospitalId,
  });
  const engineerAToken = await loginByCredential(server, {
    phone: E2E_SEED_CREDENTIALS[Role.ENGINEER].phone,
    password: E2E_SEED_PASSWORD,
    role: Role.ENGINEER,
    hospitalId: doctorA.hospitalId,
  });

  let patientA1Id = await findPatientId(
    prisma,
    doctorA.hospitalId,
    SHARED_PATIENT_IDENTITY.phone,
    SHARED_PATIENT_IDENTITY.idCard,
  );
  if (!patientA1Id) {
    const patientA1 = await createWithToken(
      server,
      doctorAToken,
      '/b/patients',
      {
        name: 'Seed Patient A1',
        inpatientNo: 'ZYH-A-0001',
        projectName: '脑积水随访项目-A',
        phone: SHARED_PATIENT_IDENTITY.phone,
        idCard: SHARED_PATIENT_IDENTITY.idCard,
        doctorId: doctorA.id,
        initialSurgery: {
          surgeryDate: '2024-06-01T08:00:00.000Z',
          surgeryName: '首次脑室腹腔分流术',
          preOpPressure: 24,
          primaryDisease: '先天性脑积水',
          hydrocephalusTypes: ['交通性'],
          notes: '首台手术',
          devices: [
            {
              implantCatalogId: adjustableCatalog.id,
              shuntMode: 'VPS',
              proximalPunctureAreas: ['额角'],
              valvePlacementSites: ['耳后'],
              distalShuntDirection: '腹腔',
              initialPressure: '1',
              implantNotes: 'Seed A1 弃用历史设备',
              labelImageUrl: 'https://seed.example.com/labels/a1-004.jpg',
            },
          ],
        },
      },
    );

    const oldDeviceId = patientA1.devices?.[0]?.id;
    if (!oldDeviceId) {
      throw new Error('failed to create seed old device');
    }

    await createWithToken(
      server,
      doctorAToken,
      `/b/patients/${patientA1.id}/surgeries`,
      {
        surgeryDate: '2025-09-10T08:00:00.000Z',
        surgeryName: '分流系统翻修术',
        preOpPressure: 18,
        primaryDisease: '分流功能障碍',
        hydrocephalusTypes: ['交通性', '高压性'],
        previousShuntSurgeryDate: '2024-06-01T08:00:00.000Z',
        preOpMaterials: [
          {
            type: 'IMAGE',
            url: 'https://seed.example.com/a1-ct-preop.png',
            name: 'Seed A1 术前 CT',
          },
        ],
        notes: '二次手术，保留原设备历史',
        abandonedDeviceIds: [oldDeviceId],
        devices: [
          {
            implantCatalogId: adjustableCatalog.id,
            shuntMode: 'VPS',
            proximalPunctureAreas: ['额角'],
            valvePlacementSites: ['耳后'],
            distalShuntDirection: '腹腔',
            initialPressure: '1',
            implantNotes: 'Seed A1 当前在用设备',
            labelImageUrl: 'https://seed.example.com/labels/a1-001.jpg',
          },
        ],
      },
    );
    patientA1Id = patientA1.id;
  }

  if (
    !(await findPatientId(
      prisma,
      doctorA.hospitalId,
      '13800002002',
      '110101199002020022',
    ))
  ) {
    await createWithToken(server, doctorA2Token, '/b/patients', {
      name: 'Seed Patient A2',
      inpatientNo: 'ZYH-A-0002',
      projectName: '脑积水随访项目-A',
      phone: '13800002002',
      idCard: '110101199002020022',
      doctorId: doctorA2.id,
      initialSurgery: {
        surgeryDate: '2025-12-15T08:00:00.000Z',
        surgeryName: '脑室腹腔分流术',
        preOpPressure: 20,
        primaryDisease: '肿瘤相关脑积水',
        hydrocephalusTypes: ['梗阻性'],
        devices: [
          {
            implantCatalogId: adjustableCatalog.id,
            shuntMode: 'VPS',
            proximalPunctureAreas: ['枕角'],
            valvePlacementSites: ['胸前'],
            distalShuntDirection: '腹腔',
            initialPressure: '1',
            implantNotes: 'Seed A2 当前在用设备',
            labelImageUrl: 'https://seed.example.com/labels/a2-002.jpg',
          },
        ],
      },
    });
  }

  if (
    !(await findPatientId(
      prisma,
      doctorA.hospitalId,
      '13800002003',
      '110101199003030033',
    ))
  ) {
    await createWithToken(server, doctorA3Token, '/b/patients', {
      name: 'Seed Patient A3',
      inpatientNo: 'ZYH-A-0003',
      projectName: '脑积水随访项目-A',
      phone: '13800002003',
      idCard: '110101199003030033',
      doctorId: doctorA3.id,
      initialSurgery: {
        surgeryDate: '2025-11-20T08:00:00.000Z',
        surgeryName: '脑室腹腔分流术',
        preOpPressure: 21,
        primaryDisease: '外伤后脑积水',
        hydrocephalusTypes: ['交通性'],
        devices: [
          {
            implantCatalogId: adjustableCatalog.id,
            shuntMode: 'LPS',
            proximalPunctureAreas: ['腰穿'],
            valvePlacementSites: ['腰背部'],
            distalShuntDirection: '腹腔',
            initialPressure: '1',
            implantNotes: 'Seed A3 当前在用设备',
            labelImageUrl: 'https://seed.example.com/labels/a3-003.jpg',
          },
        ],
      },
    });
  }

  if (
    !(await findPatientId(
      prisma,
      doctorB.hospitalId,
      SHARED_PATIENT_IDENTITY.phone,
      SHARED_PATIENT_IDENTITY.idCard,
    ))
  ) {
    await createWithToken(server, doctorBToken, '/b/patients', {
      name: 'Seed Patient B1',
      inpatientNo: 'ZYH-B-0001',
      projectName: '脑积水随访项目-B',
      phone: SHARED_PATIENT_IDENTITY.phone,
      idCard: SHARED_PATIENT_IDENTITY.idCard,
      doctorId: doctorB.id,
      initialSurgery: {
        surgeryDate: '2025-10-05T08:00:00.000Z',
        surgeryName: '脑室腹腔分流术',
        preOpPressure: 23,
        primaryDisease: '出血后脑积水',
        hydrocephalusTypes: ['高压性'],
        devices: [
          {
            implantCatalogId: adjustableCatalog.id,
            shuntMode: 'VPS',
            proximalPunctureAreas: ['额角'],
            valvePlacementSites: ['耳后'],
            distalShuntDirection: '腹腔',
            initialPressure: '1',
            implantNotes: 'Seed B1 当前在用设备',
            labelImageUrl: 'https://seed.example.com/labels/b1-001.jpg',
          },
        ],
      },
    });
  }

  const deviceA1Id = await requireDeviceId(prisma, 'Seed A1 当前在用设备');
  const deviceB1Id = await requireDeviceId(prisma, 'Seed B1 当前在用设备');

  if (!(await hasTaskItemForDevice(prisma, deviceA1Id))) {
    const publishedA = await createWithToken(
      server,
      doctorAToken,
      '/b/tasks/publish',
      {
        items: [
          {
            deviceId: deviceA1Id,
            targetPressure: '1.5',
          },
        ],
      },
    );

    await createWithToken(server, engineerAToken, '/b/tasks/accept', {
      taskId: publishedA.id,
    });
    const engineerProofAsset = await ensureTaskCompletionAsset(
      prisma,
      engineerA.hospitalId,
      engineerA.id,
      'seed-repair-engineer-proof-a',
    );
    await createWithToken(
      server,
      engineerAToken,
      '/b/tasks/complete',
      buildTaskCompletionPayload(publishedA.id, engineerProofAsset),
    );
  }

  if (!(await hasTaskItemForDevice(prisma, deviceB1Id))) {
    await createWithToken(server, doctorBToken, '/b/tasks/publish', {
      items: [
        {
          deviceId: deviceB1Id,
          targetPressure: '1.5',
        },
      ],
    });
  }

  void patientA1Id;
}

async function bootstrapDictionaries(
  server: ReturnType<INestApplication['getHttpServer']>,
  systemAdminToken: string,
) {
  const dictionarySeeds = {
    PRIMARY_DISEASE: [
      '先天性脑积水',
      '梗阻性脑积水',
      '交通性脑积水',
      '出血后脑积水',
      '肿瘤相关脑积水',
      '外伤后脑积水',
      '感染后脑积水',
      '分流功能障碍',
    ],
    HYDROCEPHALUS_TYPE: [
      '交通性',
      '梗阻性',
      '高压性',
      '正常压力',
      '先天性',
      '继发性',
    ],
    SHUNT_MODE: ['VPS', 'VPLS', 'LPS', '脑室心房分流'],
    PROXIMAL_PUNCTURE_AREA: ['额角', '枕角', '三角区', '腰穿', '后角'],
    VALVE_PLACEMENT_SITE: ['耳后', '胸前', '锁骨下', '腹壁', '腰背部'],
    DISTAL_SHUNT_DIRECTION: ['腹腔', '胸腔', '心房', '腰大池'],
  } as const;

  for (const [type, labels] of Object.entries(dictionarySeeds)) {
    for (const [index, label] of labels.entries()) {
      await createWithToken(server, systemAdminToken, '/b/dictionaries', {
        type,
        label,
        sortOrder: index * 10,
        enabled: true,
      });
    }
  }
}

async function createSystemAdmin(
  server: ReturnType<INestApplication['getHttpServer']>,
) {
  const response = await request(server).post('/auth/system-admin').send({
    name: 'Seed System Admin',
    phone: E2E_SEED_CREDENTIALS[Role.SYSTEM_ADMIN].phone,
    password: E2E_SEED_PASSWORD,
    openId: OPEN_IDS.systemAdmin,
    systemAdminBootstrapKey: process.env.SYSTEM_ADMIN_BOOTSTRAP_KEY,
  });

  expectSuccessEnvelope(response, 201);
}

async function loginByCredential(
  server: ReturnType<INestApplication['getHttpServer']>,
  payload: {
    phone: string;
    password: string;
    role: Role;
    hospitalId?: number;
  },
) {
  const response = await request(server).post('/auth/login').send(payload);
  expectSuccessEnvelope(response, 201);
  return response.body.data.accessToken as string;
}

async function createWithToken(
  server: ReturnType<INestApplication['getHttpServer']>,
  token: string,
  path: string,
  payload: Record<string, unknown>,
) {
  const response = await request(server)
    .post(path)
    .set('Authorization', `Bearer ${token}`)
    .send(payload);

  expectSuccessEnvelope(response, 201);
  return response.body.data;
}

async function patchWithToken(
  server: ReturnType<INestApplication['getHttpServer']>,
  token: string,
  path: string,
  payload: Record<string, unknown>,
) {
  const response = await request(server)
    .patch(path)
    .set('Authorization', `Bearer ${token}`)
    .send(payload);

  expectSuccessEnvelope(response, 200);
  return response.body.data;
}

async function ensureTaskCompletionAsset(
  prisma: PrismaService,
  hospitalId: number,
  creatorId: number,
  key: string,
) {
  const fileName = `${key}.webp`;
  const storagePath = `e2e/${fileName}`;

  return prisma.uploadAsset.upsert({
    where: { storagePath },
    update: {},
    create: {
      hospitalId,
      creatorId,
      type: UploadAssetType.IMAGE,
      originalName: fileName,
      fileName,
      storagePath,
      url: `/uploads/e2e/${fileName}`,
      mimeType: 'image/webp',
      fileSize: 1024,
    },
    select: {
      id: true,
      type: true,
      url: true,
      originalName: true,
      fileName: true,
    },
  });
}

function buildTaskCompletionPayload(
  taskId: number,
  asset: {
    id: number;
    type: UploadAssetType;
    url: string;
    originalName: string;
    fileName: string;
  },
) {
  return {
    taskId,
    completionMaterials: [
      {
        assetId: asset.id,
        type: asset.type,
        url: asset.url,
        name: asset.originalName || asset.fileName,
      },
    ],
  };
}

async function requireUserScope(
  prisma: PrismaService,
  openId: string,
): Promise<SeedUserScope> {
  const user = await prisma.user.findFirst({
    where: { openId },
    select: {
      id: true,
      hospitalId: true,
      departmentId: true,
      groupId: true,
    },
  });
  if (!user) {
    throw new NotFoundException(`Seed user not found: ${openId}`);
  }
  return user;
}

async function requireCatalogId(
  prisma: PrismaService,
  modelCode: string,
): Promise<number> {
  const catalog = await prisma.implantCatalog.findFirst({
    where: { modelCode },
    select: { id: true },
  });
  if (!catalog) {
    throw new NotFoundException(`Seed catalog not found: ${modelCode}`);
  }
  return catalog.id;
}

async function findPatientId(
  prisma: PrismaService,
  hospitalId: number,
  phone: string,
  idCard: string,
) {
  const patient = await prisma.patient.findFirst({
    where: { hospitalId, phone, idCard },
    select: { id: true },
  });
  return patient?.id ?? null;
}

async function hasTaskItemForDevice(prisma: PrismaService, deviceId: number) {
  const taskItem = await prisma.taskItem.findFirst({
    where: { deviceId },
    select: { id: true },
  });
  return Boolean(taskItem);
}

async function ensureCatalogViaApi(
  prisma: PrismaService,
  server: ReturnType<INestApplication['getHttpServer']>,
  systemAdminToken: string,
  payload: {
    modelCode: string;
    manufacturer: string;
    name: string;
    isValve: boolean;
    pressureLevels: string[];
    notes: string;
  },
) {
  const existing = await prisma.implantCatalog.findFirst({
    where: { modelCode: payload.modelCode },
    select: { id: true },
  });
  if (existing) {
    return existing;
  }

  return createWithToken(
    server,
    systemAdminToken,
    '/b/devices/catalogs',
    payload,
  );
}

async function requireDeviceId(
  prisma: PrismaService,
  implantNotes: string,
): Promise<number> {
  const device = await prisma.device.findFirst({
    where: { implantNotes },
    select: { id: true },
  });
  if (!device) {
    throw new NotFoundException(`Seed device not found: ${implantNotes}`);
  }
  return device.id;
}

async function requirePatientId(
  prisma: PrismaService,
  hospitalId: number,
  phone: string,
  idCard: string,
): Promise<number> {
  const patient = await prisma.patient.findFirst({
    where: { hospitalId, phone, idCard },
    select: { id: true },
  });
  if (!patient) {
    throw new NotFoundException(`Seed patient not found: ${phone}/${idCard}`);
  }
  return patient.id;
}

export async function loadSeedFixtures(
  prisma: PrismaService,
): Promise<E2ESeedFixtures> {
  const systemAdmin = await requireUserScope(prisma, OPEN_IDS.systemAdmin);
  const hospitalAdminA = await requireUserScope(
    prisma,
    OPEN_IDS.hospitalAdminA,
  );
  const directorA = await requireUserScope(prisma, OPEN_IDS.directorA);
  const leaderA = await requireUserScope(prisma, OPEN_IDS.leaderA);
  const doctorA = await requireUserScope(prisma, OPEN_IDS.doctorA);
  const doctorA2 = await requireUserScope(prisma, OPEN_IDS.doctorA2);
  const doctorA3 = await requireUserScope(prisma, OPEN_IDS.doctorA3);
  const doctorB = await requireUserScope(prisma, OPEN_IDS.doctorB);
  const engineerA = await requireUserScope(prisma, OPEN_IDS.engineerA);
  const engineerB = await requireUserScope(prisma, OPEN_IDS.engineerB);

  const hospitalAId = hospitalAdminA.hospitalId;
  const hospitalBId = doctorB.hospitalId;
  const departmentA1Id = doctorA.departmentId;
  const departmentA2Id = doctorA3.departmentId;
  const departmentB1Id = doctorB.departmentId;
  const groupA1Id = doctorA.groupId;
  const groupA2Id = doctorA3.groupId;
  const groupB1Id = doctorB.groupId;

  if (
    hospitalAId == null ||
    hospitalBId == null ||
    departmentA1Id == null ||
    departmentA2Id == null ||
    departmentB1Id == null ||
    groupA1Id == null ||
    groupA2Id == null ||
    groupB1Id == null
  ) {
    throw new NotFoundException('Seed user scope is incomplete');
  }

  return {
    hospitalAId,
    hospitalBId,
    departmentA1Id,
    departmentA2Id,
    departmentB1Id,
    groupA1Id,
    groupA2Id,
    groupB1Id,
    catalogs: {
      adjustableValveId: await requireCatalogId(
        prisma,
        FIXTURE_NAMES.adjustableCatalog,
      ),
      highPressureValveId: await requireCatalogId(
        prisma,
        FIXTURE_NAMES.highPressureCatalog,
      ),
    },
    users: {
      systemAdminId: systemAdmin.id,
      hospitalAdminAId: hospitalAdminA.id,
      directorAId: directorA.id,
      leaderAId: leaderA.id,
      doctorAId: doctorA.id,
      doctorA2Id: doctorA2.id,
      doctorA3Id: doctorA3.id,
      doctorBId: doctorB.id,
      engineerAId: engineerA.id,
      engineerBId: engineerB.id,
    },
    patients: {
      patientA1Id: await requirePatientId(
        prisma,
        hospitalAId,
        SHARED_PATIENT_IDENTITY.phone,
        SHARED_PATIENT_IDENTITY.idCard,
      ),
      patientA2Id: await requirePatientId(
        prisma,
        hospitalAId,
        '13800002002',
        '110101199002020022',
      ),
      patientA3Id: await requirePatientId(
        prisma,
        hospitalAId,
        '13800002003',
        '110101199003030033',
      ),
      patientB1Id: await requirePatientId(
        prisma,
        hospitalBId,
        SHARED_PATIENT_IDENTITY.phone,
        SHARED_PATIENT_IDENTITY.idCard,
      ),
    },
    devices: {
      deviceA1Id: await requireDeviceId(prisma, 'Seed A1 当前在用设备'),
      deviceA2Id: await requireDeviceId(prisma, 'Seed A2 当前在用设备'),
      deviceA3Id: await requireDeviceId(prisma, 'Seed A3 当前在用设备'),
      deviceA4InactiveId: await requireDeviceId(prisma, 'Seed A1 弃用历史设备'),
      deviceB1Id: await requireDeviceId(prisma, 'Seed B1 当前在用设备'),
    },
  };
}
