import {
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { PrismaService } from '../../prisma.service.js';
import { MESSAGES } from '../../common/messages.js';

/**
 * C 端患者服务：承载家属跨院生命周期聚合查询。
 */
@Injectable()
export class CPatientsService {
  constructor(private readonly prisma: PrismaService) {}

  /**
   * C 端查询：按当前家属账号绑定手机号跨院聚合患者生命周期记录。
   */
  async getFamilyLifecycleByAccount(accountId: number) {
    const account = await this.prisma.familyMiniAppAccount.findUnique({
      where: { id: accountId },
      select: {
        id: true,
        phone: true,
      },
    });
    if (!account) {
      throw new NotFoundException(MESSAGES.AUTH.FAMILY_ACCOUNT_NOT_FOUND);
    }

    const patients = await this.prisma.patient.findMany({
      where: {
        phone: account.phone,
      },
      include: {
        hospital: { select: { id: true, name: true } },
        surgeries: {
          include: {
            devices: {
              include: {
                implantCatalog: {
                  select: {
                    id: true,
                    modelCode: true,
                    manufacturer: true,
                    name: true,
                    isValve: true,
                    pressureLevels: true,
                    isPressureAdjustable: true,
                    notes: true,
                  },
                },
              },
            },
          },
          orderBy: { surgeryDate: 'desc' },
        },
        devices: {
          include: {
            surgery: {
              select: {
                id: true,
                surgeryDate: true,
                surgeryName: true,
              },
            },
            implantCatalog: {
              select: {
                id: true,
                modelCode: true,
                manufacturer: true,
                name: true,
                isValve: true,
                pressureLevels: true,
                isPressureAdjustable: true,
                notes: true,
              },
            },
            taskItems: {
              include: {
                task: true,
              },
            },
          },
        },
      },
    });
    if (patients.length === 0) {
      throw new NotFoundException(MESSAGES.PATIENT.LIFE_CYCLE_NOT_FOUND);
    }

    const lifecycle = patients
      .flatMap((patient) => {
        const surgeryEvents = patient.surgeries.map(
          (surgery, index, surgeries) => ({
            eventType: 'SURGERY',
            occurredAt: surgery.surgeryDate,
            hospital: patient.hospital,
            patient: {
              id: this.toJsonNumber(patient.id),
              name: patient.name,
              inpatientNo: patient.inpatientNo,
              projectName: patient.projectName,
            },
            surgery: {
              id: this.toJsonNumber(surgery.id),
              surgeryDate: surgery.surgeryDate,
              surgeryName: surgery.surgeryName,
              surgeonName: surgery.surgeonName,
              primaryDisease: surgery.primaryDisease,
              hydrocephalusTypes: surgery.hydrocephalusTypes,
              previousShuntSurgeryDate: surgery.previousShuntSurgeryDate,
              shuntSurgeryCount: surgeries.length - index,
            },
            devices: surgery.devices.map((device) => ({
              id: this.toJsonNumber(device.id),
              status: device.status,
              isAbandoned: device.isAbandoned,
              currentPressure: device.currentPressure,
              initialPressure: device.initialPressure,
              implantModel: device.implantModel,
              implantManufacturer: device.implantManufacturer,
              implantName: device.implantName,
              isValve: device.isValve,
              isPressureAdjustable: device.isPressureAdjustable,
              shuntMode: device.shuntMode,
              distalShuntDirection: device.distalShuntDirection,
              proximalPunctureAreas: device.proximalPunctureAreas,
              valvePlacementSites: device.valvePlacementSites,
              implantCatalog: device.implantCatalog,
            })),
          }),
        );

        const taskEvents = patient.devices.flatMap((device) =>
          device.taskItems.flatMap((taskItem) => {
            // 容错：若存在脏数据导致 task 为空，直接跳过该条明细，避免接口 500。
            if (!taskItem.task) {
              return [];
            }

            const task = taskItem.task;
            return [
              {
                eventType: 'TASK_PRESSURE_ADJUSTMENT',
                occurredAt: task.createdAt,
                hospital: patient.hospital,
                patient: {
                  id: this.toJsonNumber(patient.id),
                  name: patient.name,
                  inpatientNo: patient.inpatientNo,
                  projectName: patient.projectName,
                },
                device: {
                  id: this.toJsonNumber(device.id),
                  status: device.status,
                  isAbandoned: device.isAbandoned,
                  currentPressure: device.currentPressure,
                  implantModel: device.implantModel,
                  implantManufacturer: device.implantManufacturer,
                  implantName: device.implantName,
                  isValve: device.isValve,
                  isPressureAdjustable: device.isPressureAdjustable,
                },
                surgery: device.surgery
                  ? {
                      id: this.toJsonNumber(device.surgery.id),
                      surgeryDate: device.surgery.surgeryDate,
                      surgeryName: device.surgery.surgeryName,
                    }
                  : null,
                task: {
                  id: this.toJsonNumber(task.id),
                  status: task.status,
                  createdAt: task.createdAt,
                },
                taskItem: {
                  id: this.toJsonNumber(taskItem.id),
                  oldPressure: taskItem.oldPressure,
                  targetPressure: taskItem.targetPressure,
                },
              },
            ];
          }),
        );

        return [...surgeryEvents, ...taskEvents];
      })
      .sort(
        (a, b) =>
          new Date(b.occurredAt).getTime() - new Date(a.occurredAt).getTime(),
      );

    return {
      // 前端详情弹窗和现有 E2E 都依赖这两个回显字段。
      phone: account.phone,
      patientCount: patients.length,
      lifecycle,
    };
  }

  /**
   * 统一将 number/bigint 转为可 JSON 序列化的 number，避免 BigInt 序列化异常。
   */
  private toJsonNumber(value: number | bigint | null | undefined) {
    if (value == null) {
      return null;
    }
    return typeof value === 'bigint' ? Number(value) : value;
  }
}
