<template>
    <div class="h-full min-h-0 overflow-auto rounded-lg border border-neutral-200 bg-white">
        <div class="min-w-[900px]">
            <div class="grid" :style="gridStyle" @mouseleave="clearHoveredCell">
                <div
                    class="sticky left-0 top-0 z-30 border-b border-neutral-200 bg-tertiary-500 px-4 py-3 text-md font-semibold text-neutral-700"
                >
                    Employés
                </div>
                <div
                    v-for="day in daysInMonth"
                    :key="day.date"
                    class="sticky top-0 z-20 border-b border-neutral-200 px-2 py-3 text-center text-xs font-semibold transition-colors"
                    :class="isHoveredColumn(day.date) || day.date === today ? 'bg-primary-500 text-white' : 'bg-tertiary-500 text-neutral-700'"
                >
                    <div>{{ day.label }}</div>
                    <div
                        class="text-[10px]"
                        :class="isHoveredColumn(day.date) || day.date === today ? 'text-white/90' : 'text-neutral-500'"
                    >
                        {{ day.weekday }}
                    </div>
                </div>

                <template v-for="employee in visibleEmployees" :key="employee.id">
                    <div
                        class="sticky left-0 z-10 border-b border-neutral-100 px-4 py-3 text-md font-semibold text-black cursor-pointer transition-shadow"
                        :class="isHoveredRow(employee.id) ? 'bg-primary-500 text-white ring-2 ring-inset ring-primary-500/40' : ''"
                        :style="rowHeaderStyle(employee)"
                        draggable="true"
                        @dragstart="handleDragStart($event, employee)"
                        @dragover="handleDragOver"
                        @drop="handleDrop($event, employee)"
                    >
                        {{ formatEmployeeName(employee) }}
                    </div>
                    <div
                        v-for="day in daysInMonth"
                        :key="employee.id + '-' + day.date"
                        class="border-b border-neutral-300 px-2 py-2 text-center text-xs text-neutral-800 transition-colors"
                        :class="cellContainerClass(employee.id, day.date)"
                        @mouseenter="setHoveredCell(employee.id, day.date)"
                    >
                        <template v-if="getCellInfo(employee.id, day.date)">
                            <button
                                type="button"
                                class="relative flex h-8 w-full items-center justify-center overflow-hidden rounded-md border border-neutral-200 text-[11px] font-semibold text-neutral-800"
                                :class="getCellInfo(employee.id, day.date)?.hasFormation ? 'cursor-not-allowed opacity-80' : ''"
                                :style="getCellStyle(employee.id, day.date)"
                                :disabled="getCellInfo(employee.id, day.date)?.hasFormation"
                                @click="handleCellClick(employee, day.date)"
                            >
                                <span v-if="!getCellInfo(employee.id, day.date)?.halfLabel">
                                    {{ getCellInfo(employee.id, day.date)?.code }}
                                </span>
                                <template v-else>
                                    <span
                                        v-if="getCellInfo(employee.id, day.date)?.halfLabel === 'AM'"
                                        class="absolute top-0 left-0 flex h-1/2 w-full items-center justify-center text-[10px] font-semibold"
                                    >
                                        {{ getCellInfo(employee.id, day.date)?.code }}
                                    </span>
                                    <span
                                        v-else
                                        class="absolute bottom-0 left-0 flex h-1/2 w-full items-center justify-center text-[10px] font-semibold"
                                    >
                                        {{ getCellInfo(employee.id, day.date)?.code }}
                                    </span>
                                </template>
                                <Icon
                                    v-if="getCellInfo(employee.id, day.date)?.hasFormation && getCellInfo(employee.id, day.date)?.code !== 'F'"
                                    name="mdi:school"
                                    size="12"
                                    class="absolute top-0 right-0 text-indigo-600 bg-white rounded-bl-md p-0.5"
                                    title="Formation"
                                />
                            </button>
                        </template>
                        <template v-else>
                            <button
                                type="button"
                                class="relative flex h-8 w-full items-center justify-center rounded-md border border-neutral-200 text-[11px] font-semibold text-neutral-800 bg-white"
                                :style="getCellStyle(employee.id, day.date)"
                                @click="handleCellClick(employee, day.date)"
                            >
                                <span></span>
                            </button>
                        </template>
                    </div>
                </template>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import type { Employee } from '~/services/dto/employee'
import type { HalfDay } from '~/services/dto/half-day'
import { toYmd } from '~/utils/date'

const now = new Date()
const today = toYmd(now.getFullYear(), now.getMonth(), now.getDate())

type DayInfo = {
    date: string
    label: string
    weekday: string
}

const props = defineProps<{
    daysInMonth: DayInfo[]
    visibleEmployees: Employee[]
    gridStyle: Record<string, string>
    getCellStyle: (employeeId: number, date: string) => Record<string, string> | undefined
    getCellInfo: (employeeId: number, date: string) => { id: number; code: string; color: string; halfLabel?: HalfDay; textColor?: string; hasFormation?: boolean } | null
    formatEmployeeName: (employee: Employee) => string
    isHolidayDate: (date: string) => boolean
}>()

const emit = defineEmits<{
    (event: 'cell-click', employee: Employee, date: string): void
    (event: 'reorder', payload: { dragId: number; dropId: number }): void
}>()

const handleCellClick = (employee: Employee, date: string) => {
    emit('cell-click', employee, date)
}

const handleDragStart = (event: DragEvent, employee: Employee) => {
    if (!event.dataTransfer) return
    event.dataTransfer.effectAllowed = 'move'
    event.dataTransfer.setData('text/plain', String(employee.id))
}

const handleDragOver = (event: DragEvent) => {
    event.preventDefault()
}

const handleDrop = (event: DragEvent, employee: Employee) => {
    event.preventDefault()
    const dragId = Number(event.dataTransfer?.getData('text/plain'))
    if (!dragId || dragId === employee.id) return
    emit('reorder', { dragId, dropId: employee.id })
}

// Etat de la cellule actuellement survolee.
const hoveredEmployeeId = ref<number | null>(null)
const hoveredDate = ref<string | null>(null)

const setHoveredCell = (employeeId: number, date: string) => {
    hoveredEmployeeId.value = employeeId
    hoveredDate.value = date
}

const clearHoveredCell = () => {
    hoveredEmployeeId.value = null
    hoveredDate.value = null
}

const isHoveredRow = (employeeId: number) => hoveredEmployeeId.value === employeeId

const isHoveredColumn = (date: string) => hoveredDate.value === date

// On garde la couleur du site tant que la ligne n'est pas survolee.
const rowHeaderStyle = (employee: Employee) => {
    if (isHoveredRow(employee.id)) return undefined
    return { backgroundColor: employee.site?.color ?? '#304998' }
}

// Index de ligne par employe pour savoir si une case est "au-dessus" de la case survolee.
const employeeIndexById = computed(() => {
    const indexMap = new Map<number, number>()
    props.visibleEmployees.forEach((employee, index) => {
        indexMap.set(employee.id, index)
    })
    return indexMap
})

const cellContainerClass = (employeeId: number, date: string) => {
    if (!hoveredEmployeeId.value || !hoveredDate.value) return 'hover:bg-primary-500'

    const hoveredRowIndex = employeeIndexById.value.get(hoveredEmployeeId.value)
    const currentRowIndex = employeeIndexById.value.get(employeeId)

    // Forme en L:
    // - ligne: toutes les cases a gauche (et la case cible)
    // - colonne: toutes les cases au-dessus (et la case cible)
    const isOnLeftSegment = isHoveredRow(employeeId) && date <= hoveredDate.value
    const isOnTopSegment = isHoveredColumn(date)
        && typeof hoveredRowIndex === 'number'
        && typeof currentRowIndex === 'number'
        && currentRowIndex <= hoveredRowIndex

    if (isOnLeftSegment || isOnTopSegment) return 'bg-primary-500'
    return 'hover:bg-primary-500'
}
</script>
