import { Link } from '@inertiajs/react';
import { Plus } from 'lucide-react';
import { cn } from '@/lib/utils';
import { show } from '@/routes/admin/leave-requests';

export type Absence = {
    id: number;
    employee: { id: number; code: string; full_name: string };
    leave_type: { name: string; code: string };
    start_date: string;
    end_date: string;
    status: string;
};

type Props = {
    month: number;
    year: number;
    absences: Absence[];
    canCreate?: boolean;
    onDayClick?: (isoDate: string) => void;
};

const WEEKDAY_LABELS = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'];

function toDateOnly(dateString: string): Date {
    const [y, m, d] = dateString.split('-').map(Number);

    return new Date(y, m - 1, d);
}

export function toIsoDate(day: Date): string {
    const y = day.getFullYear();
    const m = String(day.getMonth() + 1).padStart(2, '0');
    const d = String(day.getDate()).padStart(2, '0');

    return `${y}-${m}-${d}`;
}

function isWithinRange(day: Date, absence: Absence): boolean {
    const start = toDateOnly(absence.start_date);
    const end = toDateOnly(absence.end_date);

    return day >= start && day <= end;
}

function isToday(day: Date): boolean {
    const today = new Date();

    return (
        day.getFullYear() === today.getFullYear() &&
        day.getMonth() === today.getMonth() &&
        day.getDate() === today.getDate()
    );
}

export function CalendarGrid({
    month,
    year,
    absences,
    canCreate = false,
    onDayClick,
}: Props) {
    const firstOfMonth = new Date(year, month - 1, 1);
    const daysInMonth = new Date(year, month, 0).getDate();

    // getDay(): 0 = Sunday..6 = Saturday. Convert to a Monday-first index.
    const firstWeekday = (firstOfMonth.getDay() + 6) % 7;

    const cells: Array<Date | null> = [
        ...Array.from({ length: firstWeekday }, () => null),
        ...Array.from(
            { length: daysInMonth },
            (_, index) => new Date(year, month - 1, index + 1),
        ),
    ];

    while (cells.length % 7 !== 0) {
        cells.push(null);
    }

    return (
        <div className="overflow-x-auto">
            <div className="grid min-w-[700px] grid-cols-7 gap-px rounded-md border bg-border">
                {WEEKDAY_LABELS.map((label) => (
                    <div
                        key={label}
                        className="bg-muted p-2 text-center text-xs font-medium text-muted-foreground"
                    >
                        {label}
                    </div>
                ))}

                {cells.map((day, index) => {
                    if (!day) {
                        return (
                            <div
                                key={index}
                                className="min-h-24 bg-background"
                            />
                        );
                    }

                    const dayAbsences = absences.filter((absence) =>
                        isWithinRange(day, absence),
                    );
                    const today = isToday(day);

                    const isoDate = toIsoDate(day);

                    return (
                        <div
                            key={index}
                            role={canCreate ? 'button' : undefined}
                            tabIndex={canCreate ? 0 : undefined}
                            onClick={
                                canCreate
                                    ? () => onDayClick?.(isoDate)
                                    : undefined
                            }
                            onKeyDown={
                                canCreate
                                    ? (e) => {
                                          if (
                                              e.key === 'Enter' ||
                                              e.key === ' '
                                          ) {
                                              e.preventDefault();
                                              onDayClick?.(isoDate);
                                          }
                                      }
                                    : undefined
                            }
                            className={cn(
                                'group/day relative min-h-24 space-y-1 bg-background p-1.5',
                                today && 'bg-blue-50 dark:bg-blue-950/30',
                                canCreate &&
                                    'cursor-pointer hover:bg-muted/60',
                            )}
                        >
                            <div
                                className={cn(
                                    'text-xs text-muted-foreground',
                                    today &&
                                        'flex size-5 items-center justify-center rounded-full bg-blue-600 font-semibold text-white',
                                )}
                            >
                                {day.getDate()}
                            </div>
                            {canCreate && (
                                <button
                                    type="button"
                                    onClick={(e) => {
                                        e.stopPropagation();
                                        onDayClick?.(isoDate);
                                    }}
                                    title="Nouvelle demande de congé"
                                    className="absolute top-1 right-1 flex size-5 items-center justify-center rounded-full bg-foreground text-background opacity-0 transition-opacity group-hover/day:opacity-100 focus-visible:opacity-100"
                                >
                                    <Plus className="size-3.5" />
                                </button>
                            )}
                            {dayAbsences.map((absence) => (
                                <Link
                                    key={absence.id}
                                    href={show(absence.id)}
                                    onClick={(e) => e.stopPropagation()}
                                    className={cn(
                                        'block truncate rounded px-1.5 py-0.5 text-xs',
                                        absence.status === 'approved'
                                            ? 'bg-emerald-100 text-emerald-900 dark:bg-emerald-900/40 dark:text-emerald-200'
                                            : 'border border-dashed border-amber-400 text-amber-700 dark:text-amber-300',
                                    )}
                                    title={`${absence.employee.full_name} — ${absence.leave_type.name}`}
                                >
                                    {absence.employee.full_name}
                                </Link>
                            ))}
                        </div>
                    );
                })}
            </div>
        </div>
    );
}
