export const CONTRACT_NATURES = ['CDI', 'CDD', 'INTERIM'] as const

export type ContractNature = (typeof CONTRACT_NATURES)[number]

export const contractNatureLabel = (value?: ContractNature) => {
  if (value === 'CDD') return 'CDD'
  if (value === 'INTERIM') return 'Intérim'
  return 'CDI'
}

export const showsContractEndDate = (nature: ContractNature) => {
  return nature === 'CDD' || nature === 'INTERIM'
}

export const requiresContractEndDate = (nature: ContractNature) => {
  return nature === 'CDD' || nature === 'INTERIM'
}

export const isContractNature = (value: string): value is ContractNature => {
  return (CONTRACT_NATURES as readonly string[]).includes(value)
}

/**
 * Whether a contract + nature pair requires the per-day schedule (workDaysHours).
 * Mirrors EmployeeContractPeriodValidator::assertWorkDaysHours on the backend.
 */
export const requiresWorkDaysHours = (
  contract: { trackingMode?: string | null; weeklyHours?: number | null } | null | undefined,
  nature: ContractNature
): boolean => {
  if (!contract) return false
  if (nature === 'INTERIM') return false
  if (contract.trackingMode === 'PRESENCE') return false
  if (contract.weeklyHours === 35 || contract.weeklyHours === 39) return false
  return true
}

const DAY_SHORT_LABELS: Record<number, string> = { 1: 'Lun', 2: 'Mar', 3: 'Mer', 4: 'Jeu', 5: 'Ven' }

const DAY_TINY_LABELS: Record<number, string> = { 1: 'LU', 2: 'MA', 3: 'ME', 4: 'JE', 5: 'VE' }

/**
 * Very compact worked-days summary for the day view header, e.g. "LU,VE".
 * Lists the iso days actually worked (minutes > 0), uppercase 2-letter, comma-separated.
 * Returns null when the schedule is empty/unset (non-CUSTOM contracts have no schedule).
 */
export const formatWorkedDaysShort = (
  workDaysHours: Record<number, number> | null | undefined
): string | null => {
  if (!workDaysHours) return null
  const days = Object.entries(workDaysHours)
    .map(([iso, minutes]) => [Number(iso), Number(minutes)] as const)
    .filter(([iso, minutes]) => iso >= 1 && iso <= 5 && minutes > 0)
    .sort(([a], [b]) => a - b)
    .map(([iso]) => DAY_TINY_LABELS[iso])
  if (days.length === 0) return null
  return days.join(',')
}

/**
 * Compact human-readable summary of a per-day schedule, e.g. "Lun 2h, Jeu 2h".
 * Returns null when the schedule is empty/unset.
 */
export const formatWorkDaysHoursSummary = (
  workDaysHours: Record<number, number> | null | undefined
): string | null => {
  if (!workDaysHours) return null
  const entries = Object.entries(workDaysHours)
    .map(([iso, minutes]) => [Number(iso), Number(minutes)] as const)
    .filter(([iso, minutes]) => iso >= 1 && iso <= 5 && minutes > 0)
    .sort(([a], [b]) => a - b)
  if (entries.length === 0) return null
  return entries
    .map(([iso, minutes]) => {
      const h = Math.floor(minutes / 60)
      const m = minutes % 60
      const suffix = m === 0 ? `${h}h` : `${h}h${String(m).padStart(2, '0')}`
      return `${DAY_SHORT_LABELS[iso]} ${suffix}`
    })
    .join(', ')
}
