import { useHttp, usePage } from '@inertiajs/react';
import { useCallback, useMemo } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { update as updateSeccion } from '@/routes/fichas-inventario/seccion';
import type { EditPageProps, SectionProps } from '@/types/fichas-inventario';
import { useSectionForm } from '../../hooks/use-section-form';
import { CrujiasTable } from './seccion16/CrujiasTable';
import { ElementoSelector } from './seccion16/ElementoSelector';
import type {
    CrujiaConfig,
    ElementoCatalogo,
    ElementoFila16,
    Elementos16Payload,
} from './seccion16/types';
import { buildCrujiaState } from './seccion16/types';

function buildElementosFromFilas(
    filas: Record<string, unknown>[],
): Elementos16Payload {
    const result: Elementos16Payload = {};
    for (const fila of filas) {
        const id = String(fila.elemento_catalogo_id);
        if (!id || id === 'null') { continue; }
        const crujias_json = (fila.crujias_json ?? {}) as Record<
            string,
            Record<string, boolean>
        >;

        let sist_const: ElementoFila16['sist_const'] = null;
        if (fila.sist_const === 1) {
            sist_const = 'tradicional';
        } else if (fila.sist_const === 2) {
            sist_const = 'industrial';
        }

        result[id] = {
            sist_const,
            materiales_acabados:
                (fila.materiales_acabados as string | null) ?? null,
            crujias: crujias_json,
            estado_conservacion:
                (fila.estado_conservacion as 'B' | 'R' | 'M' | null) ?? null,
        };
    }
    return result;
}

export function Section161({ data, catalogs }: SectionProps) {
    const { inventario_meta } = usePage<EditPageProps>().props;
    const inventarioId = inventario_meta.id;

    const catalogo = (
        (catalogs.elementos_16_1 ?? []) as Record<string, unknown>[]
    ).map((e) => ({
        id: e.id as number,
        nombre: (e.nombre as string) ?? '',
        categoria: (e.categoria as string) ?? '',
        activo: true,
        sort_order: (e.sort_order as number) ?? 0,
    })) as ElementoCatalogo[];

    const filas161 = (data.filas_16_1 ?? []) as Record<string, unknown>[];

    const sectionForm = useSectionForm('16', {
        crujias_config: (data.crujias_config as CrujiaConfig[] | null) ?? [],
    });

    const filasHttp = useHttp({
        elementos: buildElementosFromFilas(filas161),
    });

    const selectedIds = useMemo(
        () => Object.keys(filasHttp.data.elementos).map((id) => Number(id)),
        [filasHttp.data.elementos],
    );

    const handleSelectorChange = useCallback(
        (ids: number[]) => {
            const current = filasHttp.data.elementos;
            const crujias = sectionForm.data.crujias_config;
            const next: Elementos16Payload = {};

            for (const id of ids) {
                const strId = String(id);
                if (current[strId]) {
                    next[strId] = current[strId];
                } else {
                    const crujiaInit: Record<
                        string,
                        Record<string, boolean>
                    > = {};
                    for (const c of crujias) {
                        crujiaInit[String(c.id)] = buildCrujiaState(
                            c.total_plantas,
                        ) as Record<string, boolean>;
                    }
                    next[strId] = {
                        sist_const: null,
                        materiales_acabados: null,
                        crujias: crujiaInit,
                        estado_conservacion: null,
                    };
                }
            }

            filasHttp.setData('elementos', next);
        },
        [filasHttp, sectionForm.data.crujias_config],
    );

    const handleCrujiasChange = useCallback(
        (crujias: CrujiaConfig[]) => {
            sectionForm.setData('crujias_config', crujias);
        },
        [sectionForm],
    );

    const handleElementosChange = useCallback(
        (elementos: Elementos16Payload) => {
            filasHttp.setData('elementos', elementos);
        },
        [filasHttp],
    );

    const saveFilas = useCallback(async () => {
        if (sectionForm.isDirty) {
            await sectionForm.save();
        }

        if (!filasHttp.isDirty) { return; }

        const url = updateSeccion.url([inventarioId, '16-1']);

        await new Promise<void>((resolve, reject) => {
            filasHttp.put(url, {
                onSuccess: (response: unknown) => {
                    const resp = response as {
                        data?: Record<string, unknown>[];
                    };
                    if (resp.data) {
                        filasHttp.setData(
                            'elementos',
                            buildElementosFromFilas(resp.data),
                        );
                        filasHttp.setDefaults({
                            elementos: buildElementosFromFilas(resp.data),
                        });
                    }
                    resolve();
                },
                onError: reject,
            } as any);
        });
    }, [filasHttp, inventarioId, sectionForm]);

    return (
        <div className="flex flex-col gap-4">
            <div className="grid gap-4 md:grid-cols-[320px_minmax(0,1fr)]">
                <Card className="rounded-2xl border-border/70">
                    <CardContent className="pt-4">
                        <p className="mb-3 text-sm font-medium text-foreground">
                            Elementos constructivos
                        </p>
                        <ElementoSelector
                            catalogo={catalogo}
                            selectedIds={selectedIds}
                            onChange={handleSelectorChange}
                        />
                    </CardContent>
                </Card>

                <div className="flex flex-col gap-2">
                    <p className="text-sm font-medium text-foreground">
                        Tabla 16.1 — Crujías y sistema constructivo
                    </p>
                    <p className="text-xs text-muted-foreground">
                        Usa el botón{' '}
                        <kbd className="rounded border bg-muted px-1 text-xs">
                            + Crujía
                        </kbd>{' '}
                        para agregar nuevas crujías, definir su código y su
                        total de plantas.
                    </p>
                    <CrujiasTable
                        catalogo={catalogo}
                        crujias={sectionForm.data.crujias_config}
                        elementos={filasHttp.data.elementos}
                        onCrujiasChange={handleCrujiasChange}
                        onElementosChange={handleElementosChange}
                    />
                    {(filasHttp.isDirty || sectionForm.isDirty) && (
                        <div className="flex justify-end">
                            <Button
                                type="button"
                                disabled={
                                    filasHttp.processing ||
                                    sectionForm.processing
                                }
                                onClick={saveFilas}
                            >
                                {filasHttp.processing || sectionForm.processing
                                    ? 'Guardando...'
                                    : 'Guardar tabla 16.1'}
                            </Button>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
}
