'use client'

import { useMemo, useState, useRef, useCallback, memo } from'react'
import type { Consultant, AppointmentType, PlanningProject, Assignment } from'@/lib/planning-types'
import { WORK_MODE_COLORS, WORK_MODE_LABELS, STATUS_COLORS, STATUS_LABELS, getYearDays, formatDateKey } from'@/lib/planning-config'
import { getBavarianHolidayMap } from'@/lib/calendar/bavarian-holidays'
import { buildCapacityMap } from'@/lib/planning-capacity'
import { DEFAULT_CALENDAR_COLORS } from'@/lib/planning-settings'
import type { CalendarColors, CustomHoliday } from'@/lib/planning-settings'
import { SNAP_NAME_COL_W, SNAP_DAY_COL_W } from'@/lib/planning/grid-snap'
import { useGridInteraction } from'./hooks/use-grid-interaction'
import PlanningHeader from'./planning-header'
import PlanningRow from'./planning-row'

// ── Constants ─────────────────────────────────────────────────────────────────

const NAME_COL_W = SNAP_NAME_COL_W // 160
const DAY_COL_W = SNAP_DAY_COL_W // 40

// ── Types ─────────────────────────────────────────────────────────────────────

interface TooltipState {
 assignment: Assignment
 startDate: string
 endDate: string
 x: number
 y: number
}

interface Props {
 year: number
 consultants: Consultant[]
 assignments: Assignment[]
 appointmentTypes: AppointmentType[]
 planningProjects: PlanningProject[]
 selectionMode: boolean
 selectedIds: Set<string>
 syncStatusMap?: Record<string, string>
 highlightedIds: Set<string>
 currentConsultantId?: string
 selectedWeeks: Set<number>
 calendarColors?: CalendarColors
 customHolidays?: CustomHoliday[]
 dbHolidays?: Map<string, string>
 /** On mobile: pass a 7-day slice instead of the full month */
 daysOverride?: Date[]
 onCellClick: (consultantId: string, startDate: string, endDate: string) => void
 onCardClick: (assignment: Assignment) => void
 onCardRightClick: (assignment: Assignment, x: number, y: number) => void
 onBulkRightClick: (x: number, y: number) => void
 onTileMove: (assignments: Assignment[], newStartDate: string, newConsultantId: string) => void
 onToggleSelect: (id: string) => void
 onCtrlClickCard: (id: string) => void
 onSelectRange: (consultantId: string, startDate: string, endDate: string) => void
 onToggleHighlight: (consultantId: string) => void
 onToggleWeek: (week: number) => void
}

// ── Component ─────────────────────────────────────────────────────────────────

function PlanningGridInner({
 year, consultants, assignments, appointmentTypes, planningProjects,
 selectionMode, selectedIds, syncStatusMap = {}, highlightedIds, currentConsultantId,
 selectedWeeks, calendarColors = DEFAULT_CALENDAR_COLORS, customHolidays = [], dbHolidays,
 daysOverride,
 onCellClick, onCardClick, onCardRightClick, onBulkRightClick,
 onTileMove, onToggleSelect, onCtrlClickCard,
 onSelectRange, onToggleHighlight, onToggleWeek,
}: Props) {
 const [tooltip, setTooltip] = useState<TooltipState | null>(null)
 const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
 const tableRef = useRef<HTMLTableElement>(null)

 // ── Derived data (memoized) ───────────────────────────────────────────────

 const days = useMemo(
 () => daysOverride ?? getYearDays(year),
 [daysOverride, year],
 )

 const getDays = useCallback(() => days, [days])

 const holidayMap = useMemo(() => {
 const base = dbHolidays ?? getBavarianHolidayMap(year)
 const map = new Map(base)
 for (const h of customHolidays) map.set(h.date, h.name)
 return map
 }, [year, customHolidays, dbHolidays])

 const assignmentMap = useMemo(() => {
 const map = new Map<string, Assignment[]>()
 for (const a of assignments) {
 const key = `${a.consultant_id}:${a.date}`
 const list = map.get(key) ?? []
 list.push(a)
 map.set(key, list)
 }
 return map
 }, [assignments])

 const typeMap = useMemo(() => new Map(appointmentTypes.map((t) => [t.id, t])), [appointmentTypes])
 const projectMap = useMemo(() => new Map(planningProjects.map((p) => [p.id, p])), [planningProjects])

 const conflictCells = useMemo(() => {
 const s = new Set<string>()
 for (const [key, list] of assignmentMap) {
 if (list.length >= 2) s.add(key)
 }
 return s
 }, [assignmentMap])

 const capacityMap = useMemo(
 () => buildCapacityMap(assignments, consultants),
 [assignments, consultants],
 )

 // ── Drag-select interaction ───────────────────────────────────────────────

 const { dragSelect, startCellDrag } = useGridInteraction({
 tableRef,
 getDays,
 onCellClick,
 onSelectRange,
 })

 // ── Tooltip ───────────────────────────────────────────────────────────────

 const handleTooltipShow = useCallback((
 assignment: Assignment,
 e: React.MouseEvent<HTMLDivElement>,
 startDate: string = assignment.date,
 endDate: string = assignment.date,
 ) => {
 if (selectionMode) return
 if (timerRef.current) clearTimeout(timerRef.current)
 const rect = e.currentTarget.getBoundingClientRect()
 timerRef.current = setTimeout(() => {
 let x = rect.right + 10
 let y = rect.top
 if (x + 288 > window.innerWidth) x = rect.left - 298
 if (y + 220 > window.innerHeight) y = Math.max(8, window.innerHeight - 228)
 setTooltip({ assignment, startDate, endDate, x, y })
 }, 150)
 }, [selectionMode])

 const handleTooltipHide = useCallback(() => {
 if (timerRef.current) clearTimeout(timerRef.current)
 setTooltip(null)
 }, [])

 // ── Empty state ───────────────────────────────────────────────────────────

 if (consultants.length === 0) {
 return (
 <div className="flex flex-col items-center justify-center py-24 gap-2 text-muted-foreground">
 <p className="font-medium">Keine Mitarbeiter gefunden.</p>
 <p className="text-sm">Lege zuerst Consultants in der Datenbank an.</p>
 </div>
 )
 }

 // ── Render ────────────────────────────────────────────────────────────────

 return (
 <div>
 <table ref={tableRef} className="border-separate border-spacing-0 bg-card text-[12px] table-fixed">
 <colgroup>
 <col style={{ width: NAME_COL_W, minWidth: NAME_COL_W }} />
 {days.map((d) => (
 <col key={formatDateKey(d)} style={{ width: DAY_COL_W, minWidth: DAY_COL_W, maxWidth: DAY_COL_W }} />
 ))}
 </colgroup>

 <PlanningHeader
 days={days}
 selectedWeeks={selectedWeeks}
 calendarColors={calendarColors}
 holidayMap={holidayMap}
 onToggleWeek={onToggleWeek}
 />

 <tbody>
 {consultants.map((consultant, ci) => (
 <PlanningRow
 key={consultant.id}
 consultant={consultant}
 rowIndex={ci}
 days={days}
 assignmentMap={assignmentMap}
 typeMap={typeMap}
 projectMap={projectMap}
 capacityMap={capacityMap}
 conflictCells={conflictCells}
 holidayMap={holidayMap}
 calendarColors={calendarColors}
 selectedWeeks={selectedWeeks}
 selectionMode={selectionMode}
 selectedIds={selectedIds}
 syncStatusMap={syncStatusMap}
 isHighlighted={highlightedIds.has(consultant.id)}
 isCurrentUser={consultant.id === currentConsultantId}
 dragSelect={dragSelect}
 onTileMove={onTileMove}
 onCardClick={onCardClick}
 onCardRightClick={onCardRightClick}
 onCtrlClickCard={onCtrlClickCard}
 onToggleSelect={onToggleSelect}
 onBulkRightClick={onBulkRightClick}
 onToggleHighlight={onToggleHighlight}
 onTooltipShow={handleTooltipShow}
 onTooltipHide={handleTooltipHide}
 onCellMouseDown={startCellDrag}
 />
 ))}
 </tbody>
 </table>

 {tooltip && !selectionMode && (
 <AssignmentTooltip
 assignment={tooltip.assignment}
 startDate={tooltip.startDate}
 endDate={tooltip.endDate}
 appointmentType={typeMap.get(tooltip.assignment.appointment_type_id)}
 project={tooltip.assignment.project_id ? projectMap.get(tooltip.assignment.project_id) : undefined}
 consultant={consultants.find((c) => c.id === tooltip.assignment.consultant_id)}
 x={tooltip.x}
 y={tooltip.y}
 />
 )}
 </div>
 )
}

export default memo(PlanningGridInner)

// ── Tooltip ───────────────────────────────────────────────────────────────────

const WORK_MODE_ABBREV: Record<string, string> = {
 homeoffice:'HO',
 onsite:'VO',
 remote:'RE',
}

function AssignmentTooltip({
 assignment, startDate, endDate, appointmentType, project, consultant, x, y,
}: {
 assignment: Assignment
 startDate: string
 endDate: string
 appointmentType: AppointmentType | undefined
 project: PlanningProject | undefined
 consultant: Consultant | undefined
 x: number
 y: number
}) {
 const fmtShort = (iso: string) => {
 const d = new Date(iso +'T00:00:00')
 return d.toLocaleDateString('de-DE', { day:'2-digit', month:'2-digit', year:'numeric'})
 }
 // Always render a Zeitraum range — single days show "26.05.2026 — 26.05.2026"
 // so the format is consistent with multi-day spans.
 const dateFormatted = `${fmtShort(startDate)} — ${fmtShort(endDate)}`

 return (
 <div
 className="fixed z-50 bg-card border border-muted rounded-lg shadow-lg p-3 w-72 pointer-events-none"
 style={{ left: x, top: y }}
 >
 <div className="flex items-center justify-between gap-2 mb-2">
 <div className="flex items-center gap-2">
 {appointmentType && (
 <span className="w-3 h-3 rounded-sm shrink-0"style={{ backgroundColor: appointmentType.color }} />
 )}
 <span className="font-semibold text-[12px] text-foreground">{appointmentType?.label ??'—'}</span>
 </div>
 <span
 className="text-[10px] font-bold px-1.5 py-0.5 rounded text-white shrink-0"
 style={{ backgroundColor: WORK_MODE_COLORS[assignment.work_mode] }}
 title={WORK_MODE_LABELS[assignment.work_mode]}
 >
 {WORK_MODE_ABBREV[assignment.work_mode]}
 </span>
 </div>

 <div className="space-y-1 text-[11px]">
 <div className="flex items-center justify-between">
 <span className="text-muted-foreground">Zeitraum</span>
 <span className="font-medium text-foreground">{dateFormatted}</span>
 </div>
 {project && (
 <div className="flex items-center justify-between gap-2">
 <span className="text-muted-foreground shrink-0">Projekt</span>
 <span className="text-foreground text-right truncate">
 <span className="font-mono bg-muted px-1 py-0.5 rounded text-[10px] mr-1">{project.code}</span>
 {project.name}
 </span>
 </div>
 )}
 {consultant && (
 <div className="flex items-center justify-between gap-2">
 <span className="text-muted-foreground shrink-0">Mitarbeiter</span>
 <span className="text-foreground">{consultant.display_name}</span>
 </div>
 )}
 {assignment.supplier_name && (
 <div className="flex items-center justify-between gap-2">
 <span className="text-muted-foreground shrink-0">Reise / Kunde</span>
 <span className="text-foreground text-right">{assignment.supplier_name}</span>
 </div>
 )}
 {assignment.location_label && (
 <div className="flex items-center justify-between gap-2">
 <span className="text-muted-foreground shrink-0">Arbeitsort</span>
 <span className="text-foreground text-right">{assignment.location_label}</span>
 </div>
 )}
 {assignment.description && (
 <div className="text-foreground italic pt-0.5">{assignment.description}</div>
 )}
 <div className="flex items-center gap-1 pt-1.5 mt-1 border-t border-muted">
 <span className="w-2 h-2 rounded-full shrink-0"style={{ backgroundColor: STATUS_COLORS[assignment.status] }} />
 <span className="text-muted-foreground">Status: {STATUS_LABELS[assignment.status]}</span>
 </div>
 </div>
 </div>
 )
}
