import { Link } from '@inertiajs/react';
import { Check } from 'lucide-react';
import { classroomColor, withAlpha } from '@/lib/classroom-color';
import { formatTime } from '@/lib/date';
import { cn } from '@/lib/utils';
import { show as meetingShow } from '@/routes/meetings';
import type { CalendarMeeting } from '@/types';

export const statusLabels: Record<CalendarMeeting['status'], string> = {
    scheduled: 'Pianificata',
    running: 'In corso',
    ended: 'Terminata',
};

/**
 * Status reads through shape, not hue: a hollow ring for what is still to come, a
 * pulsing dot for what is live, a check for what is done. Hue stays reserved for the
 * classroom, so both can be read at once.
 */
export function StatusDot({
    status,
    className,
}: {
    status: CalendarMeeting['status'];
    className?: string;
}) {
    if (status === 'ended') {
        return (
            <Check
                className={cn(
                    'text-muted-foreground size-3 shrink-0',
                    className,
                )}
                aria-hidden
            />
        );
    }

    if (status === 'running') {
        return (
            <span
                className={cn('relative flex size-2 shrink-0', className)}
                aria-hidden
            >
                <span className="bg-primary absolute inline-flex size-full animate-ping rounded-full opacity-70 motion-reduce:animate-none" />
                <span className="bg-primary relative inline-flex size-2 rounded-full" />
            </span>
        );
    }

    return (
        <span
            className={cn(
                'border-muted-foreground/60 size-2 shrink-0 rounded-full border',
                className,
            )}
            aria-hidden
        />
    );
}

type Props = {
    meeting: CalendarMeeting;
    /** `compact` fits a month cell, `block` fills a week slot, `row` is a list line. */
    variant?: 'compact' | 'block' | 'row';
};

export default function MeetingChip({ meeting, variant = 'compact' }: Props) {
    const color = classroomColor(meeting.classroom);
    const ended = meeting.status === 'ended';
    const start = formatTime(meeting.scheduled_at);
    const end = formatTime(meeting.ends_at);

    const label = `${meeting.title}, aula ${meeting.classroom.name}, dalle ${start} alle ${end}, ${statusLabels[meeting.status].toLowerCase()}`;

    return (
        <Link
            href={meetingShow(meeting.uuid)}
            aria-label={label}
            title={label}
            style={{
                borderLeftColor: color,
                // A list row is wide enough that a tint becomes a slab; the rule alone
                // carries the classroom there. In a grid the fill is what makes it an object.
                backgroundColor:
                    variant === 'row'
                        ? undefined
                        : withAlpha(color, ended ? 0.05 : 0.11),
            }}
            className={cn(
                'focus-visible:ring-ring block border-l-[3px] text-left transition-colors focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:outline-none',
                variant === 'compact' &&
                    'rounded-sm px-1.5 py-[3px] hover:brightness-[0.97] dark:hover:brightness-125',
                variant === 'block' &&
                    'h-full overflow-hidden rounded-sm px-1.5 py-1 hover:brightness-[0.97] dark:hover:brightness-125',
                variant === 'row' && 'hover:bg-muted/50 rounded-md px-3 py-2',
                ended && 'opacity-70',
            )}
        >
            {variant === 'compact' && (
                <span className="flex items-center gap-1.5">
                    <StatusDot status={meeting.status} />
                    <span className="text-muted-foreground shrink-0 text-[11px] tabular-nums">
                        {start}
                    </span>
                    <span className="truncate text-[11px] font-medium">
                        {meeting.title}
                    </span>
                </span>
            )}

            {variant === 'block' && (
                <span className="flex h-full flex-col gap-0.5 overflow-hidden">
                    <span className="flex items-center gap-1.5">
                        <StatusDot status={meeting.status} />
                        <span className="text-muted-foreground text-[11px] tabular-nums">
                            {start}
                        </span>
                    </span>
                    <span className="truncate text-xs leading-tight font-medium">
                        {meeting.title}
                    </span>
                    <span className="text-muted-foreground truncate text-[11px]">
                        {meeting.classroom.name}
                    </span>
                </span>
            )}

            {variant === 'row' && (
                <span className="flex items-center gap-3">
                    <StatusDot status={meeting.status} />
                    <span className="text-muted-foreground w-24 shrink-0 text-sm tabular-nums">
                        {start} – {end}
                    </span>
                    <span className="min-w-0 flex-1">
                        <span className="block truncate text-sm font-medium">
                            {meeting.title}
                        </span>
                        <span className="text-muted-foreground block truncate text-xs">
                            {meeting.classroom.name} ({meeting.classroom.code})
                        </span>
                    </span>
                    <span className="text-muted-foreground hidden shrink-0 text-xs sm:block">
                        {statusLabels[meeting.status]}
                    </span>
                </span>
            )}
        </Link>
    );
}
