"use client";

import { type ReactNode, useActionState, useEffect, useMemo, useRef, useState } from "react";
import {
  AbastecimientoAguaPotable,
  CuentaConLuz,
  EstadoCivil,
  EstadoConstructivo,
  EstadoHabitabilidad,
  MaterialPredominante,
  ParentescoOcupante,
  SistemaEvacuacionAguas,
  SituacionLaboral,
  SituacionLote,
  TipoVivienda,
} from "@prisma/client";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Plus, Trash2 } from "lucide-react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Field, SelectField, TextAreaField } from "@/components/fichas/form-fields";
import { DateField } from "@/components/fichas/date-field";
import { EstadoFichaMenu } from "@/components/fichas/estado-ficha-menu";
import { SubmitButton } from "@/components/fichas/submit-button";
import { formatDateCL } from "@/lib/date-format";
import { normalizeTramoRsh, tramoRshOptions } from "@/lib/tramo-rsh";
import { createFichaAction, updateFichaAction } from "@/server/actions/fichas";
import { initialState } from "@/server/actions/action-state";
import type { ActionState } from "@/server/actions/action-state";
import type { FichaDetail } from "@/server/queries/fichas";

const situacionLoteOptions = [
  { value: SituacionLote.CON_DUENO, label: "Con dueño" },
  { value: SituacionLote.CON_RESOLUCION, label: "Con resolución" },
  { value: SituacionLote.SIN_RESOLUCION, label: "Sin resolución" },
  { value: SituacionLote.SIN_OCUPANTE, label: "Sin ocupante" },
  { value: SituacionLote.INHABILITADO_SERVIU, label: "Inhabilitado por SERVIU" },
  { value: SituacionLote.SEDE_SOCIAL, label: "Sede social" },
  { value: SituacionLote.OTRO, label: "Otro" },
];

const manzanaOptions = [
  { value: "C", label: "C" },
  { value: "D", label: "D" },
  { value: "E", label: "E" },
  { value: "E1", label: "E1" },
  { value: "F", label: "F" },
];

const direccionLoteOptions = [
  { value: "Longitudinal", label: "Longitudinal" },
  { value: "Pasaje Dagoberto Godoy", label: "Pasaje Dagoberto Godoy" },
  { value: "Pasaje Lima", label: "Pasaje Lima" },
  { value: "Pasaje Cádiz", label: "Pasaje Cádiz" },
  { value: "Pasaje Michigan", label: "Pasaje Michigan" },
  { value: "Santa Rosa", label: "Santa Rosa" },
  { value: "Madrid", label: "Madrid" },
  { value: "Irene Frei", label: "Irene Frei" },
];

const contribucionesOptions = [
  { value: "EXENTO", label: "Exento" },
  { value: "SI", label: "Sí" },
];

const estadoHabitabilidadOptions = [
  { value: EstadoHabitabilidad.HABITADO, label: "Habitado" },
  { value: EstadoHabitabilidad.DESHABITADO, label: "Deshabitado" },
];

const tipoViviendaOptions = [
  { value: TipoVivienda.VIVIENDA_1_PISO, label: "Vivienda de 1 piso" },
  { value: TipoVivienda.VIVIENDA_2_PISOS, label: "Vivienda de 2 pisos" },
  { value: TipoVivienda.VIVIENDA_PRECARIA, label: "Vivienda precaria" },
];

const estadoConstructivoOptions = [
  { value: EstadoConstructivo.BUENA, label: "Buena" },
  { value: EstadoConstructivo.MALA, label: "Mala" },
  { value: EstadoConstructivo.ACEPTABLE, label: "Aceptable" },
];

const materialPredominanteOptions = [
  { value: MaterialPredominante.LIGERA, label: "Ligera" },
  { value: MaterialPredominante.SOLIDA, label: "Sólida" },
  { value: MaterialPredominante.MIXTO, label: "Mixto" },
];

const cuentaConLuzOptions = [
  { value: CuentaConLuz.MEDIDOR_PROPIO, label: "Medidor propio" },
  { value: CuentaConLuz.CEDIDA_VECINOS, label: "Cedida por vecinos" },
  { value: CuentaConLuz.CONEXION_IRREGULAR_RED_PUBLICA, label: "Conexión irregular a red pública" },
];

const sistemaEvacuacionAguasOptions = [
  { value: SistemaEvacuacionAguas.FOSA_SEPTICA, label: "Fosa séptica" },
  { value: SistemaEvacuacionAguas.POZO_NEGRO, label: "Pozo negro" },
  {
    value: SistemaEvacuacionAguas.DERIVACION_CURSO_AGUA_SUPERFICIAL,
    label: "Derivación a curso de agua superficial",
  },
];

const abastecimientoAguaPotableOptions = [
  { value: AbastecimientoAguaPotable.ALJIBE_MUNICIPAL_GOBERNACION, label: "Aljibe municipal / Gobernación" },
  { value: AbastecimientoAguaPotable.ALJIBE_PARTICULAR, label: "Aljibe particular" },
  { value: AbastecimientoAguaPotable.POZO_PROPIO, label: "Pozo propio" },
];

const estadoCivilOptions = [
  { value: EstadoCivil.CASADO, label: "Casado(a)" },
  { value: EstadoCivil.VIUDO, label: "Viudo(a)" },
  { value: EstadoCivil.DIVORCIADO, label: "Divorciado(a)" },
  { value: EstadoCivil.SOLTERO, label: "Soltero(a)" },
];

const situacionLaboralOptions = [
  { value: SituacionLaboral.INDEPENDIENTE, label: "Independiente" },
  { value: SituacionLaboral.DEPENDIENTE, label: "Dependiente" },
  { value: SituacionLaboral.PENSIONADO, label: "Pensionado" },
  { value: SituacionLaboral.JUBILADO, label: "Jubilado" },
  { value: SituacionLaboral.CESANTE, label: "Cesante" },
];

const parentescoOptions = [
  { value: ParentescoOcupante.HIJO, label: "Hijo(a)" },
  { value: ParentescoOcupante.CONYUGE, label: "Cónyuge" },
  { value: ParentescoOcupante.ESPOSO, label: "Esposo(a)" },
  { value: ParentescoOcupante.PADRE, label: "Padre" },
  { value: ParentescoOcupante.MADRE, label: "Madre" },
  { value: ParentescoOcupante.ABUELO, label: "Abuelo(a)" },
  { value: ParentescoOcupante.TIO, label: "Tío(a)" },
  { value: ParentescoOcupante.SOBRINO, label: "Sobrino(a)" },
  { value: ParentescoOcupante.NIETO, label: "Nieto(a)" },
  { value: ParentescoOcupante.OTRO, label: "Otro" },
];

type OcupanteActualRow = {
  rowKey: string;
  id?: string;
  nombreCompleto?: string | null;
  rut?: string | null;
  edad?: number | string | null;
  parentesco?: string | null;
};

type SubmittedFichaValues = {
  estadoFicha?: string;
  observacionesRelevantes?: string;
  ocupante?: {
    nombre?: string;
    rut?: string;
    correoElectronico?: string;
    telefono?: string;
    fechaNacimiento?: string;
    anioLlegadaSector?: string | number;
    estadoCivil?: string;
    situacionLaboral?: string;
    tramoRsh?: string;
    cantidadPersonasLote?: string | number;
    observaciones?: string;
  };
  ocupantesActuales?: OcupanteActualRow[];
  lote?: {
    lote?: string;
    manzana?: string;
    direccionLote?: string;
    nombreAsociado?: string;
    resolucion?: string;
    fojas?: string;
    numero?: string;
    anio?: string | number;
    rol?: string;
    situacionLote?: string;
    duenoAsignatario?: string;
    rutDuenoAsignatario?: string;
    contribuciones?: string | null;
    estadoHabitabilidad?: string;
  };
  vivienda?: {
    tipoVivienda?: string;
    estadoConstructivo?: string;
    materialPredominante?: string;
    cuentaConLuz?: string;
    sistemaEvacuacionAguas?: string;
    abastecimientoAguaPotable?: string;
    cantidadViviendasLote?: string | number;
    observacionesSociales?: string;
    observacionesTerritoriales?: string;
  };
  deslinde?: {
    norte?: string;
    sur?: string;
    este?: string;
    oeste?: string;
    comentarios?: string;
  };
};

type TabValue = "ocupante" | "lote" | "vivienda" | "deslindes" | "documentos" | "observaciones" | "historial";
type DirtySections = Partial<Record<TabValue, boolean>>;

const tabs: { value: TabValue; label: string }[] = [
  { value: "ocupante", label: "Ocupante actual" },
  { value: "lote", label: "Antecedentes del lote" },
  { value: "vivienda", label: "Situación vivienda" },
  { value: "deslindes", label: "Deslindes" },
  { value: "documentos", label: "Documentos" },
  { value: "observaciones", label: "Observaciones" },
  { value: "historial", label: "Historial" },
];

function firstError(errors: Record<string, string[]> | undefined, key: string) {
  return errors?.[key]?.[0];
}

function emptyOcupanteRow(rowKey = "empty-0"): OcupanteActualRow {
  return { rowKey, nombreCompleto: "", rut: "", edad: null, parentesco: "" };
}

function rowHasData(row: OcupanteActualRow) {
  return Boolean(row.id || row.nombreCompleto || row.rut || row.edad || row.parentesco);
}

function collectOcupantesFromForm(form: HTMLFormElement | null, rows: OcupanteActualRow[]) {
  if (!form) return rows;
  const formData = new FormData(form);
  return rows.map((row, index) => ({
    rowKey: row.rowKey,
    id: String(formData.get(`ocupantesActuales.${index}.id`) ?? "") || undefined,
    nombreCompleto: String(formData.get(`ocupantesActuales.${index}.nombreCompleto`) ?? ""),
    rut: String(formData.get(`ocupantesActuales.${index}.rut`) ?? ""),
    edad: String(formData.get(`ocupantesActuales.${index}.edad`) ?? ""),
    parentesco: String(formData.get(`ocupantesActuales.${index}.parentesco`) ?? ""),
  }));
}

function rowsFromSubmittedOcupantes(ocupantes: OcupanteActualRow[] | undefined, formVersion?: number) {
  if (!ocupantes?.length) return [emptyOcupanteRow(`submitted-${formVersion ?? "empty"}-0`)];
  return ocupantes.map((ocupante, index) => ({
    ...ocupante,
    rowKey: ocupante.rowKey ?? ocupante.id ?? `submitted-${formVersion ?? "ok"}-${index}`,
  }));
}

function ocupantesFromActionState(result: ActionState) {
  const values = result.formValues as SubmittedFichaValues | undefined;
  return values?.ocupantesActuales;
}

function sectionFromFieldName(name: string, fallback: TabValue): TabValue {
  if (name === "estadoFicha" || name.startsWith("ocupante.") || name.startsWith("ocupantesActuales.")) {
    return "ocupante";
  }
  if (name.startsWith("lote.")) return "lote";
  if (name.startsWith("vivienda.")) return "vivienda";
  if (name.startsWith("deslinde.")) return "deslindes";
  if (name === "observacionesRelevantes") return "observaciones";
  return fallback;
}

function sectionSnapshot(form: HTMLFormElement, section: TabValue) {
  const values: string[] = [];
  for (const element of Array.from(form.elements)) {
    if (!(element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement)) {
      continue;
    }
    if (!element.name || element.name === "section") continue;
    if (sectionFromFieldName(element.name, section) !== section) continue;
    if (element instanceof HTMLInputElement && (element.type === "checkbox" || element.type === "radio")) {
      values.push(`${element.name}=${element.checked ? element.value : ""}`);
      continue;
    }
    values.push(`${element.name}=${element.value}`);
  }
  return values.sort().join("&");
}

export function FichaForm({
  ficha,
  documentosContent,
  observacionesContent,
  historialContent,
}: {
  ficha?: FichaDetail;
  documentosContent?: ReactNode;
  observacionesContent?: ReactNode;
  historialContent?: ReactNode;
}) {
  const router = useRouter();
  const action = ficha ? updateFichaAction.bind(null, ficha.id) : createFichaAction;
  const [state, formAction] = useActionState(action, initialState);
  const formRef = useRef<HTMLFormElement>(null);
  const sectionBaselines = useRef<Partial<Record<TabValue, string>>>({});
  const [activeTab, setActiveTab] = useState<TabValue>("ocupante");
  const [pendingTab, setPendingTab] = useState<TabValue | null>(null);
  const [dirtySections, setDirtySections] = useState<DirtySections>({});
  const [sectionErrors, setSectionErrors] = useState<Record<string, string[]> | undefined>();
  const [isSavingSection, setIsSavingSection] = useState(false);
  const [resetVersion, setResetVersion] = useState(0);
  const [removedOcupanteIds, setRemovedOcupanteIds] = useState<string[]>([]);
  const [appliedOcupantesVersion, setAppliedOcupantesVersion] = useState<number | undefined>();
  const submittedValues = state.formValues as SubmittedFichaValues | undefined;
  const visibleErrors = sectionErrors ?? state.errors;
  const ocupanteValues = submittedValues?.ocupante ?? ficha?.ocupante;
  const loteValues = submittedValues?.lote ?? ficha?.lote;
  const viviendaValues = submittedValues?.vivienda ?? ficha?.situacionVivienda;
  const deslindeValues = submittedValues?.deslinde ?? ficha?.deslinde;
  const [estadoFicha, setEstadoFicha] = useState(submittedValues?.estadoFicha ?? ficha?.estadoFicha ?? "");
  const latestAudit = ficha?.auditLogs?.[0];
  const initialOcupantesActuales = useMemo<OcupanteActualRow[]>(() => {
    if (submittedValues?.ocupantesActuales?.length) {
      return submittedValues.ocupantesActuales.map((ocupante, index) => ({
        ...ocupante,
        rowKey: ocupante.rowKey ?? ocupante.id ?? `submitted-${index}`,
      }));
    }
    if (!ficha?.ocupantesActuales?.length) return [emptyOcupanteRow()];
    return ficha.ocupantesActuales.map((ocupante) => ({
      rowKey: ocupante.id,
      id: ocupante.id,
      nombreCompleto: ocupante.nombreCompleto,
      rut: ocupante.rut,
      edad: ocupante.edad,
      parentesco: ocupante.parentesco,
    }));
  }, [ficha, submittedValues]);
  const [ocupantesActuales, setOcupantesActuales] = useState<OcupanteActualRow[]>(initialOcupantesActuales);

  if (
    state.ok &&
    state.formVersion &&
    state.formVersion !== appliedOcupantesVersion &&
    submittedValues?.ocupantesActuales
  ) {
    setOcupantesActuales(rowsFromSubmittedOcupantes(submittedValues.ocupantesActuales, state.formVersion));
    setRemovedOcupanteIds([]);
    setAppliedOcupantesVersion(state.formVersion);
  }

  const displayedOcupantesActuales = ocupantesActuales.length > 0 ? ocupantesActuales : [emptyOcupanteRow()];

  useEffect(() => {
    if (!state.message) return;
    if (state.ok) {
      toast.success(state.message);
      if (state.redirectTo) router.push(state.redirectTo);
      if (!state.formValues) router.refresh();
    } else {
      toast.error(state.message);
    }
  }, [router, state]);

  useEffect(() => {
    if (!ficha || !formRef.current) return;
    sectionBaselines.current = {
      ocupante: sectionSnapshot(formRef.current, "ocupante"),
      lote: sectionSnapshot(formRef.current, "lote"),
      vivienda: sectionSnapshot(formRef.current, "vivienda"),
      deslindes: sectionSnapshot(formRef.current, "deslindes"),
      observaciones: sectionSnapshot(formRef.current, "observaciones"),
    };
  }, [ficha, resetVersion, state.formVersion]);

  function markSectionDirty(section: TabValue) {
    if (!ficha) return;
    setDirtySections((current) => ({ ...current, [section]: true }));
  }

  function markChangedField(target: EventTarget | null) {
    if (!(target instanceof HTMLInputElement || target instanceof HTMLSelectElement || target instanceof HTMLTextAreaElement)) {
      return;
    }
    if (!target.name || target.name === "section") return;
    markSectionDirty(sectionFromFieldName(target.name, activeTab));
  }

  async function saveSection(section: TabValue): Promise<ActionState> {
    if (!ficha || section === "documentos" || section === "historial" || !formRef.current) {
      return { ok: true };
    }
    const formData = new FormData(formRef.current);
    formData.set("section", section);
    return updateFichaAction(ficha.id, initialState, formData);
  }

  function handleTabChange(nextTab: string) {
    const targetTab = nextTab as TabValue;
    if (targetTab === activeTab || isSavingSection) return;

    const currentTab = activeTab;
    if (!ficha || !dirtySections[currentTab] || currentTab === "documentos" || currentTab === "historial") {
      setActiveTab(targetTab);
      return;
    }
    if (formRef.current && sectionSnapshot(formRef.current, currentTab) === sectionBaselines.current[currentTab]) {
      setDirtySections((current) => ({ ...current, [currentTab]: false }));
      setActiveTab(targetTab);
      return;
    }

    setPendingTab(targetTab);
  }

  async function saveAndContinue() {
    if (!pendingTab) return;
    const currentTab = activeTab;
    setIsSavingSection(true);
    const result = await saveSection(currentTab);
    setIsSavingSection(false);
    if (result.ok) {
      if (formRef.current) {
        sectionBaselines.current[currentTab] = sectionSnapshot(formRef.current, currentTab);
      }
      const savedOcupantes = ocupantesFromActionState(result);
      if (currentTab === "ocupante" && savedOcupantes) {
        setOcupantesActuales(rowsFromSubmittedOcupantes(savedOcupantes, result.formVersion));
        setRemovedOcupanteIds([]);
      }
      setDirtySections((current) => ({ ...current, [currentTab]: false }));
      setSectionErrors(undefined);
      setActiveTab(pendingTab);
      setPendingTab(null);
      if (!result.formValues) router.refresh();
    } else {
      setSectionErrors(result.errors);
      toast.error(result.message ?? "No se pudo guardar la sección.");
      setPendingTab(null);
    }
  }

  function continueWithoutSaving() {
    if (!pendingTab) return;
    setDirtySections((current) => ({ ...current, [activeTab]: false }));
    setSectionErrors(undefined);
    if (activeTab === "ocupante") {
      setOcupantesActuales(initialOcupantesActuales);
      setRemovedOcupanteIds([]);
    }
    setActiveTab(pendingTab);
    setPendingTab(null);
    setResetVersion((value) => value + 1);
  }

  function cancelTabChange() {
    setPendingTab(null);
  }

  return (
    <>
    <div className="mb-4 flex flex-col gap-3 rounded-lg border border-border bg-card px-4 py-3 shadow-sm sm:flex-row sm:items-center sm:justify-between">
      <div className="space-y-1">
        <p className="text-xs uppercase tracking-wide text-muted-foreground">Estado de ficha</p>
        <p className="text-sm text-muted-foreground">
          {ficha
            ? `Última modificación ${formatDateCL(latestAudit?.createdAt ?? ficha.updatedAt)} · ${
                latestAudit?.user?.name ?? ficha.createdBy.name
              }`
            : "Elige un estado antes de crear la ficha."}
        </p>
      </div>
      <EstadoFichaMenu fichaId={ficha?.id} value={estadoFicha} onChange={setEstadoFicha} />
    </div>
    <form
      ref={formRef}
      action={formAction}
      className="space-y-5"
      onInput={(event) => markChangedField(event.target)}
      onChange={(event) => markChangedField(event.target)}
      onSubmit={() => {
        setSectionErrors(undefined);
      }}
    >
      <input type="hidden" name="section" value={activeTab} />
      <input type="hidden" name="estadoFicha" value={estadoFicha} />
      {removedOcupanteIds.map((id) => (
        <input key={id} type="hidden" name="ocupantesActualesEliminados" value={id} />
      ))}
      <Tabs
        key={`${state.formVersion ?? "initial"}-${resetVersion}`}
        value={activeTab}
        onValueChange={handleTabChange}
        className="w-full"
      >
        <div className="space-y-2">
          <div className="overflow-x-auto pb-2">
            <TabsList className="h-auto min-w-max flex-wrap justify-start">
              {tabs.map((tab) => (
                <TabsTrigger key={tab.value} value={tab.value} disabled={isSavingSection}>
                  {tab.label}
                </TabsTrigger>
              ))}
            </TabsList>
          </div>
        </div>

        <TabsContent value="ocupante">
          <div className="space-y-4">
            <Card>
              <CardHeader>
                <CardTitle>Ocupante responsable</CardTitle>
              </CardHeader>
              <CardContent className="grid gap-4 md:grid-cols-2">
                <Field
                  label="Año que llegó al sector"
                  name="ocupante.anioLlegadaSector"
                  type="number"
                  defaultValue={ocupanteValues?.anioLlegadaSector}
                  error={firstError(visibleErrors, "ocupante.anioLlegadaSector")}
                />
                <Field
                  label="Nombre del ocupante responsable actual del lote"
                  name="ocupante.nombre"
                  defaultValue={ocupanteValues?.nombre}
                  error={firstError(visibleErrors, "ocupante.nombre")}
                />
                <Field
                  label="RUT"
                  name="ocupante.rut"
                  defaultValue={ocupanteValues?.rut}
                  placeholder="12345678-9"
                  error={firstError(visibleErrors, "ocupante.rut")}
                />
                <Field
                  label="Correo electrónico"
                  name="ocupante.correoElectronico"
                  type="email"
                  defaultValue={ocupanteValues?.correoElectronico}
                  error={firstError(visibleErrors, "ocupante.correoElectronico")}
                />
                <Field label="Teléfono" name="ocupante.telefono" defaultValue={ocupanteValues?.telefono} />
                <DateField
                  label="Fecha de nacimiento"
                  name="ocupante.fechaNacimiento"
                  defaultValue={ocupanteValues?.fechaNacimiento}
                  error={firstError(visibleErrors, "ocupante.fechaNacimiento")}
                />
                <SelectField
                  label="Estado civil"
                  name="ocupante.estadoCivil"
                  defaultValue={ocupanteValues?.estadoCivil ?? ""}
                  options={estadoCivilOptions}
                  error={firstError(visibleErrors, "ocupante.estadoCivil")}
                />
                  <SelectField
                    label="Situación laboral actual"
                    name="ocupante.situacionLaboral"
                    defaultValue={ocupanteValues?.situacionLaboral ?? ""}
                    options={situacionLaboralOptions}
                    error={firstError(visibleErrors, "ocupante.situacionLaboral")}
                  />
                  <SelectField
                    label="Tramo % RSH"
                    name="ocupante.tramoRsh"
                    defaultValue={normalizeTramoRsh(ocupanteValues?.tramoRsh) ?? ""}
                    options={[...tramoRshOptions]}
                    error={firstError(visibleErrors, "ocupante.tramoRsh")}
                  />
                  <Field
                    label="Cantidad de personas viviendo en el lote"
                    name="ocupante.cantidadPersonasLote"
                    type="number"
                  defaultValue={ocupanteValues?.cantidadPersonasLote}
                  error={firstError(visibleErrors, "ocupante.cantidadPersonasLote")}
                />
                <div className="md:col-span-2">
                  <TextAreaField
                    label="Observaciones del ocupante"
                    name="ocupante.observaciones"
                    defaultValue={ocupanteValues?.observaciones}
                  />
                </div>
              </CardContent>
            </Card>

            <Card>
              <CardHeader className="flex flex-row items-center justify-between gap-4">
                <CardTitle>Ocupantes actuales</CardTitle>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    markSectionDirty("ocupante");
                    const currentRows = collectOcupantesFromForm(formRef.current, displayedOcupantesActuales);
                    setOcupantesActuales([...currentRows, emptyOcupanteRow(crypto.randomUUID())]);
                  }}
                >
                  <Plus className="h-4 w-4" />
                  Agregar ocupante
                </Button>
              </CardHeader>
              <CardContent className="space-y-3">
                {displayedOcupantesActuales.map((ocupante, index) => (
                  <div key={ocupante.rowKey} className="grid gap-3 rounded-md border border-border bg-card p-3 lg:grid-cols-[1.4fr_1fr_120px_1fr_auto] lg:items-start">
                    <input type="hidden" name={`ocupantesActuales.${index}.id`} value={ocupante.id ?? ""} />
                    <Field
                      label="Nombre y apellido"
                      name={`ocupantesActuales.${index}.nombreCompleto`}
                      defaultValue={ocupante.nombreCompleto}
                      error={firstError(visibleErrors, `ocupantesActuales.${index}.nombreCompleto`)}
                    />
                    <Field
                      label="RUT"
                      name={`ocupantesActuales.${index}.rut`}
                      defaultValue={ocupante.rut}
                      placeholder="12345678-9"
                      error={firstError(visibleErrors, `ocupantesActuales.${index}.rut`)}
                    />
                    <Field
                      label="Edad"
                      name={`ocupantesActuales.${index}.edad`}
                      type="number"
                      defaultValue={ocupante.edad}
                      error={firstError(visibleErrors, `ocupantesActuales.${index}.edad`)}
                    />
                    <SelectField
                      label="Parentesco"
                      name={`ocupantesActuales.${index}.parentesco`}
                      defaultValue={ocupante.parentesco ?? ""}
                      options={parentescoOptions}
                      error={firstError(visibleErrors, `ocupantesActuales.${index}.parentesco`)}
                    />
                    <div className="pt-7">
                      <Button
                        type="button"
                        variant="destructive"
                        size="sm"
                        disabled={displayedOcupantesActuales.length === 1 && !rowHasData(ocupante)}
                        onClick={() => {
                          markSectionDirty("ocupante");
                          const currentRows = collectOcupantesFromForm(formRef.current, displayedOcupantesActuales);
                          const removedId = ocupante.id;
                          if (removedId) {
                            setRemovedOcupanteIds((ids) => (ids.includes(removedId) ? ids : [...ids, removedId]));
                          }
                          const nextRows = currentRows.filter((row) => row.rowKey !== ocupante.rowKey);
                          setOcupantesActuales(
                            nextRows.length > 0 ? nextRows : [emptyOcupanteRow(crypto.randomUUID())],
                          );
                        }}
                      >
                        <Trash2 className="h-4 w-4" />
                        Eliminar
                      </Button>
                    </div>
                  </div>
                ))}
              </CardContent>
            </Card>
          </div>
        </TabsContent>

        <TabsContent value="lote">
          <Card>
            <CardContent className="grid gap-4 pt-6 md:grid-cols-2">
              <Field label="Número de lote" name="lote.lote" type="number" defaultValue={loteValues?.lote} required error={firstError(visibleErrors, "lote.lote")} />
              <SelectField label="Manzana" name="lote.manzana" defaultValue={loteValues?.manzana ?? ""} options={manzanaOptions} placeholder="Seleccione" error={firstError(visibleErrors, "lote.manzana")} />
              <SelectField label="Dirección del lote" name="lote.direccionLote" defaultValue={loteValues?.direccionLote ?? ""} options={direccionLoteOptions} placeholder="Seleccione" error={firstError(visibleErrors, "lote.direccionLote")} />
              <Field label="Nombre asociado al lote" name="lote.nombreAsociado" defaultValue={loteValues?.nombreAsociado} />
              <Field label="Resolución" name="lote.resolucion" defaultValue={loteValues?.resolucion} />
              <Field label="Fojas" name="lote.fojas" defaultValue={loteValues?.fojas} />
              <Field label="Número" name="lote.numero" defaultValue={loteValues?.numero} />
              <Field label="Año" name="lote.anio" type="number" defaultValue={loteValues?.anio} error={firstError(visibleErrors, "lote.anio")} />
              <Field label="Rol" name="lote.rol" defaultValue={loteValues?.rol} />
              <SelectField label="Situación del lote" name="lote.situacionLote" defaultValue={loteValues?.situacionLote ?? ""} options={situacionLoteOptions} placeholder="Seleccione" error={firstError(visibleErrors, "lote.situacionLote")} />
              <Field label="Dueño / asignatario" name="lote.duenoAsignatario" defaultValue={loteValues?.duenoAsignatario} />
              <Field label="RUT dueño / asignatario" name="lote.rutDuenoAsignatario" defaultValue={loteValues?.rutDuenoAsignatario} error={firstError(visibleErrors, "lote.rutDuenoAsignatario")} />
              <SelectField label="Contribuciones" name="lote.contribuciones" defaultValue={loteValues?.contribuciones ?? ""} options={contribucionesOptions} placeholder="Seleccione" error={firstError(visibleErrors, "lote.contribuciones")} />
              <SelectField label="Estado de habitabilidad" name="lote.estadoHabitabilidad" defaultValue={loteValues?.estadoHabitabilidad ?? ""} options={estadoHabitabilidadOptions} placeholder="Seleccione" error={firstError(visibleErrors, "lote.estadoHabitabilidad")} />
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="vivienda">
          <Card>
            <CardContent className="grid gap-4 pt-6 md:grid-cols-2">
              <SelectField
                label="Tipo de vivienda"
                name="vivienda.tipoVivienda"
                defaultValue={viviendaValues?.tipoVivienda ?? ""}
                options={tipoViviendaOptions}
                error={firstError(visibleErrors, "vivienda.tipoVivienda")}
              />
              <SelectField
                label="Estado constructivo"
                name="vivienda.estadoConstructivo"
                defaultValue={viviendaValues?.estadoConstructivo ?? ""}
                options={estadoConstructivoOptions}
                error={firstError(visibleErrors, "vivienda.estadoConstructivo")}
              />
              <SelectField
                label="Material predominante"
                name="vivienda.materialPredominante"
                defaultValue={viviendaValues?.materialPredominante ?? ""}
                options={materialPredominanteOptions}
                error={firstError(visibleErrors, "vivienda.materialPredominante")}
              />
              <SelectField
                label="Cuenta con luz"
                name="vivienda.cuentaConLuz"
                defaultValue={viviendaValues?.cuentaConLuz ?? ""}
                options={cuentaConLuzOptions}
                error={firstError(visibleErrors, "vivienda.cuentaConLuz")}
              />
              <SelectField
                label="Sistema de evacuación y tratamiento de aguas servidas"
                name="vivienda.sistemaEvacuacionAguas"
                defaultValue={viviendaValues?.sistemaEvacuacionAguas ?? ""}
                options={sistemaEvacuacionAguasOptions}
                error={firstError(visibleErrors, "vivienda.sistemaEvacuacionAguas")}
              />
              <SelectField
                label="Abastecimiento de agua potable"
                name="vivienda.abastecimientoAguaPotable"
                defaultValue={viviendaValues?.abastecimientoAguaPotable ?? ""}
                options={abastecimientoAguaPotableOptions}
                error={firstError(visibleErrors, "vivienda.abastecimientoAguaPotable")}
              />
              <Field
                label="Cantidad de viviendas en el lote"
                name="vivienda.cantidadViviendasLote"
                type="number"
                defaultValue={viviendaValues?.cantidadViviendasLote}
                error={firstError(visibleErrors, "vivienda.cantidadViviendasLote")}
              />
              <div className="md:col-span-2">
                <TextAreaField label="Observaciones sociales" name="vivienda.observacionesSociales" defaultValue={viviendaValues?.observacionesSociales} />
              </div>
              <div className="md:col-span-2">
                <TextAreaField label="Observaciones territoriales" name="vivienda.observacionesTerritoriales" defaultValue={viviendaValues?.observacionesTerritoriales} />
              </div>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="deslindes">
          <Card>
            <CardHeader>
              <CardTitle>Deslindes actuales del terreno</CardTitle>
            </CardHeader>
            <CardContent className="grid gap-4 md:grid-cols-2">
              <Field label="Norte" name="deslinde.norte" defaultValue={deslindeValues?.norte} />
              <Field label="Sur" name="deslinde.sur" defaultValue={deslindeValues?.sur} />
              <Field label="Este" name="deslinde.este" defaultValue={deslindeValues?.este} />
              <Field label="Oeste" name="deslinde.oeste" defaultValue={deslindeValues?.oeste} />
              <div className="md:col-span-2">
                <TextAreaField
                  label="Comentarios de deslindes"
                  name="deslinde.comentarios"
                  defaultValue={deslindeValues?.comentarios}
                  rows={5}
                />
              </div>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="documentos">
          <div className="sr-only">Documentos de la ficha</div>
        </TabsContent>

        <TabsContent value="observaciones">
          <Card>
            <CardContent className="pt-6">
              <TextAreaField
                label="Observaciones relevantes"
                name="observacionesRelevantes"
                defaultValue={submittedValues?.observacionesRelevantes ?? ficha?.observacionesRelevantes}
                rows={7}
              />
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="historial">
          {historialContent ?? (
            <Card>
              <CardContent className="pt-6">
                <p className="text-sm text-muted-foreground">Crea la ficha para ver su historial de cambios.</p>
              </CardContent>
            </Card>
          )}
        </TabsContent>
      </Tabs>

      <Dialog open={Boolean(pendingTab)} onOpenChange={(open) => !open && cancelTabChange()}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Cambios sin guardar</DialogTitle>
            <DialogDescription>
              Tienes cambios pendientes en esta sección. ¿Quieres guardarlos antes de continuar?
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="flex-col gap-2 sm:flex-row sm:justify-end">
            <Button type="button" variant="outline" onClick={cancelTabChange} disabled={isSavingSection}>
              Cancelar
            </Button>
            <Button type="button" variant="outline" onClick={continueWithoutSaving} disabled={isSavingSection}>
              Continuar sin guardar
            </Button>
            <Button type="button" onClick={() => void saveAndContinue()} disabled={isSavingSection}>
              {isSavingSection ? "Guardando..." : "Guardar y continuar"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {activeTab !== "documentos" ? (
        <div className="flex justify-end">
          <SubmitButton label={ficha ? "Guardar avance" : "Crear ficha"} />
        </div>
      ) : null}
    </form>
    {activeTab === "documentos" ? (
      documentosContent ?? (
        <Card>
          <CardContent className="pt-6">
            <p className="text-sm text-muted-foreground">Crea la ficha para habilitar documentos.</p>
          </CardContent>
        </Card>
      )
    ) : null}
    {activeTab === "observaciones" ? observacionesContent : null}
    </>
  );
}



