import { Plus, X } from 'lucide-react';
import { useId, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Field, FieldLabel } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import type { IdentificacionData } from '@/generated/types';
import { index as juntaVecinalIndex } from '@/routes/junta-vecinal';
import { index as zonaCatastralIndex } from '@/routes/zona-catastral';
import { CalleCombobox } from '../components/calle-combobox';
import { useCatalogo } from '../hooks/use-catalogo';
import { useSectionForm } from '../lib/section-form-context';

export function Identificacion() {
    const { data, setData, errors } = useSectionForm<IdentificacionData>();
    const zonas = useCatalogo(zonaCatastralIndex.url());
    const juntas = useCatalogo(juntaVecinalIndex.url());

    return (
        <div className="flex flex-col gap-0">
            <FieldRow label="Departamento" fixed value="Potosí" />
            <FieldRow label="Provincia" fixed value="Tomás Frías" />
            <FieldRow label="Municipio" fixed value="Potosí" />

            <FieldRow
                label="Zona catastral"
                required
                error={errors.zona_catastral_id}
            >
                <Select
                    value={data.zona_catastral_id?.toString()}
                    onValueChange={(v) =>
                        setData('zona_catastral_id', Number(v))
                    }
                >
                    <SelectTrigger className="w-full!">
                        <SelectValue
                            placeholder={
                                zonas.loading ? 'Cargando…' : 'Seleccionar zona'
                            }
                        />
                    </SelectTrigger>
                    <SelectContent>
                        {(zonas.data ?? []).map((z) => (
                            <SelectItem key={z.id} value={z.id.toString()}>
                                {z.id} : {z.nombre}
                            </SelectItem>
                        ))}
                    </SelectContent>
                </Select>
            </FieldRow>

            <FieldRow
                label="Junta vecinal"
                required
                error={errors.junta_vecinal_id}
            >
                <Select
                    value={data.junta_vecinal_id?.toString()}
                    onValueChange={(v) =>
                        setData('junta_vecinal_id', Number(v))
                    }
                >
                    <SelectTrigger className="w-full!">
                        <SelectValue
                            placeholder={
                                juntas.loading
                                    ? 'Cargando…'
                                    : 'Seleccionar junta'
                            }
                        />
                    </SelectTrigger>
                    <SelectContent>
                        {(juntas.data ?? []).map((j) => (
                            <SelectItem key={j.id} value={j.id.toString()}>
                                {j.nombre}
                            </SelectItem>
                        ))}
                    </SelectContent>
                </Select>
            </FieldRow>

            <FieldRow label="Calle" required error={errors.calle_id}>
                <CalleCombobox
                    value={data.calle_id ?? null}
                    onChange={(id) => setData('calle_id', id ?? 0)}
                    error={errors.calle_id}
                />
            </FieldRow>

            <FieldRow
                label="Esquina / Entre"
                required
                error={errors.esq_calle_id}
            >
                <CalleCombobox
                    value={data.esq_calle_id ?? null}
                    onChange={(id) => setData('esq_calle_id', id ?? 0)}
                    error={errors.esq_calle_id}
                    placeholder="Buscar esquina…"
                />
            </FieldRow>

            <FieldRow
                label="N° de inmueble"
                required
                error={errors.numero_inmueble}
            >
                <NumerosInmueble
                    value={data.numero_inmueble}
                    onChange={(arr) => setData('numero_inmueble', arr)}
                />
            </FieldRow>
        </div>
    );
}

type NumerosInmuebleProps = {
    value: number[];
    onChange: (value: number[]) => void;
};

function NumerosInmueble({ value, onChange }: NumerosInmuebleProps) {
    const hintId = useId();
    const [inputs, setInputs] = useState<string[]>(value.map(String));

    const lift = (next: string[]) => {
        setInputs(next);
        onChange(
            next
                .map((s) => Number.parseInt(s.replace(/\D/g, ''), 10))
                .filter((n) => !Number.isNaN(n) && n > 0),
        );
    };

    const actualizar = (index: number, raw: string) => {
        const next = [...inputs];
        next[index] = raw.replace(/\D/g, '');
        lift(next);
    };

    const agregar = () => lift([...inputs, '']);

    const quitar = (index: number) =>
        lift(inputs.filter((_, i) => i !== index));

    return (
        <div className="flex flex-col gap-2">
            {inputs.length === 0 ? (
                <p id={hintId} className="text-sm text-muted-foreground">
                    Sin número de inmueble.
                </p>
            ) : (
                inputs.map((numero, index) => {
                    const inputId = `${hintId}-${index}`;
                    return (
                        <div key={inputId} className="flex items-center gap-2">
                            <Label htmlFor={inputId} className="sr-only">
                                Número de inmueble {index + 1}
                            </Label>
                            <Input
                                id={inputId}
                                type="text"
                                inputMode="numeric"
                                pattern="[0-9]*"
                                aria-describedby={hintId}
                                value={numero}
                                placeholder="Ej. 145"
                                onChange={(e) =>
                                    actualizar(index, e.target.value)
                                }
                                className="md:max-w-35"
                            />
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon-sm"
                                aria-label={`Quitar número ${index + 1}`}
                                onClick={() => quitar(index)}
                            >
                                <X />
                            </Button>
                        </div>
                    );
                })
            )}
            <Button
                type="button"
                variant="outline"
                size="sm"
                className="w-fit"
                onClick={agregar}
            >
                <Plus data-icon="inline-start" />
                Agregar número
            </Button>
        </div>
    );
}

function FieldRow({
    label,
    required,
    fixed,
    value,
    error,
    children,
}: {
    label: string;
    required?: boolean;
    fixed?: boolean;
    value?: string;
    error?: string;
    children?: React.ReactNode;
}) {
    return (
        <Field
            data-invalid={!!error}
            className="grid gap-2 border-b border-border/60 py-3 sm:grid-cols-[180px_minmax(0,1fr)] sm:items-center sm:gap-4"
        >
            <FieldLabel className="text-sm font-medium text-muted-foreground">
                {label}
                {required && <span className="ml-0.5 text-destructive">*</span>}
            </FieldLabel>
            {fixed ? (
                <div className="flex h-9 min-w-0 items-center rounded-md border border-border bg-muted px-3 text-sm text-foreground">
                    {value}
                </div>
            ) : (
                <div className="flex min-w-0 flex-col gap-1">
                    {children}
                    {error && (
                        <span className="text-sm text-destructive">
                            {error}
                        </span>
                    )}
                </div>
            )}
        </Field>
    );
}
