export const TYPE_LABELS: Record<string, string> = {
  lsc_workshop: 'LSC Workshop',
  kapa_workshop: 'Kapazitäts-Workshop',
  fabrikanalyse: 'Fabrikanalyse',
  sonderauftrag: 'Sonderauftrag',
  zdsc_campus: 'ZDSC Campus',
  '360_workshop': '360° Workshop',
  praeventionsteam: 'Präventionsteam',
  process_audit: 'Process Audit',
  qualifizierung: 'Qualifizierung',
  investplausibilisierung: 'Investplausibilisierung',
}

/**
 * Format multiple project type codes as display labels, joined by separator.
 * Empty array returns empty string.
 */
export function formatTypeLabels(codes: string[], separator = ', '): string {
  return codes.map((c) => TYPE_LABELS[c] ?? c).join(separator)
}

/**
 * Extract project type codes from a project's junction assignments.
 * Tolerates undefined/null junction.
 */
export function getTypeCodes(project: {
  project_type_assignments?: Array<{ project_type_code: string }> | null
}): string[] {
  return (project.project_type_assignments ?? []).map((a) => a.project_type_code)
}

/**
 * Stable display priority for primary-type fallback.
 * NEVER rely on Postgres row order — use this list when a single type is required.
 */
export const TYPE_PRIORITY = [
  'lsc_workshop',
  'kapa_workshop',
  'fabrikanalyse',
  'investplausibilisierung',
  'praeventionsteam',
  '360_workshop',
  'sonderauftrag',
  'zdsc_campus',
] as const

/**
 * Pick a stable primary type code from a list of codes or a project-with-junction.
 * Returns null when no codes are present.
 */
export function getPrimaryTypeCode(
  input:
    | string[]
    | { project_type_assignments?: Array<{ project_type_code: string }> | null },
): string | null {
  const codes = Array.isArray(input) ? input : getTypeCodes(input)
  if (codes.length === 0) return null
  for (const code of TYPE_PRIORITY) {
    if (codes.includes(code)) return code
  }
  return codes[0] ?? null
}

/**
 * Convenience predicate: does the project carry the given type code?
 */
export function hasTypeCode(
  project: { project_type_assignments?: Array<{ project_type_code: string }> | null },
  code: string,
): boolean {
  return getTypeCodes(project).includes(code)
}

/**
 * Resolve the primary type code's master ID via a Map<code, {id}>.
 * Used by API v1 to keep emitting a compatibility `project_type_id` derived
 * from the junction's primary type, instead of reading projects.project_type_id.
 */
export function getPrimaryProjectTypeId(
  project: { project_type_assignments?: Array<{ project_type_code: string }> | null },
  projectTypesByCode: Map<string, { id: string }>,
): string | null {
  const primaryCode = getPrimaryTypeCode(project)
  if (!primaryCode) return null
  return projectTypesByCode.get(primaryCode)?.id ?? null
}

/**
 * Effective type codes for a project, with optional parent fallback.
 * Rule: own assignments win; if the project has none, inherit from parent.
 * Used in reporting where sub-projects without own assignments should still
 * appear under the parent's type-buckets.
 */
export function getEffectiveTypeCodes(
  project: {
    project_type_assignments?: Array<{ project_type_code: string }> | null
  },
  parent?: {
    project_type_assignments?: Array<{ project_type_code: string }> | null
  } | null,
): string[] {
  const ownCodes = getTypeCodes(project)
  if (ownCodes.length > 0) return ownCodes
  return parent ? getTypeCodes(parent) : []
}
