import { z } from 'zod'

const isoDateTime = z
  .string()
  .min(1, 'Tanggal / waktu wajib diisi')
  .refine((val) => {
    const date = new Date(val)
    return !isNaN(date.getTime())
  }, 'Format tanggal / waktu tidak valid')

const positiveInt = z.coerce.number().int().nonnegative()

const OperatorTeamSchema = z.object({
  dpjpId: z.coerce
    .number({
      invalid_type_error: 'Silahkan pilih dpjp terlebih dahulu',
    })
    .int(),
  operatorName: z.string({
    required_error: 'Masukkan nama operator',
  }),
  assistantOperatorName: z.string({
    required_error: 'Masukkan nama asisten operator',
  }),
  instrumentNurseName: z.string({
    required_error: 'Masukkan nama instrumentir',
  }),

  surgeryDate: isoDateTime,
  actionDiagnosis: z.string(),

  postSurgeryNurseId: z.number().int().optional().nullable(),
})

const ProcedureSchema = z.object({
  id: z.number().int(),
  name: z.string().min(1),
  code: z.string().min(1),
})

const OperationExecutionSchema = z.object({
  surgeryType: z.enum(['kecil', 'sedang', 'besar', 'khusus'], { required_error: 'Silahkan pilih jenis operasi' }),
  billingCode: z.string({
    required_error: 'Silahkan pilih kode billing',
  }),
  operationSystem: z.enum(['khusus', 'cito', 'efektif', 'urgent'], { required_error: 'Silahkan pilih sistem operasi' }),

  operationStartAt: isoDateTime,
  operationEndAt: isoDateTime,

  anesthesiaStartAt: isoDateTime,
  anesthesiaEndAt: isoDateTime,

  surgeryCleanType: z.enum(['bersih', 'bersih_terkontaminasi', 'terkontaminasi', 'kotor']).optional(),
  surgeryNumber: z.enum(['first', 'retry']).optional(),

  birthPlaceNote: z.string().optional(),
  personWeight: positiveInt.optional(),
  birthCondition: z.string().optional(),

  operationDescription: z.string({
    required_error: 'Mohon lengkapi uraian operasi',
  }),

  bleedingAmountCc: positiveInt.optional(),

  birthRemark: z.enum(['lahir_hidup', 'lahir_mati']).optional(),
})

const BloodInputSchema = z
  .object({
    type: z.enum(['prc', 'wb', 'ffp', 'tc']),
    amount: z.object({
      prc: z.coerce.number().optional(),
      wb: z.coerce.number().optional(),
      ffp: z.coerce.number().optional(),
      tc: z.coerce.number().optional(),
    }),
  })
  .transform((val) => ({
    type: val.type,
    amount: Object.fromEntries(
      ['prc', 'wb', 'ffp', 'tc'].map((k) => [k, val.type === k ? (val.amount[k] ?? null) : null]),
    ),
  }))

const ImplantSchema = z.object({
  brand: z.string().optional(),
  name: z.string().optional(),
  stickerNumber: z.string().optional(),
  companionName: z.string().optional(),
})

const SpecimenSchema = z.object({
  destination: z.string({
    required_error: 'Silahkan pilih specimen',
  }),
})

const TissueNoteSchema = z.object({
  note: z
    .string()
    .trim()
    .transform((val) => (val === '' ? undefined : val))
    .optional(),
})

export const ActionReportSchema = z.object({
  operatorTeam: OperatorTeamSchema,
  procedures: z.array(ProcedureSchema).min(1, { message: 'Silahkan pilih prosedur' }),

  operationExecution: OperationExecutionSchema,

  bloodInput: BloodInputSchema.optional(),
  implant: ImplantSchema.optional(),
  specimen: SpecimenSchema.optional(),

  tissueNotes: z.array(TissueNoteSchema).optional(),
})

export type ActionReportFormData = z.infer<typeof ActionReportSchema>
