import { Icon } from "@iconify/react";
import { Box, Link, MenuItem, Paper, Stack, TextField, Typography } from "@mui/material";
import { useEffect, useMemo, useState } from "react";
import { searchClientes } from "../../../api/clientes.service";
import { getMonedas } from "../../../api/monedas.service";
import { getSucursales } from "../../../api/sucursales.service";
import { getVendedoresActivos } from "../../../api/vendedores-cobradores.service";
import { useAuthStore } from "../../../store/AuthStore";
import {
  useCreatePresupuestoMutation,
  usePresupuestoConfigQuery,
  useUpdatePresupuestoMutation,
} from "../../../tanstack/PresupuestosStack";
import { useCondicionesPagoQuery } from "../../../tanstack/PagosStack";
import { useUltimaCotizacionQuery } from "../../../tanstack/MonedasStack";
import { calcTotals } from "../../../utils/presupuestoCalc";
import { formatMoney } from "../../../utils/formatMoney";
import { fmtFechaCalendario } from "../../../utils/fecha";
import { InlineValidationBanner, MonedaInput } from "../../_standards";
import { DocumentoPreviewModal } from "../DocumentoPreviewModal";
import {
  Divider,
  Field,
  FieldsGrid,
  Footer,
  FooterActionButton,
  FormHead,
  FormPanel,
  GhostButton,
  SectionTitle,
} from "../../ui/FormShell";
import { SearchableSelect } from "../../ui/SearchableSelect";
import { AsyncSelect } from "./AsyncSelect";
import { ItemsEditor } from "./ItemsEditor";

const clienteLabel = (c) =>
  c?.razon_social ?? c?.personas?.razon_social ?? c?.nombre_fantasia ?? c?.label ?? "";
const clienteRuc = (c) => c?.ruc ?? c?.personas?.ruc ?? c?.documento ?? "";

// Mantiene un porcentaje dentro de [0, 100]; preserva el campo vacío mientras se escribe.
const clampPct = (v) => {
  if (v === "" || v == null) return "";
  const n = Number(v);
  if (!Number.isFinite(n)) return "";
  return Math.min(Math.max(n, 0), 100);
};

const initialFromData = (data) => {
  if (!data) {
    return {
      cliente: null, cliente_id: null, contacto_cliente: "", vendedor_id: null, titulo: "",
      sucursal_id: null, moneda_id: null, tipo_cambio_usd: 0, fecha_vigencia: "", condicion_pago_id: null,
      descuento_global_pct: 0, descuento_tipo: "ninguno", descuento_monto: 0,
      notas_cliente: "", observaciones_internas: "", items: [],
    };
  }
  return {
    cliente: { id: data.cliente_id, razon_social: data.clientes?.personas?.razon_social ?? "(cliente actual)", ruc: data.clientes?.personas?.ruc },
    cliente_id: data.cliente_id,
    contacto_cliente: data.contacto_cliente ?? "",
    vendedor_id: data.vendedor_id ?? null,
    titulo: data.titulo ?? "",
    sucursal_id: data.sucursal_id ?? null,
    moneda_id: data.moneda_id ?? null,
    tipo_cambio_usd: Number(data.tipo_cambio_usd) || 0,
    fecha_vigencia: data.fecha_vigencia ? String(data.fecha_vigencia).slice(0, 10) : "",
    condicion_pago_id: data.condicion_pago_id ?? null,
    descuento_global_pct: Number(data.descuento_global_pct) || 0,
    descuento_tipo: Number(data.descuento_global_pct) > 0 ? "porcentaje" : "ninguno",
    descuento_monto: 0,
    notas_cliente: data.notas_cliente ?? "",
    observaciones_internas: data.observaciones_internas ?? "",
    items: (data.items || []).map((it, i) => ({
      _key: it.id ?? crypto.randomUUID(),
      orden: it.orden ?? i + 1,
      tipo: it.tipo,
      producto: null,
      producto_id: it.producto_id ?? null,
      descripcion: it.descripcion ?? "",
      cantidad: Number(it.cantidad) || 0,
      unidad_medida: it.unidad_medida ?? "",
      precio_unitario: Number(it.precio_unitario) || 0,
      descuento_pct: Number(it.descuento_pct) || 0,
      descuento_monto: Number(it.descuento_monto) || 0,
      iva_categoria: it.iva_categoria ?? "IVA_10",
    })),
  };
};

export function FormPresupuesto({ initialData = null, onSaved, onCancel }) {
  const [form, setForm] = useState(() => initialFromData(initialData));
  const [vendedores, setVendedores] = useState([]);
  const [monedas, setMonedas] = useState([]);
  const [sucursales, setSucursales] = useState([]);
  const [errores, setErrores] = useState([]);
  const [previewOpen, setPreviewOpen] = useState(false);
  const { user } = useAuthStore();

  const create = useCreatePresupuestoMutation();
  const update = useUpdatePresupuestoMutation();
  const { data: condicionesPago = [] } = useCondicionesPagoQuery();
  const { data: presupuestoConfig } = usePresupuestoConfigQuery();
  const isEdit = !!initialData?.id;
  const saving = create.isPending || update.isPending;

  const condicionesActivas = useMemo(
    () => (Array.isArray(condicionesPago) ? condicionesPago : []).filter((c) => c.activo !== false),
    [condicionesPago],
  );

  const condicionOpts = useMemo(
    () => condicionesActivas.map((c) => ({ id: c.id, label: c.descripcion })),
    [condicionesActivas],
  );

  // Al crear, preseleccionar la condición marcada como "por defecto".
  useEffect(() => {
    if (!isEdit && !form.condicion_pago_id && condicionesActivas.length) {
      const def = condicionesActivas.find((c) => c.es_default) || condicionesActivas[0];
      if (def) setForm((f) => ({ ...f, condicion_pago_id: def.id }));
    }
  }, [condicionesActivas, isEdit, form.condicion_pago_id]);

  // Al crear, aplicar los valores por defecto de la configuración:
  // moneda = moneda_base, vigencia = hoy + dias_vigencia. No pisa lo ya cargado.
  useEffect(() => {
    if (isEdit || !presupuestoConfig) return;
    setForm((f) => {
      const patch = {};
      if (!f.moneda_id && monedas.length && presupuestoConfig.moneda_base) {
        const base = monedas.find((m) => m.codigo === presupuestoConfig.moneda_base);
        if (base) patch.moneda_id = base.id;
      }
      if (!f.fecha_vigencia && presupuestoConfig.dias_vigencia) {
        const d = new Date();
        d.setDate(d.getDate() + Number(presupuestoConfig.dias_vigencia));
        const mm = String(d.getMonth() + 1).padStart(2, "0");
        const dd = String(d.getDate()).padStart(2, "0");
        patch.fecha_vigencia = `${d.getFullYear()}-${mm}-${dd}`;
      }
      return Object.keys(patch).length ? { ...f, ...patch } : f;
    });
  }, [presupuestoConfig, monedas, isEdit]);

  useEffect(() => {
    (async () => {
      try {
        const v = await getVendedoresActivos();
        setVendedores((Array.isArray(v) ? v : v?.data || []).map((x) => ({
          id: x.id, label: `${x.nombre ?? ""} ${x.apellido ?? ""}`.trim() || x.codigo || "Vendedor",
        })));
      } catch { /* noop */ }
      try {
        const s = await getSucursales();
        const list = (Array.isArray(s) ? s : s?.data || []).map((x) => ({
          id: x.id,
          label: `${x.punto_establecimiento || "000"} — ${x.descripcion ?? "Sucursal"}`,
        }));
        setSucursales(list);
      } catch { /* noop */ }
      try {
        const m = await getMonedas();
        setMonedas((Array.isArray(m) ? m : m?.data || []).map((x) => ({
          id: x.id, codigo: x.codigo, label: `${x.codigo} — ${x.descripcion ?? ""}`.trim(),
        })));
      } catch { /* noop */ }
    })();
  }, []);

  useEffect(() => {
    if (isEdit || form.sucursal_id || !sucursales.length) return;
    const def = sucursales.find((s) => s.id === user?.sucursal_id) || sucursales[0];
    if (def?.id) setForm((f) => ({ ...f, sucursal_id: def.id }));
  }, [form.sucursal_id, isEdit, sucursales, user?.sucursal_id]);

  const set = (patch) => setForm((f) => ({ ...f, ...patch }));

  const monedaCodigo = useMemo(
    () => monedas.find((m) => m.id === form.moneda_id)?.codigo || "PYG",
    [monedas, form.moneda_id],
  );
  const esUSD = monedaCodigo !== "PYG";

  // Cotización vigente de la moneda seleccionada (Config > Monedas). Se usa para
  // sugerir el tipo de cambio y para bloquear el guardado si no hay cotización cargada.
  const { data: ultimaCotizacion } = useUltimaCotizacionQuery(esUSD ? form.moneda_id : null);
  const cotizacionVenta = Number(ultimaCotizacion?.cotizacion_venta) || 0;
  const sinCotizacion = esUSD && !(cotizacionVenta > 0);

  // Al elegir/cambiar una moneda ≠ PYG, sugerir el tipo de cambio desde la última
  // cotización_venta. No pisa un valor ya ingresado (el onChange de moneda lo limpia).
  useEffect(() => {
    if (!esUSD || !(cotizacionVenta > 0)) return;
    setForm((f) => (Number(f.tipo_cambio_usd) > 0 ? f : { ...f, tipo_cambio_usd: cotizacionVenta }));
  }, [cotizacionVenta, esUSD]);

  const tcActivo = esUSD ? form.tipo_cambio_usd : null;
  // Total bruto (invariante al descuento global) — base para derivar el % cuando el
  // descuento se ingresa como monto fijo.
  const totalBrutoBase = useMemo(
    () => calcTotals(form.items, 0, tcActivo).totals.total_bruto,
    [form.items, tcActivo],
  );
  // % efectivo del descuento global según el tipo elegido en el Resumen (como Factura):
  // 'porcentaje' → el % ingresado; 'monto' → monto/total_bruto·100; 'ninguno' → 0.
  const descPctEfectivo = useMemo(() => {
    if (form.descuento_tipo === "porcentaje") return Number(form.descuento_global_pct) || 0;
    if (form.descuento_tipo === "monto") {
      if (!(totalBrutoBase > 0)) return 0;
      return Math.min(Math.max(((Number(form.descuento_monto) || 0) / totalBrutoBase) * 100, 0), 100);
    }
    return 0;
  }, [form.descuento_tipo, form.descuento_global_pct, form.descuento_monto, totalBrutoBase]);

  const { totals, items: itemsCalc } = useMemo(
    () => calcTotals(form.items, descPctEfectivo, tcActivo),
    [form.items, descPctEfectivo, tcActivo],
  );
  const totalIva = useMemo(() => Number(totals.iva5 || 0) + Number(totals.iva10 || 0), [totals.iva5, totals.iva10]);
  const baseGravada = useMemo(() => Number(totals.base_iva5 || 0) + Number(totals.base_iva10 || 0), [totals.base_iva5, totals.base_iva10]);

  const validar = () => {
    const errs = [];
    if (!form.cliente_id) errs.push("Cliente: obligatorio");
    if (!form.titulo.trim()) errs.push("Título: obligatorio");
    if (!isEdit && !form.sucursal_id) errs.push("Sucursal: obligatoria");
    if (!isEdit && !form.moneda_id) errs.push("Moneda: obligatoria");
    if (!isEdit && !form.fecha_vigencia) errs.push("Vigencia: obligatoria");
    if (form.items.filter((i) => i.descripcion.trim()).length === 0) errs.push("Debe haber al menos un ítem con descripción");
    if (sinCotizacion) errs.push(`Moneda ${monedaCodigo}: no hay cotización cargada en Configuración → Monedas. Cargala antes de presupuestar en esta moneda.`);
    if (esUSD && !(Number(form.tipo_cambio_usd) > 0)) errs.push(`Tipo de cambio: requerido para moneda ${monedaCodigo}`);
    form.items.forEach((i, idx) => { if (!i.descripcion.trim()) errs.push(`Ítem ${idx + 1}: descripción obligatoria`); });
    setErrores(errs);
    return errs.length === 0;
  };

  const abrirPreview = () => {
    if (!validar()) return;
    setPreviewOpen(true);
  };

  const confirmarGuardado = async () => {
    const payload = {
      cliente_id: form.cliente_id,
      contacto_cliente: form.contacto_cliente || undefined,
      vendedor_id: form.vendedor_id || undefined,
      titulo: form.titulo.trim(),
      ...(!isEdit ? { sucursal_id: form.sucursal_id || undefined } : {}),
      moneda_id: form.moneda_id || undefined,
      tipo_cambio_usd: esUSD ? Number(form.tipo_cambio_usd) : undefined,
      fecha_vigencia: form.fecha_vigencia || undefined,
      condicion_pago_id: form.condicion_pago_id || undefined,
      notas_cliente: form.notas_cliente || undefined,
      observaciones_internas: form.observaciones_internas || undefined,
      descuento_global_pct: Math.round((Number(descPctEfectivo) || 0) * 10000) / 10000,
      items: form.items.map((it, i) => ({
        orden: i + 1,
        tipo: it.tipo,
        producto_id: it.producto_id || undefined,
        descripcion: it.descripcion,
        notas_item: it.notas_item || undefined,
        cantidad: Number(it.cantidad) || 0,
        unidad_medida: it.unidad_medida || undefined,
        precio_unitario: Number(it.precio_unitario) || 0,
        descuento_pct: Number(it.descuento_pct) || 0,
        descuento_monto: Number(it.descuento_monto) || 0,
        iva_categoria: it.iva_categoria || "IVA_10",
      })),
    };
    try {
      const result = isEdit
        ? await update.mutateAsync({ id: initialData.id, data: payload })
        : await create.mutateAsync(payload);
      setPreviewOpen(false);
      onSaved?.(result);
    } catch { /* toast lo maneja la mutation */ }
  };

  return (
    <FormPanel id="presupuestos-form">
      {/* Volver primero y a la izquierda: es la salida del formulario, y en esa
          esquina se lee antes que el título. Ver docs/ui-standards.md. */}
      <FormHead style={{ justifyContent: "flex-start", gap: 12 }}>
        <GhostButton onClick={onCancel}>
          <Icon icon="lucide:arrow-left" /> Volver
        </GhostButton>
        <SectionTitle style={{ margin: 0 }}>
          <Icon icon={isEdit ? "lucide:file-edit" : "lucide:file-plus"} />
          {isEdit ? "Editar presupuesto" : "Nuevo presupuesto"}
        </SectionTitle>
      </FormHead>

      {errores.length > 0 && (
        <Box sx={{ mb: 1.5 }}>
          <InlineValidationBanner errors={errores} title="Revisá los siguientes campos" />
        </Box>
      )}

      <Box
        sx={{
          mt: 1,
          display: "grid",
          gridTemplateColumns: { xs: "1fr", lg: "minmax(0, 1fr) minmax(300px, 340px)" },
          gap: { xs: 1.5, md: 2 },
          alignItems: "start",
        }}
      >
        <Box id="presupuestos-form-datos" sx={{ minWidth: 0 }}>
          <SectionTitle><Icon icon="lucide:clipboard-list" /> Datos del presupuesto</SectionTitle>
          <FieldsGrid $cols={4}>
            <Field>
              <label>Cliente *</label>
              <AsyncSelect
                value={form.cliente}
                onChange={(c) => set({ cliente: c, cliente_id: c?.id ?? null })}
                fetcher={(q) => searchClientes(q, 15)}
                getOptionLabel={(o) => clienteLabel(o)}
                renderOptionContent={(o) => (
                  <Box>
                    <Typography variant="body2">{clienteLabel(o)}</Typography>
                    {clienteRuc(o) && <Typography variant="caption" color="text.secondary">RUC/CI: {clienteRuc(o)}</Typography>}
                  </Box>
                )}
                placeholder="Buscar por razón social o RUC…"
              />
            </Field>
            <Field>
              <label>Contacto del cliente</label>
              <input value={form.contacto_cliente} onChange={(e) => set({ contacto_cliente: e.target.value })} placeholder="Ej: Ing. Pérez" />
            </Field>
            <Field $span={2}>
              <label>Título / Asunto *</label>
              <input value={form.titulo} onChange={(e) => set({ titulo: e.target.value })} placeholder="Ej: Equipamiento oficinas planta 2" />
            </Field>

            <Field>
              <label>Vendedor</label>
              <SearchableSelect options={vendedores} value={form.vendedor_id} onChange={(id) => set({ vendedor_id: id })} placeholder="Buscar vendedor…" />
            </Field>
            <Field>
              <label>Sucursal *</label>
              <SearchableSelect
                options={sucursales}
                value={form.sucursal_id}
                onChange={(id) => set({ sucursal_id: id })}
                placeholder="Seleccionar sucursal…"
                disabled={isEdit}
              />
            </Field>
            <Field id="presupuestos-form-moneda">
              <label>Moneda *</label>
              <SearchableSelect
                options={monedas}
                value={form.moneda_id}
                onChange={(id) => set({ moneda_id: id, tipo_cambio_usd: 0 })}
                placeholder="Seleccionar moneda…"
              />
            </Field>
            {esUSD && (
              <Field>
                <label>Tipo de cambio ({monedaCodigo} → Gs)</label>
                <input type="number" min="0" step="any" value={form.tipo_cambio_usd} onChange={(e) => set({ tipo_cambio_usd: e.target.value })} placeholder="Ej: 7400" />
                {sinCotizacion ? (
                  <Typography variant="caption" sx={{ display: "flex", alignItems: "center", gap: 0.5, mt: 0.5, color: "warning.main" }}>
                    <Icon icon="lucide:alert-triangle" width={13} />
                    Sin cotización para {monedaCodigo}.{" "}
                    <Link href="/configuracion?seccion=monedas" target="_blank" rel="noopener" underline="hover">
                      Cargala en Configuración → Monedas
                    </Link>
                  </Typography>
                ) : ultimaCotizacion?.fecha ? (
                  <Typography variant="caption" sx={{ display: "flex", alignItems: "center", gap: 0.5, mt: 0.5, color: "text.secondary" }}>
                    <Icon icon="lucide:info" width={13} />
                    Sugerido de cotización del {new Date(ultimaCotizacion.fecha).toLocaleDateString("es-PY")}
                  </Typography>
                ) : null}
              </Field>
            )}
            <Field id="presupuestos-form-vigencia">
              <label>Vigencia hasta *</label>
              <input type="date" value={form.fecha_vigencia} onChange={(e) => set({ fecha_vigencia: e.target.value })} />
            </Field>
            <Field $span={2}>
              <label>Condición de pago</label>
              <SearchableSelect options={condicionOpts} value={form.condicion_pago_id}
                onChange={(id) => set({ condicion_pago_id: id })} placeholder="Seleccionar condición…" clearable />
            </Field>
            <Field $span={2}>
              <label>Notas para el cliente (aparecen en el PDF)</label>
              <textarea rows={2} value={form.notas_cliente} onChange={(e) => set({ notas_cliente: e.target.value })} />
            </Field>
            <Field $span={4}>
              <label>Observaciones internas (no aparecen en el PDF)</label>
              <textarea rows={2} value={form.observaciones_internas} onChange={(e) => set({ observaciones_internas: e.target.value })} />
            </Field>
          </FieldsGrid>

          <Divider />

          <Box id="presupuestos-form-items">
            <SectionTitle><Icon icon="lucide:list" /> Ítems</SectionTitle>
            <ItemsEditor items={form.items} onChange={(items) => set({ items })} moneda={monedaCodigo} />
          </Box>
        </Box>

        <Box
          sx={{
            minWidth: 0,
            position: { lg: "sticky" },
            top: { lg: 12 },
            alignSelf: "start",
          }}
        >
          <Paper id="presupuestos-form-resumen" variant="outlined" sx={{ borderRadius: 2, overflow: "hidden" }}>
            <Box sx={{ display: "flex", alignItems: "center", gap: 1, px: 2, py: 1.6, bgcolor: "action.hover", borderBottom: "1px solid", borderColor: "divider" }}>
              <Icon icon="mdi:calculator" />
              <Typography variant="h6" sx={{ fontSize: "1.05rem", fontWeight: 700 }}>Resumen</Typography>
            </Box>
            <Box sx={{ p: { xs: 1.5, sm: 2 } }}>
              <Box sx={{ mb: 1.75 }}>
                <Typography variant="caption" color="text.secondary" sx={{ fontWeight: 600, letterSpacing: 0.4, textTransform: "uppercase", display: "block", mb: 0.75 }}>
                  Tipo descuento
                </Typography>
                <Stack direction="row" spacing={1}>
                  <TextField
                    select
                    size="small"
                    fullWidth
                    value={form.descuento_tipo}
                    onChange={(e) => {
                      const t = e.target.value;
                      if (t === "porcentaje") set({ descuento_tipo: t, descuento_monto: 0 });
                      else if (t === "monto") set({ descuento_tipo: t, descuento_global_pct: 0 });
                      else set({ descuento_tipo: t, descuento_global_pct: 0, descuento_monto: 0 });
                    }}
                  >
                    <MenuItem value="ninguno">Ninguno</MenuItem>
                    <MenuItem value="porcentaje">Porcentaje %</MenuItem>
                    <MenuItem value="monto">Monto fijo</MenuItem>
                  </TextField>
                  {form.descuento_tipo === "porcentaje" && (
                    <TextField
                      size="small"
                      type="number"
                      value={form.descuento_global_pct}
                      onChange={(e) => set({ descuento_global_pct: clampPct(e.target.value) })}
                      inputProps={{ min: 0, max: 100, step: "any", style: { textAlign: "right" } }}
                      placeholder="%"
                      sx={{ maxWidth: 96 }}
                    />
                  )}
                  {form.descuento_tipo === "monto" && (
                    <MonedaInput
                      value={Number(form.descuento_monto) || 0}
                      onChange={(v) => set({ descuento_monto: v })}
                      moneda={monedaCodigo}
                      size="small"
                      sx={{ maxWidth: 150 }}
                    />
                  )}
                </Stack>
              </Box>

              <Stack spacing={1.1}>
                <SummaryRow label="Total Bruto" value={formatMoney(totals.total_bruto, monedaCodigo)} />
                {totals.descuento_global_monto > 0 && (
                  <SummaryRow
                    label={form.descuento_tipo === "monto" ? "Desc. Global (monto)" : `Desc. Global (${Math.round(descPctEfectivo * 100) / 100}%)`}
                    value={`- ${formatMoney(totals.descuento_global_monto, monedaCodigo)}`}
                  />
                )}
                <SummaryDivider />
                <SummaryRow label="Liq. IVA 10%" value={formatMoney(totals.iva10, monedaCodigo)} />
                <SummaryRow label="Liq. IVA 5%" value={formatMoney(totals.iva5, monedaCodigo)} />
                <SummaryRow label="Total IVA" value={formatMoney(totalIva, monedaCodigo)} />
                <SummaryDivider />
                <SummaryRow label="Base Gravada" value={formatMoney(baseGravada, monedaCodigo)} />
                <SummaryRow label="Total Exentas" value={formatMoney(totals.subtotal_exento, monedaCodigo)} />
                <SummaryDivider />
                <SummaryRow label="TOTAL OPERACIÓN" value={formatMoney(totals.total, monedaCodigo)} main />
                {totals.total_equivalente != null && <SummaryRow label="Equivalente Gs" value={formatMoney(totals.total_equivalente, "PYG")} />}
              </Stack>
            </Box>
          </Paper>
        </Box>
      </Box>

      <Footer id="presupuestos-form-footer">
        <FooterActionButton type="button" $variant="danger" disabled={saving} onClick={onCancel}>
          <Icon icon="lucide:x-circle" /> Cancelar
        </FooterActionButton>
        <FooterActionButton type="button" $variant="primary" disabled={saving} onClick={abrirPreview}>
          <Icon icon="lucide:save" /> {saving ? "Guardando…" : isEdit ? "Guardar cambios" : "Crear presupuesto"}
        </FooterActionButton>
      </Footer>

      <DocumentoPreviewModal
        open={previewOpen}
        onClose={() => setPreviewOpen(false)}
        onConfirm={confirmarGuardado}
        loading={saving}
        titulo={isEdit ? "Confirmar cambios del presupuesto" : "Confirmar presupuesto"}
        confirmLabel={isEdit ? "Guardar cambios" : "Crear presupuesto"}
        moneda={monedaCodigo}
        campos={[
          { label: "Cliente", value: form.cliente?.razon_social || "" },
          { label: "Contacto", value: form.contacto_cliente || "" },
          { label: "Título", value: form.titulo || "" },
          { label: "Vendedor", value: vendedores.find((v) => v.id === form.vendedor_id)?.label || "" },
          { label: "Sucursal", value: sucursales.find((s) => s.id === form.sucursal_id)?.label || "" },
          { label: "Moneda", value: monedaCodigo },
          { label: "Vigencia", value: form.fecha_vigencia ? fmtFechaCalendario(form.fecha_vigencia) : "" },
          { label: "Condición de pago", value: condicionOpts.find((c) => c.id === form.condicion_pago_id)?.label || "" },
        ]}
        items={form.items
          .map((it, i) => {
            const bruto = (Number(it.precio_unitario) || 0) * (Number(it.cantidad) || 0);
            const subtotal = Number(itemsCalc?.[i]?.subtotal_con_iva) || 0;
            return {
              descripcion: it.descripcion,
              cantidad: Number(it.cantidad) || 0,
              precio: Number(it.precio_unitario) || 0,
              iva: it.iva_categoria === "IVA_10" ? 10 : it.iva_categoria === "IVA_5" ? 5 : "",
              descuento: Math.max(bruto - subtotal, 0),
              total: subtotal,
              _visible: !!it.descripcion?.trim(),
            };
          })
          .filter((r) => r._visible)}
        totales={[
          { label: "Total Bruto", value: totals.total_bruto },
          descPctEfectivo > 0
            ? { label: `Desc. Global (${Math.round(descPctEfectivo * 100) / 100}%)`, value: -totals.descuento_global_monto, color: "warning.main" }
            : null,
          { label: "Total IVA", value: totalIva },
          { label: "TOTAL OPERACIÓN", value: totals.total, fuerte: true, color: "primary.main" },
        ]}
        notas={form.notas_cliente}
      />
    </FormPanel>
  );
}

function SummaryDivider() {
  return <Box sx={{ borderTop: "1px dashed", borderColor: "divider", my: 0.2 }} />;
}

function SummaryRow({ label, value, main = false }) {
  return (
    <Stack direction="row" justifyContent="space-between" alignItems="center" gap={1}>
      <Typography sx={{ fontSize: main ? { xs: "1rem", sm: "1.08rem" } : "0.95rem", fontWeight: main ? 800 : 500, letterSpacing: main ? 0.3 : 0 }}>
        {label}
      </Typography>
      <Typography sx={{ fontSize: main ? { xs: "1.55rem", sm: "2rem" } : "1rem", fontWeight: main ? 800 : 700, lineHeight: 1, color: main ? "primary.main" : "text.primary" }}>
        {value}
      </Typography>
    </Stack>
  );
}
