/**
 * computeTiles — derives renderable tile info from raw assignment data.
 *
 * A "tile" is a consecutive span of same-type assignments for one consultant
 * rendered as a single colored block in the planning grid.
 */

import type { Consultant, AppointmentType, PlanningProject, Assignment } from '@/lib/planning-types'
import { formatDateKey } from '@/lib/planning-config'

export interface TileInfo {
  id:               string
  assignments:      Assignment[]
  startColumnIndex: number
  spanDays:         number
  color:            string
  label:            string
}

export function computeTiles(
  consultant:    Consultant,
  days:          Date[],
  assignmentMap: Map<string, Assignment[]>,
  typeMap:       Map<string, AppointmentType>,
  projectMap:    Map<string, PlanningProject>,
): TileInfo[] {
  const tiles: TileInfo[] = []
  let di = 0

  while (di < days.length) {
    const dk      = formatDateKey(days[di])
    const cellKey = `${consultant.id}:${dk}`
    const list    = assignmentMap.get(cellKey) ?? []

    if (list.length === 0) { di++; continue }

    // Conflict: multiple assignments on same day — render first only
    if (list.length > 1) {
      const a    = list[0]
      const type = typeMap.get(a.appointment_type_id)
      const proj = a.project_id ? projectMap.get(a.project_id) : undefined
      tiles.push({
        id:               a.id,
        assignments:      [a],
        startColumnIndex: di,
        spanDays:         1,
        color:            type?.color ?? '#E5E5E5',
        label:            proj ? proj.code : (type?.code ?? type?.label?.slice(0, 8) ?? '—'),
      })
      di++
      continue
    }

    // Single assignment — find consecutive span of same type + project
    const base = list[0]
    let span = 1

    while (di + span < days.length) {
      const nextKey  = `${consultant.id}:${formatDateKey(days[di + span])}`
      const nextList = assignmentMap.get(nextKey) ?? []
      if (nextList.length !== 1) break
      const next = nextList[0]
      if (next.appointment_type_id !== base.appointment_type_id) break
      if (next.project_id !== base.project_id) break
      span++
    }

    const spanAssignments: Assignment[] = []
    for (let j = 0; j < span; j++) {
      spanAssignments.push(
        (assignmentMap.get(`${consultant.id}:${formatDateKey(days[di + j])}`) ?? [])[0],
      )
    }

    const type  = typeMap.get(base.appointment_type_id)
    const proj  = base.project_id ? projectMap.get(base.project_id) : undefined
    const label = proj
      ? (span >= 3 ? `${proj.code} ${proj.name}` : proj.code)
      : (type?.code ?? type?.label?.slice(0, 8) ?? '—')

    tiles.push({
      id:               base.id,
      assignments:      spanAssignments,
      startColumnIndex: di,
      spanDays:         span,
      color:            type?.color ?? '#E5E5E5',
      label,
    })

    di += span
  }

  return tiles
}

// ── Cell background color ──────────────────────────────────────────────────────

import type { CalendarColors } from '@/lib/planning-settings'
import { isToday } from '@/lib/planning-config'

export function hexToRgba(hex: string, alpha: number): string {
  const r = parseInt(hex.slice(1, 3), 16)
  const g = parseInt(hex.slice(3, 5), 16)
  const b = parseInt(hex.slice(5, 7), 16)
  return `rgba(${r}, ${g}, ${b}, ${alpha})`
}

export function getCellBg(
  day:            Date,
  dk:             string,
  holidayMap:     Map<string, string>,
  rowHighlighted: boolean,
  weekSelected:   boolean,
  colors:         CalendarColors,
): string {
  const selColor = colors.selectionHighlightColor   ?? '#3B82F6'
  const selOp    = colors.selectionHighlightOpacity ?? 8

  if (rowHighlighted && weekSelected) return hexToRgba(selColor, (selOp + 8) / 100)
  if (rowHighlighted)                 return hexToRgba(selColor, (selOp + 4) / 100)
  if (weekSelected)                   return hexToRgba(selColor, selOp / 100)

  if (isToday(day))             return colors.today
  if (holidayMap.has(dk))       return colors.holiday
  if (day.getDay() === 0 || day.getDay() === 6) return colors.weekend
  return colors.weekday
}
