"use client";

import { useEffect, useMemo, useState, use } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import {
  ArrowLeft, Save, User, Phone, MapPin, Calendar, Banknote, FileText,
  Bell, Pencil, Trash2, AlertTriangle, X, Camera,
} from "lucide-react";
import { motion } from "framer-motion";
import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input";
import RoleGate from "@/components/auth/RoleGate";
import CortesEditor from "@/components/cortes/CortesEditor";
import CommercialItemsEditor from "@/components/presupuestos/CommercialItemsEditor";
import PaymentsPanel from "@/components/pagos/PaymentsPanel";
import PedidoTareaTipo from "@/components/pedidos/PedidoTareaTipo";
import PedidoConsultas from "@/components/pedidos/PedidoConsultas";
import { getPB } from "@/lib/pocketbase";
import { getPedido, updatePedido, cancelPedido, deletePedido } from "@/lib/pb/pedidos";
import { archiveCorteJobForPedido, listCorteItemsForPedido, replacePedidoCortes } from "@/lib/pb/cortes";
import { listPedidoItems, pedidoItemToDraft, replacePedidoItems } from "@/lib/pb/pedido-items";
import { listPagosForPedido } from "@/lib/pb/pagos";
import { corteItemToDraft, isMeaningfulCorteDraft } from "@/lib/cortes/drafts";
import { completeCorteDrafts, hasIncompleteCorteDrafts } from "@/lib/cortes/progress";
import { summarizeCommercialItems } from "@/lib/presupuestos/domain";
import { useUnsavedChangesGuard } from "@/lib/useUnsavedChangesGuard";
import type { CorteItemDraft } from "@/lib/cortes/types";
import type { Cliente } from "@/lib/types/pedido";

type ClienteDraft = {
  nombre: string;
  celular: string;
  direccion: string;
  notas: string;
  tipo_cliente: "persona" | "empresa";
  documento_tipo: "dni" | "cuil" | "cuit";
  documento_numero: string;
  razon_social: string;
  contacto_nombre: string;
  contacto_celular: string;
};

const EMPTY_DRAFT: ClienteDraft = {
  nombre: "",
  celular: "",
  direccion: "",
  notas: "",
  tipo_cliente: "persona",
  documento_tipo: "dni",
  documento_numero: "",
  razon_social: "",
  contacto_nombre: "",
  contacto_celular: "",
};
import {
  ESTADO_PEDIDO_LABELS, ESTADO_CORTES_LABELS,
  type Pedido, type PedidoItemDraft, type EstadoPedido, type EstadoCortes,
} from "@/lib/types/pedido";
import { PIPELINE_LABELS, inferEtapaProduccion, type EtapaProduccion, mapEtapaToEstadoPedido } from "@/lib/pedidos/pipeline";
import type { Pago } from "@/lib/types/pago";
import { EstadoPedidoBadge, EstadoCortesBadge } from "@/components/pedidos/EstadoBadge";
import PhotoCapture from "@/components/pedidos/PhotoCapture";
import { money, dateInputValue, dateLong, celularToWaMe, stripArgCelularPrefix, normalizeCelular } from "@/lib/format";

export default function PedidoDetailPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = use(params);
  const router = useRouter();

  const [pedido, setPedido] = useState<Pedido | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState("");
  const [showCancel, setShowCancel] = useState(false);
  const [cancelReason, setCancelReason] = useState("");
  const [savedSnapshot, setSavedSnapshot] = useState("");

  const [showClienteModal, setShowClienteModal] = useState(false);
  const [clienteDraft, setClienteDraft] = useState<ClienteDraft>(EMPTY_DRAFT);
  const [clienteSaving, setClienteSaving] = useState(false);
  const [clienteErr, setClienteErr] = useState("");

  const cliente = pedido?.expand?.cliente;

  function openClienteModal() {
    if (!cliente) return;
    setClienteDraft({
      nombre: cliente.nombre || "",
      celular: stripArgCelularPrefix(cliente.celular),
      direccion: cliente.direccion || "",
      notas: cliente.notas || "",
      tipo_cliente: cliente.tipo_cliente || "persona",
      documento_tipo: cliente.documento_tipo || "dni",
      documento_numero: cliente.documento_numero || "",
      razon_social: cliente.razon_social || "",
      contacto_nombre: cliente.contacto_nombre || "",
      contacto_celular: stripArgCelularPrefix(cliente.contacto_celular),
    });
    setClienteErr("");
    setShowClienteModal(true);
  }

  async function saveClienteModal() {
    if (!cliente || !clienteDraft.nombre.trim()) return;
    setClienteSaving(true);
    setClienteErr("");
    try {
      const payload = {
        nombre: clienteDraft.nombre.trim(),
        celular: normalizeCelular(clienteDraft.celular.trim()),
        direccion: clienteDraft.direccion.trim(),
        notas: clienteDraft.notas,
        tipo_cliente: clienteDraft.tipo_cliente,
        documento_tipo: clienteDraft.documento_tipo,
        documento_numero: clienteDraft.documento_numero.trim(),
        razon_social: clienteDraft.razon_social.trim(),
        contacto_nombre: clienteDraft.contacto_nombre.trim(),
        contacto_celular: normalizeCelular(clienteDraft.contacto_celular.trim()),
      };
      const updated = await getPB().collection("clientes").update<Cliente>(cliente.id, payload);
      setPedido((prev) => prev ? {
        ...prev,
        expand: {
          ...prev.expand,
          cliente: updated
        }
      } : null);
      setShowClienteModal(false);
    } catch (e) {
      setClienteErr((e as Error).message || "No se pudo guardar cliente");
    } finally {
      setClienteSaving(false);
    }
  }

  // editable fields
  const [fechaPedido, setFechaPedido] = useState("");
  const [fechaEntrega, setFechaEntrega] = useState("");
  const [fechaEntregaHasta, setFechaEntregaHasta] = useState("");
  const [entregaDesde, setEntregaDesde] = useState("");
  const [entregaHasta, setEntregaHasta] = useState("");
  const [total, setTotal] = useState("");
  const [descripcion, setDescripcion] = useState("");
  const [estadoPedido, setEstadoPedido] = useState<EstadoPedido>("cargado");
  const [estadoCortes, setEstadoCortes] = useState<EstadoCortes>("no_necesita");
  const [etapaProduccion, setEtapaProduccion] = useState<EtapaProduccion>("pedido_nuevo");
  const [avisado, setAvisado] = useState(false);
  const [hayQueMedir, setHayQueMedir] = useState(false);
  const [hayQueEnviar, setHayQueEnviar] = useState(false);
  const [hayQueInstalar, setHayQueInstalar] = useState(false);
  const [requierePintura, setRequierePintura] = useState(false);
  const [urgente, setUrgente] = useState(false);
  const [cortes, setCortes] = useState<CorteItemDraft[]>([]);
  const [pedidoItems, setPedidoItems] = useState<PedidoItemDraft[]>([]);
  const [pagos, setPagos] = useState<Pago[]>([]);

  useEffect(() => {
    (async () => {
      try {
        const p = await getPedido(id);
        const [items, comerciales, pagosList] = await Promise.all([
          listCorteItemsForPedido(id),
          listPedidoItems(id),
          listPagosForPedido(id),
        ]);
        setPedido(p);
        setFechaPedido(dateInputValue(p.fecha_creacion));
        setFechaEntrega(dateInputValue(p.fecha_entrega_estimada));
        setFechaEntregaHasta(dateInputValue(p.fecha_entrega_hasta));
        setTotal(p.total?.toString() ?? "");
        setDescripcion(p.descripcion ?? "");
        setEstadoPedido(p.estado_pedido);
        setEstadoCortes(p.estado_cortes);
        setEtapaProduccion(p.etapa_produccion || inferEtapaProduccion(p));
        setAvisado(p.avisado_retiro);
        setHayQueMedir(!!p.hay_que_medir);
        setHayQueEnviar(!!p.hay_que_enviar);
        setHayQueInstalar(!!p.hay_que_instalar);
        setRequierePintura(!!p.requiere_pintura);
        setUrgente(!!p.urgente);
        setCortes(items.map(corteItemToDraft));
        setPedidoItems(comerciales.map(pedidoItemToDraft));
        setPagos(pagosList);
        
        setSavedSnapshot(buildPedidoSnapshot({
          fechaPedido: dateInputValue(p.fecha_creacion),
          fechaEntrega: dateInputValue(p.fecha_entrega_estimada),
          fechaEntregaHasta: dateInputValue(p.fecha_entrega_hasta),
          total: p.total?.toString() ?? "",
          descripcion: p.descripcion ?? "",
          estadoPedido: p.estado_pedido,
          estadoCortes: p.estado_cortes,
          etapaProduccion: p.etapa_produccion || inferEtapaProduccion(p),
          avisado: p.avisado_retiro,
          hayQueMedir: !!p.hay_que_medir,
          hayQueEnviar: !!p.hay_que_enviar,
          hayQueInstalar: !!p.hay_que_instalar,
          requierePintura: !!p.requiere_pintura,
          cortes: items.map(corteItemToDraft),
          pedidoItems: comerciales.map(pedidoItemToDraft),
        }));
      } catch (e) {
        setErr((e as Error).message || "No se pudo cargar el pedido");
      } finally {
        setLoading(false);
      }
    })();
  }, [id]);

  async function reloadPagos() {
    const [updated, pagosList] = await Promise.all([
      getPedido(id),
      listPagosForPedido(id),
    ]);
    setPedido(updated);
    setPagos(pagosList);
    setTotal((updated.total || 0).toString());
  }

  const totalN = parseFloat(total) || 0;
  const itemsTotal = summarizeCommercialItems(pedidoItems).total;
  // La seña es siempre la suma de los pagos (read-only). Se gestiona desde el panel de pagos.
  const pagosTotal = pagos.reduce((sum, pago) => sum + (pago.monto || 0), 0);
  const effectiveTotal = itemsTotal > 0 ? itemsTotal : totalN;
  const saldo = Math.max(0, effectiveTotal - pagosTotal);
  const currentSnapshot = useMemo(() => buildPedidoSnapshot({
    fechaPedido,
    fechaEntrega,
    fechaEntregaHasta,
    total,
    descripcion,
    estadoPedido,
    estadoCortes,
    etapaProduccion,
    avisado,
    hayQueMedir,
    hayQueEnviar,
    hayQueInstalar,
    requierePintura,
    cortes,
    pedidoItems,
  }), [
    fechaPedido,
    fechaEntrega,
    fechaEntregaHasta,
    total,
    descripcion,
    estadoPedido,
    estadoCortes,
    etapaProduccion,
    avisado,
    hayQueMedir,
    hayQueEnviar,
    hayQueInstalar,
    requierePintura,
    cortes,
    pedidoItems,
  ]);
  const hasUnsavedChanges = !!savedSnapshot && currentSnapshot !== savedSnapshot;

  function applyDeliveryRange(fromDays: string, toDays: string) {
    setEntregaDesde(fromDays);
    setEntregaHasta(toDays);
    const from = parseInt(fromDays, 10);
    const to = parseInt(toDays || fromDays, 10);
    if (Number.isFinite(from) && from >= 0) setFechaEntrega(addDaysInputValue(from));
    if (!Number.isFinite(to) || to < 0) return;
    setFechaEntregaHasta(addDaysInputValue(to));
  }

  const triggerGuard = useUnsavedChangesGuard(hasUnsavedChanges && !saving, save);

  function leaveTo(path: string) {
    triggerGuard(path);
  }

  async function save() {
    if (!pedido) return;
    let nextCortes = cortes;
    let nextEstadoCortes = estadoCortes;
    const meaningfulCortes = cortes.filter(isMeaningfulCorteDraft);
    const shouldCloseCortes = estadoPedido === "entregado";

    if (shouldCloseCortes && meaningfulCortes.length === 0) {
      nextEstadoCortes = "no_necesita";
    } else if (shouldCloseCortes && meaningfulCortes.length > 0) {
      if (hasIncompleteCorteDrafts(meaningfulCortes)) {
        const ok = confirm(
          "Hay cortes pendientes o cantos sin marcar. Si entregas el pedido, se marcaran todos como hechos y se archivara la lista de cortes. Confirmar?",
        );
        if (!ok) return;
      }
      nextCortes = completeCorteDrafts(cortes);
      nextEstadoCortes = "cortados";
    }

    setSaving(true);
    setErr("");
    try {
      const nextEtapaProduccion = shouldCloseCortes
        ? (saldo > 0 ? "entregado_con_saldo" : "entregado_sin_saldo")
        : etapaProduccion;
      const nextEstadoPedido = mapEtapaToEstadoPedido(nextEtapaProduccion);
      const updated = await updatePedido(pedido.id, {
        fecha_creacion: fechaPedido ? new Date(fechaPedido + "T00:00:00").toISOString() : pedido.fecha_creacion,
        fecha_entrega_estimada: fechaEntrega || undefined,
        fecha_entrega_hasta: fechaEntregaHasta || undefined,
        total: effectiveTotal,
        pagado: pagosTotal,
        senia: pagosTotal,
        descripcion,
        estado_pedido: nextEstadoPedido,
        estado_cortes: nextEstadoCortes,
        etapa_produccion: nextEtapaProduccion,
        avisado_retiro: avisado,
        hay_que_medir: hayQueMedir,
        hay_que_enviar: hayQueEnviar,
        hay_que_instalar: hayQueInstalar,
        requiere_pintura: requierePintura,
      });
      await replacePedidoItems(pedido.id, pedidoItems);
      await replacePedidoCortes(updated, nextCortes);
      if (shouldCloseCortes && meaningfulCortes.length > 0) {
        await archiveCorteJobForPedido(updated.id);
      }
      setPedido(updated);
      setCortes(nextCortes);
      setEstadoCortes(nextEstadoCortes);
      setEtapaProduccion(nextEtapaProduccion);
      setEstadoPedido(updated.estado_pedido);
      setSavedSnapshot(buildPedidoSnapshot({
        fechaPedido,
        fechaEntrega,
        fechaEntregaHasta,
        total,
        descripcion,
        estadoPedido: updated.estado_pedido,
        estadoCortes: nextEstadoCortes,
        etapaProduccion: nextEtapaProduccion,
        avisado,
        hayQueMedir,
        hayQueEnviar,
        hayQueInstalar,
        requierePintura,
        cortes: nextCortes,
        pedidoItems,
      }));
    } catch (e) {
      setErr((e as Error).message || "No se pudo guardar");
    } finally {
      setSaving(false);
    }
  }

  async function doCancel() {
    if (!pedido || !cancelReason.trim()) return;
    setSaving(true);
    try {
      const updated = await cancelPedido(pedido.id, cancelReason.trim());
      setPedido(updated);
      setEstadoPedido("cancelado");
      setShowCancel(false);
    } catch (e) {
      setErr((e as Error).message || "No se pudo cancelar");
    } finally {
      setSaving(false);
    }
  }

  async function doDelete() {
    if (!pedido) return;
    const label = pedido.numero ? `#${pedido.numero}` : "borrador";
    if (!confirm(`¿Borrar definitivamente el pedido ${label}? Esta acción no se puede deshacer.`)) return;
    setSaving(true);
    try {
      await deletePedido(pedido.id);
      router.replace("/pedidos");
    } catch (e) {
      setErr((e as Error).message || "No se pudo borrar");
      setSaving(false);
    }
  }

  async function toggleUrgente() {
    if (!pedido) return;
    const next = !urgente;
    setUrgente(next);
    try {
      await updatePedido(pedido.id, { urgente: next });
    } catch {
      setUrgente(!next);
    }
  }

  if (loading) {
    return <div className="text-center text-faint py-12">Cargando pedido…</div>;
  }
  if (!pedido) {
    return <div className="text-center text-bad py-12">{err || "Pedido no encontrado"}</div>;
  }

  const pedidoLabel = pedido.codigo || (pedido.numero ? `#${pedido.numero}` : "Borrador");

  return (
    <div className="max-w-5xl">
      <div className="flex items-center gap-3 mb-6">
        <button type="button" onClick={() => leaveTo("/pedidos")} className="text-ink-soft hover:text-ink">
          <ArrowLeft size={20} />
        </button>
        <div className="flex-1">
          <div className="flex items-center gap-3">
            <h1 className="text-2xl font-extrabold text-ink">Pedido {pedidoLabel}</h1>
            <EstadoPedidoBadge value={pedido.estado_pedido} />
            <EstadoCortesBadge value={pedido.estado_cortes} />
          </div>
          <p className="text-sm text-ink-soft mt-0.5">
            Creado {dateLong(fechaPedido || pedido.fecha_creacion)}
            {pedido.expand?.created_by?.name ? ` por ${pedido.expand.created_by.name}` : ""}
          </p>
        </div>
        <Button onClick={save} loading={saving}>
          <Save size={16} /> Guardar cambios
        </Button>
      </div>

      {pedido.estado_pedido === "cancelado" && (
        <div className="mb-5 p-4 rounded-xl bg-red-50 border border-red-200 flex items-start gap-3">
          <AlertTriangle size={18} className="text-bad mt-0.5 flex-shrink-0" />
          <div>
            <strong className="text-bad">Pedido cancelado</strong>
            {pedido.cancelled_reason && (
              <p className="text-sm text-ink-soft mt-1">{pedido.cancelled_reason}</p>
            )}
          </div>
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-5">
        {/* Cliente (readonly view) */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          className="card p-5 lg:col-span-3 space-y-3"
        >
          <div className="flex items-center justify-between gap-3">
            <h2 className="font-bold text-ink flex items-center gap-2">
              <User size={16} /> Cliente
            </h2>
            {cliente && (
              <button
                type="button"
                onClick={openClienteModal}
                className="rounded-lg border border-line px-2.5 py-1.5 text-xs font-semibold text-ink-soft hover:text-ink"
              >
                Ver ficha
              </button>
            )}
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3 text-sm">
            <Field icon={User} label="Nombre">{cliente?.nombre || "—"}</Field>
            <Field icon={Phone} label="Celular">
              {cliente?.celular ? (
                <span className="flex items-center gap-2">
                  <span>{cliente.celular}</span>
                  {celularToWaMe(cliente.celular) && (
                    <a
                      href={celularToWaMe(cliente.celular)!}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-[#25D366] hover:text-[#128C7E] transition-colors"
                      title="Chatear por WhatsApp"
                    >
                      <WaIcon size={17} />
                    </a>
                  )}
                </span>
              ) : "—"}
            </Field>
            <Field icon={MapPin} label="Dirección">{cliente?.direccion || "—"}</Field>
          </div>
        </motion.section>

        {/* Estado editable */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.04 }}
          className="card p-5 lg:col-span-3 space-y-4"
        >
          <h2 className="font-bold text-ink">Estado</h2>
          <button
            type="button"
            onClick={toggleUrgente}
            className={`flex w-full items-center gap-2 rounded-xl border px-3 py-2.5 text-sm font-bold transition-colors ${
              urgente
                ? "border-red-300 bg-red-100 text-red-800"
                : "border-line bg-canvas text-ink-soft hover:text-ink"
            }`}
          >
            <AlertTriangle size={16} className={urgente ? "text-red-600" : "text-faint"} />
            {urgente ? "Pedido URGENTE" : "Marcar como urgente"}
          </button>
          <SelectField
            label="Estado del pedido"
            value={estadoPedido}
            onChange={(v) => setEstadoPedido(v as EstadoPedido)}
            disabled
            options={Object.entries(ESTADO_PEDIDO_LABELS).map(([v, l]) => ({ v, l }))}
          />
          <SelectField
            label="Estado de cortes"
            value={estadoCortes}
            onChange={(v) => setEstadoCortes(v as EstadoCortes)}
            options={Object.entries(ESTADO_CORTES_LABELS).map(([v, l]) => ({ v, l }))}
          />
          <SelectField
            label="Pipeline de produccion"
            value={etapaProduccion}
            onChange={(v) => {
              const nextEtapa = v as EtapaProduccion;
              setEtapaProduccion(nextEtapa);
              setEstadoPedido(mapEtapaToEstadoPedido(nextEtapa));
            }}
            options={Object.entries(PIPELINE_LABELS).map(([v, l]) => ({ v, l }))}
          />
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={avisado}
              onChange={(e) => setAvisado(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <Bell size={16} className="text-ink-soft" />
            <span className="text-sm text-ink">Avisado para retirar/enviar</span>
          </label>
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={hayQueMedir}
              onChange={(e) => setHayQueMedir(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Hay que medir en el lugar</span>
          </label>
          {hayQueMedir && <PedidoTareaTipo pedidoId={pedido.id} tipo="medir" label="Medir" />}
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={hayQueEnviar}
              onChange={(e) => setHayQueEnviar(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Hay que enviar el pedido</span>
          </label>
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={hayQueInstalar}
              onChange={(e) => setHayQueInstalar(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Requiere instalación</span>
          </label>
          {hayQueInstalar && <PedidoTareaTipo pedidoId={pedido.id} tipo="instalar" label="Instalar" />}
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={requierePintura}
              onChange={(e) => setRequierePintura(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Requiere pintura</span>
          </label>
        </motion.section>

        {/* Consultas y reclamos */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.06 }}
          className="card p-5 lg:col-span-3"
        >
          <PedidoConsultas pedidoId={pedido.id} />
        </motion.section>

        {/* Detalle */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.08 }}
          className="card p-5 lg:col-span-3 space-y-4"
        >
          <h2 className="font-bold text-ink flex items-center gap-2">
            <FileText size={16} /> Detalle del trabajo
          </h2>
          <div>
            <label className="text-sm font-medium text-ink-soft mb-1.5 block">Descripción</label>
            <textarea
              value={descripcion}
              onChange={(e) => setDescripcion(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter" && e.shiftKey) e.stopPropagation();
              }}
              rows={6}
              className="w-full px-3 py-2.5 rounded-xl bg-surface border border-line focus:border-brand outline-none text-ink resize-y"
            />
          </div>
          <CommercialItemsEditor items={pedidoItems} onChange={setPedidoItems} title="Productos del pedido" />
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
            <Input label="Fecha del pedido" type="date" value={fechaPedido}
              onChange={(e) => setFechaPedido(e.target.value)} prefix={<Calendar size={16} />} />
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
            <Input label="Total (calculado)" type="number" inputMode="decimal" value={effectiveTotal.toString()}
              readOnly disabled prefix={<Banknote size={16} />} />
            <div>
              <span className="text-sm font-medium text-ink-soft block mb-1.5">Seña (suma de pagos)</span>
              <div className="h-11 px-3 rounded-xl bg-canvas border border-line flex items-center gap-2 font-bold text-ink" title="Se calcula automáticamente con los pagos cargados abajo. No se edita a mano.">
                <Banknote size={16} className="text-faint" />
                {money(pagosTotal)}
              </div>
            </div>
            <div>
              <span className="text-sm font-medium text-ink-soft block mb-1.5">Saldo</span>
              <div className={`h-11 px-3 rounded-xl bg-canvas border border-line flex items-center font-bold ${saldo > 0 ? "text-bad" : "text-good"}`}>
                {money(saldo)}
              </div>
            </div>
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <Input label="Entrega desde" type="date" value={fechaEntrega}
              onChange={(e) => setFechaEntrega(e.target.value)} prefix={<Calendar size={16} />} />
            <Input label="Entrega hasta" type="date" value={fechaEntregaHasta}
              onChange={(e) => setFechaEntregaHasta(e.target.value)} prefix={<Calendar size={16} />} />
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <Input label="Desde días" type="number" min="0" inputMode="numeric" value={entregaDesde}
              onChange={(e) => applyDeliveryRange(e.target.value, entregaHasta)} placeholder="Ej: 15" />
            <Input label="Hasta días" type="number" min="0" inputMode="numeric" value={entregaHasta}
              onChange={(e) => applyDeliveryRange(entregaDesde, e.target.value)} placeholder="Ej: 25" />
          </div>
        </motion.section>

        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.09 }}
          className="card p-5 lg:col-span-3"
        >
          <PaymentsPanel
            clienteId={pedido.cliente}
            pedidoId={pedido.id}
            pagos={pagos}
            onChanged={reloadPagos}
          />
        </motion.section>

        {/* Cortes */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.1 }}
          className="card p-4 lg:col-span-3"
        >
          <CortesEditor items={cortes} onChange={setCortes} />
        </motion.section>

        {/* Fotos del croquis */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.12 }}
          className="card p-5 lg:col-span-3"
        >
          <h2 className="font-bold text-ink flex items-center gap-2 mb-3">
            <Camera size={16} /> Fotos del croquis
          </h2>
          <p className="text-xs text-faint mb-3">
            Sacá una foto del dibujo en papel (o subila desde la galería). Podés agregar varias.
          </p>
          <PhotoCapture pedido={pedido} onServerChange={(p) => setPedido(p)} />
        </motion.section>

        {/* Actions */}
        <div className="lg:col-span-3 flex items-center justify-between gap-3 pt-2 flex-wrap">
          <div className="flex gap-2">
            {pedido.estado_pedido !== "cancelado" && (
              <Button variant="secondary" onClick={() => setShowCancel(true)}>
                <AlertTriangle size={16} /> Cancelar pedido
              </Button>
            )}
            <RoleGate role="admin">
              <Button variant="danger" onClick={doDelete} loading={saving}>
                <Trash2 size={16} /> Borrar
              </Button>
            </RoleGate>
          </div>
          <div className="flex items-center gap-3 ml-auto">
            {err && <span className="text-sm font-medium text-bad">{err}</span>}
            <Button onClick={save} size="lg" loading={saving}>
              <Save size={18} /> Guardar cambios
            </Button>
          </div>
        </div>
      </div>

      {showCancel && (
        <div className="fixed inset-0 bg-black/40 grid place-items-center p-5 z-20" onClick={() => setShowCancel(false)}>
          <motion.div
            initial={{ opacity: 0, scale: 0.95 }}
            animate={{ opacity: 1, scale: 1 }}
            className="card p-6 max-w-md w-full shadow-[var(--shadow-lg)]"
            onClick={(e) => e.stopPropagation()}
          >
            <h3 className="font-bold text-ink mb-2">Cancelar pedido {pedidoLabel}</h3>
            <p className="text-sm text-ink-soft mb-4">
              El pedido se marca como cancelado pero queda en el historial. Si querés borrarlo de verdad, pedile a un admin.
            </p>
            <label className="text-sm font-medium text-ink-soft block mb-1.5">Motivo</label>
            <textarea
              value={cancelReason}
              onChange={(e) => setCancelReason(e.target.value)}
              rows={3}
              className="w-full px-3 py-2.5 rounded-xl bg-surface border border-line focus:border-brand outline-none text-ink resize-y mb-4"
              placeholder="Ej: cliente no respondió, se cambió por otro pedido…"
              autoFocus
            />
            <div className="flex gap-2 justify-end">
              <Button variant="secondary" onClick={() => setShowCancel(false)}>Atrás</Button>
              <Button variant="danger" onClick={doCancel} loading={saving} disabled={!cancelReason.trim()}>
                Confirmar cancelación
              </Button>
            </div>
          </motion.div>
        </div>
      )}

      {showClienteModal && (
        <div className="fixed inset-0 z-40 grid place-items-center bg-black/35 p-4" onClick={() => setShowClienteModal(false)}>
          <div className="max-h-[92dvh] w-full max-w-2xl overflow-auto rounded-xl border border-line bg-surface p-5 shadow-[var(--shadow-lg)]" onClick={(e) => e.stopPropagation()}>
            <div className="mb-4 flex items-center justify-between gap-3">
              <h2 className="text-lg font-extrabold text-ink font-bold">Ficha cliente</h2>
              <button type="button" onClick={() => setShowClienteModal(false)} className="rounded-lg p-1.5 text-faint hover:text-ink">
                <X size={18} />
              </button>
            </div>
            <div className="grid gap-3">
              <Input label="Nombre" value={clienteDraft.nombre} onChange={(e) => setClienteDraft(d => ({ ...d, nombre: e.target.value }))} />
              <Input label="Celular" prefix={<span className="text-sm font-medium text-ink-soft select-none">+549</span>} placeholder="2915114902" value={clienteDraft.celular} onChange={(e) => setClienteDraft(d => ({ ...d, celular: e.target.value }))} />
              <Input label="Direccion" value={clienteDraft.direccion} onChange={(e) => setClienteDraft(d => ({ ...d, direccion: e.target.value }))} />
              <div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
                <label className="flex flex-col gap-1.5">
                  <span className="text-sm font-medium text-ink-soft">Tipo</span>
                  <select value={clienteDraft.tipo_cliente} onChange={(e) => setClienteDraft(d => ({ ...d, tipo_cliente: e.target.value as ClienteDraft["tipo_cliente"] }))} className="h-11 rounded-xl border border-line bg-surface px-3 text-sm text-ink outline-none focus:border-brand">
                    <option value="persona">Persona</option>
                    <option value="empresa">Empresa</option>
                  </select>
                </label>
                <label className="flex flex-col gap-1.5">
                  <span className="text-sm font-medium text-ink-soft">Documento</span>
                  <select value={clienteDraft.documento_tipo} onChange={(e) => setClienteDraft(d => ({ ...d, documento_tipo: e.target.value as ClienteDraft["documento_tipo"] }))} className="h-11 rounded-xl border border-line bg-surface px-3 text-sm text-ink outline-none focus:border-brand">
                    <option value="dni">DNI</option>
                    <option value="cuil">CUIL</option>
                    <option value="cuit">CUIT</option>
                  </select>
                </label>
                <Input label="Numero" value={clienteDraft.documento_numero} onChange={(e) => setClienteDraft(d => ({ ...d, documento_numero: e.target.value }))} />
              </div>
              {clienteDraft.tipo_cliente === "empresa" && (
                <div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
                  <Input label="Razon social" value={clienteDraft.razon_social} onChange={(e) => setClienteDraft(d => ({ ...d, razon_social: e.target.value }))} />
                  <Input label="Contacto" value={clienteDraft.contacto_nombre} onChange={(e) => setClienteDraft(d => ({ ...d, contacto_nombre: e.target.value }))} />
                  <Input label="Celular contacto" prefix={<span className="text-sm font-medium text-ink-soft select-none">+549</span>} placeholder="2915114902" value={clienteDraft.contacto_celular} onChange={(e) => setClienteDraft(d => ({ ...d, contacto_celular: e.target.value }))} />
                </div>
              )}
              <label className="flex flex-col gap-1.5">
                <span className="text-sm font-medium text-ink-soft">Notas</span>
                <textarea
                  value={clienteDraft.notas}
                  onChange={(e) => setClienteDraft(d => ({ ...d, notas: e.target.value }))}
                  rows={4}
                  className="rounded-xl border border-line bg-surface px-3 py-2 text-sm text-ink outline-none focus:border-brand"
                />
              </label>
            </div>
            {clienteErr && <p className="mt-3 text-sm text-bad">{clienteErr}</p>}
            <div className="mt-5 flex justify-end gap-2">
              <Button type="button" variant="secondary" onClick={() => setShowClienteModal(false)}>Cerrar</Button>
              <Button type="button" onClick={saveClienteModal} loading={clienteSaving}>
                <Save size={16} /> Guardar
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function addDaysInputValue(days: number): string {
  const d = new Date();
  d.setDate(d.getDate() + days);
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

function buildPedidoSnapshot(value: {
  fechaPedido: string;
  fechaEntrega: string;
  fechaEntregaHasta: string;
  total: string;
  descripcion: string;
  estadoPedido: EstadoPedido;
  estadoCortes: EstadoCortes;
  etapaProduccion: EtapaProduccion;
  avisado: boolean;
  hayQueMedir: boolean;
  hayQueEnviar: boolean;
  hayQueInstalar: boolean;
  requierePintura: boolean;
  cortes: CorteItemDraft[];
  pedidoItems: PedidoItemDraft[];
}) {
  return JSON.stringify(value);
}

function WaIcon({ size = 16 }: { size?: number }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" aria-hidden>
      <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/>
    </svg>
  );
}

function Field({
  icon: Icon, label, children,
}: {
  icon: typeof User; label: string; children: React.ReactNode;
}) {
  return (
    <div>
      <span className="text-xs text-faint uppercase tracking-wider flex items-center gap-1.5 mb-0.5">
        <Icon size={11} /> {label}
      </span>
      <p className="text-ink font-medium">{children}</p>
    </div>
  );
}

function SelectField({
  label, value, onChange, options, disabled,
}: {
  label: string; value: string; onChange: (v: string) => void;
  options: { v: string; l: string }[];
  disabled?: boolean;
}) {
  return (
    <label className="flex flex-col gap-1.5">
      <span className="text-sm font-medium text-ink-soft">{label}</span>
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        className="h-11 px-3 rounded-xl bg-surface border border-line focus:border-brand outline-none text-ink disabled:bg-canvas disabled:text-ink-soft disabled:cursor-not-allowed"
      >
        {options.map((o) => (
          <option key={o.v} value={o.v}>{o.l}</option>
        ))}
      </select>
    </label>
  );
}
