import { formatDepartment } from '@/composables/sepsisFormat'

export const KNOWN_DEPARTMENTS = ['ICU', 'GENERAL_MEDICINE', 'SURGERY']

const DEPARTMENT_KEY_MAP = {
  ICU: 'ICU',
  Icu: 'ICU',
  GENERAL_MEDICINE: 'GENERAL_MEDICINE',
  GeneralMedicine: 'GENERAL_MEDICINE',
  SURGERY: 'SURGERY',
  Surgery: 'SURGERY',
  EMERGENCY: 'EMERGENCY',
  Emergency: 'EMERGENCY',
  CARDIOLOGY: 'CARDIOLOGY',
  Cardiology: 'CARDIOLOGY',
  PEDIATRICS: 'PEDIATRICS',
  Pediatrics: 'PEDIATRICS',
}

export function normalizeDepartmentKey(department) {
  if (!department) return 'UNKNOWN'
  return DEPARTMENT_KEY_MAP[department] ?? department
}

export function departmentFilterValue(key) {
  if (KNOWN_DEPARTMENTS.includes(key)) return key
  return key
}

export function news2AcuityTier(score) {
  const value = score ?? 0
  if (value >= 7) return 'high'
  if (value >= 5) return 'medium'
  return 'low'
}

function emptyBucket(key) {
  return {
    key,
    label: formatDepartment(key),
    filterValue: departmentFilterValue(key),
    patientCount: 0,
    acuity: { low: 0, medium: 0, high: 0 },
    activeBundleCount: 0,
    openAlertCount: 0,
    news2Sum: 0,
    news2Count: 0,
    alertVolume: 0,
  }
}

function isActiveBundle(encounter) {
  return Boolean(encounter.sepsisActive || encounter.sepsisBundleStatus === 'IN_PROGRESS')
}

export function aggregateByDepartment(encounters, alertSummaryRows = []) {
  const alertByDept = new Map()
  for (const row of alertSummaryRows) {
    const key = normalizeDepartmentKey(row.department)
    alertByDept.set(key, (alertByDept.get(key) ?? 0) + Number(row.total ?? 0))
  }

  const buckets = new Map()
  for (const key of KNOWN_DEPARTMENTS) {
    buckets.set(key, emptyBucket(key))
  }

  function ensure(key) {
    if (!buckets.has(key)) {
      buckets.set(key, emptyBucket(key))
    }
    const bucket = buckets.get(key)
    bucket.alertVolume = alertByDept.get(key) ?? bucket.alertVolume
    return bucket
  }

  for (const encounter of encounters) {
    const key = normalizeDepartmentKey(encounter.department)
    const bucket = ensure(key)
    bucket.patientCount += 1

    const tier = news2AcuityTier(encounter.news2Score)
    bucket.acuity[tier] += 1

    if (isActiveBundle(encounter)) bucket.activeBundleCount += 1
    bucket.openAlertCount += encounter.openAlertCount ?? 0

    if (encounter.news2Score != null) {
      bucket.news2Sum += encounter.news2Score
      bucket.news2Count += 1
    }
  }

  for (const [key, total] of alertByDept) {
    ensure(key).alertVolume = total
  }

  return [...buckets.values()]
    .map(bucket => ({
      ...bucket,
      averageNews2:
        bucket.news2Count > 0
          ? Math.round((bucket.news2Sum / bucket.news2Count) * 10) / 10
          : null,
    }))
    .sort((a, b) => {
      const knownA = KNOWN_DEPARTMENTS.indexOf(a.key)
      const knownB = KNOWN_DEPARTMENTS.indexOf(b.key)
      if (knownA !== -1 || knownB !== -1) {
        if (knownA === -1) return 1
        if (knownB === -1) return -1
        return knownA - knownB
      }
      return b.patientCount - a.patientCount
    })
}

export function summarizeDepartments(departments) {
  return departments.reduce(
    (totals, dept) => ({
      patientCount: totals.patientCount + dept.patientCount,
      criticalCount: totals.criticalCount + dept.acuity.high,
      activeBundleCount: totals.activeBundleCount + dept.activeBundleCount,
      openAlertCount: totals.openAlertCount + dept.openAlertCount,
    }),
    { patientCount: 0, criticalCount: 0, activeBundleCount: 0, openAlertCount: 0 },
  )
}
