import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import { Input } from '@/components/ui/input';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { cn } from '@/lib/utils';
import { CalendarIcon } from 'lucide-react';
import * as React from 'react';

/**
 * Date input that always displays in French jj/mm/aaaa format regardless of
 * the user's browser locale (the native <input type="date"> can't be forced
 * to a specific format). Click the calendar icon to pick a date via the
 * shadcn Calendar popover, or type the date directly in jj/mm/aaaa.
 *
 * Values are exchanged with the parent in ISO `YYYY-MM-DD` so backend
 * payloads stay consistent.
 */
interface Props {
    value: string; // YYYY-MM-DD
    onChange: (iso: string) => void;
    disabled?: boolean;
    className?: string;
    inputClassName?: string;
    onCommit?: () => void; // fired on blur — same semantics as the old `onBlur`
}

function isoToFr(iso: string): string {
    if (!iso) return '';
    const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(iso);
    if (!m) return iso;
    return `${m[3]}/${m[2]}/${m[1]}`;
}

function frToIso(fr: string): string | null {
    const m = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/.exec(fr.trim());
    if (!m) return null;
    const dd = m[1].padStart(2, '0');
    const mo = m[2].padStart(2, '0');
    const yy = m[3];
    // Sanity: reject impossible values
    const day = Number(dd), mon = Number(mo);
    if (day < 1 || day > 31 || mon < 1 || mon > 12) return null;
    return `${yy}-${mo}-${dd}`;
}

export function FrDateInput({ value, onChange, disabled, className, inputClassName, onCommit }: Props) {
    const [text, setText] = React.useState(isoToFr(value));
    const [open, setOpen] = React.useState(false);

    // Keep local text in sync when the parent value changes (e.g. after a
    // server round-trip that resets the row).
    React.useEffect(() => setText(isoToFr(value)), [value]);

    const commit = () => {
        const iso = frToIso(text);
        if (iso && iso !== value) {
            onChange(iso);
        } else if (!iso && text !== '') {
            // invalid — revert display to last good value
            setText(isoToFr(value));
        }
        onCommit?.();
    };

    const selectedDate = value ? new Date(value + 'T00:00:00') : undefined;

    return (
        <div className={cn('flex items-center gap-1', className)}>
            <Input
                type="text"
                inputMode="numeric"
                placeholder="jj/mm/aaaa"
                value={text}
                disabled={disabled}
                onChange={(e) => setText(e.target.value)}
                onBlur={commit}
                onKeyDown={(e) => {
                    if (e.key === 'Enter') {
                        e.preventDefault();
                        (e.target as HTMLInputElement).blur();
                    }
                }}
                className={cn('h-11 tabular-nums', inputClassName)}
            />
            <Popover open={open} onOpenChange={setOpen}>
                <PopoverTrigger asChild>
                    <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        className="h-11 w-9 shrink-0"
                        disabled={disabled}
                        aria-label="Choisir une date"
                    >
                        <CalendarIcon className="h-4 w-4" />
                    </Button>
                </PopoverTrigger>
                <PopoverContent className="w-auto p-0" align="start">
                    <Calendar
                        mode="single"
                        selected={selectedDate}
                        onSelect={(d) => {
                            if (!d) return;
                            const iso = d.toISOString().slice(0, 10);
                            setText(isoToFr(iso));
                            onChange(iso);
                            setOpen(false);
                            onCommit?.();
                        }}
                    />
                </PopoverContent>
            </Popover>
        </div>
    );
}
