import { useState, useEffect, useMemo, useRef } from "react";
import {
  Droplets, Users, Car, UserRound, Wallet, Plus, X, Check,
  Clock, TrendingUp, Search, Trash2, Pencil, ChevronRight,
  Sparkles, Banknote, CreditCard, ArrowRightLeft, Receipt, Scale,
  Package, PackagePlus, PackageMinus, AlertTriangle, Settings,
  ArrowLeft, CalendarDays, CalendarCheck, CalendarX, PlayCircle,
  LogOut, ShieldCheck, Activity, Gift, Minus, PartyPopper, Download,
  StickyNote, FileText, Share2, Printer, Star, UserX, History, Repeat,
  Bell, BarChart3, PiggyBank, ArrowDownCircle, ArrowUpCircle
} from "lucide-react";

const STORAGE_KEY = "autolavado-data";
const SESION_KEY = "autolavado-sesion";
const SUCURSAL_KEY = "autolavado-sucursal";

const DEFAULT_TIPOS_SERVICIO = [
  { nombre: "Lavado Básico", precio: 80 },
  { nombre: "Lavado Premium", precio: 130 },
  { nombre: "Lavado y Encerado", precio: 180 },
  { nombre: "Aspirado", precio: 50 },
  { nombre: "Lavado de Motor", precio: 100 },
  { nombre: "Detallado Completo", precio: 350 },
];

const DEFAULT_ADICIONALES = [
  { nombre: "Cera", precio: 50 },
  { nombre: "Lavado de Motor", precio: 100 },
  { nombre: "Aromatizante", precio: 30 },
  { nombre: "Brillo de llantas", precio: 40 },
];

const METODOS_PAGO = [
  { id: "efectivo", label: "Efectivo", icon: Banknote },
  { id: "tarjeta", label: "Tarjeta", icon: CreditCard },
  { id: "transferencia", label: "Transferencia", icon: ArrowRightLeft },
];

const CATEGORIAS_GASTO = [
  "Insumos y jabones",
  "Sueldos",
  "Renta",
  "Agua y luz",
  "Mantenimiento de equipo",
  "Otro",
];

const UNIDADES = ["piezas", "litros", "galones", "kg", "paquetes", "botes"];

const TIPOS_VEHICULO = ["Sedán", "Hatchback", "SUV", "Pickup", "Van/Camioneta", "Motocicleta"];

const todayStr = () => new Date().toISOString().split("T")[0];
// determina si un registro pertenece a la sucursal activa (los registros viejos sin sucursal se asignan a la primera)
const uid = () => Math.random().toString(36).slice(2, 10);
const pertenece = (item, sucursalId, sucursales) => {
  const principal = sucursales && sucursales[0] ? sucursales[0].id : "suc-principal";
  return (item.sucursalId || principal) === sucursalId;
};

const DEFAULT_FIDELIDAD = [
  { id: "prog-5-50", nombre: "5 lavados", metaSellos: 5, premio: "50% de descuento" },
  { id: "prog-10-gratis", nombre: "10 lavados", metaSellos: 10, premio: "Un lavado gratis" },
];

// progreso de un cliente en un programa, con compatibilidad con la versión anterior (un solo contador "sellos")
const getSellos = (cliente, programa, index) => {
  if (cliente.progreso && typeof cliente.progreso[programa.id] === "number") return cliente.progreso[programa.id];
  if (index === 0 && typeof cliente.sellos === "number") return cliente.sellos;
  return 0;
};
const upsertCliente = (clientes, nombre, placas, tipoVehiculo) => {
  const nombreLimpio = nombre.trim();
  const idx = clientes.findIndex((c) => c.nombre.trim().toLowerCase() === nombreLimpio.toLowerCase());
  if (idx === -1) {
    return [...clientes, { id: uid(), nombre: nombreLimpio, telefono: "", vehiculo: tipoVehiculo || "", placas: (placas || "").trim(), sellos: 0 }];
  }
  const copia = [...clientes];
  const existente = copia[idx];
  copia[idx] = {
    ...existente,
    placas: (placas || "").trim() || existente.placas,
    vehiculo: existente.vehiculo || tipoVehiculo || "",
    sellos: Number(existente.sellos) || 0,
  };
  return copia;
};
const money = (n) =>
  "$" + Number(n || 0).toLocaleString("es-MX", { maximumFractionDigits: 0 });
const fecha = (d) =>
  new Date(d + "T00:00:00").toLocaleDateString("es-MX", {
    weekday: "short",
    day: "numeric",
    month: "short",
  });
const duracionTexto = (ms) => {
  const min = Math.round(ms / 60000);
  if (min < 1) return "menos de 1 min";
  if (min < 60) return `${min} min`;
  const h = Math.floor(min / 60);
  const m = min % 60;
  return `${h}h ${m}min`;
};
// convierte un timestamp (ms) al formato que espera <input type="datetime-local">, en hora local
const tsToInputLocal = (ts) => {
  const d = new Date(ts);
  const pad = (n) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
};
const inputLocalToTs = (v) => new Date(v).getTime();
const tiempoRelativo = (ts) => {
  const diffMin = Math.round((Date.now() - ts) / 60000);
  if (diffMin < 1) return "justo ahora";
  if (diffMin < 60) return `hace ${diffMin} min`;
  const h = Math.round(diffMin / 60);
  if (h < 24) return `hace ${h} h`;
  const d = Math.round(h / 24);
  return `hace ${d} d`;
};
const tiempoHasta = (ts) => {
  const diffMin = Math.round((ts - Date.now()) / 60000);
  if (diffMin <= 0) return "ahora";
  if (diffMin < 60) return `en ${diffMin} min`;
  const h = Math.floor(diffMin / 60);
  const m = diffMin % 60;
  return m > 0 ? `en ${h}h ${m}min` : `en ${h}h`;
};
const diasEntre = (fechaA, fechaB) => Math.round((new Date(fechaB) - new Date(fechaA)) / 86400000);
const csvEscape = (val) => {
  const s = String(val ?? "");
  return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
};
const arrayToCsv = (rows, headers) => {
  const head = headers.map((h) => csvEscape(h.label)).join(",");
  const body = rows
    .map((r) => headers.map((h) => csvEscape(typeof h.value === "function" ? h.value(r) : r[h.value])).join(","))
    .join("\n");
  return head + "\n" + body;
};
const descargarArchivo = (nombre, contenido, tipo) => {
  const blob = new Blob([contenido], { type: tipo });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = nombre;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
};

const DEFAULT_SUCURSALES = [{ id: "suc-principal", nombre: "Sucursal Principal" }];
const DEFAULT_CARTERAS = [{ id: "cartera-insumos", nombre: "Insumos y productos", saldo: 0 }];

const emptyData = {
  nombreNegocio: "Mi Autolavado",
  metaDiaria: 1500,
  clientes: [],
  servicios: [],
  empleados: [],
  gastos: [],
  inventario: [],
  movimientosInventario: [],
  tiposServicio: DEFAULT_TIPOS_SERVICIO,
  serviciosAdicionales: DEFAULT_ADICIONALES,
  citas: [],
  actividad: [],
  adminPin: "",
  fidelidad: DEFAULT_FIDELIDAD,
  sucursales: DEFAULT_SUCURSALES,
  carteras: DEFAULT_CARTERAS,
  movimientosCartera: [],
  membresias: [],
};

export default function App() {
  const [data, setData] = useState(null);
  const [tab, setTab] = useState("dashboard");
  const [ready, setReady] = useState(false);
  const [err, setErr] = useState("");
  const [showConfig, setShowConfig] = useState(false);
  const [sesion, setSesion] = useState(null);
  const [sesionReady, setSesionReady] = useState(false);
  const [sucursalAdmin, setSucursalAdmin] = useState(null);

  useEffect(() => {
    (async () => {
      try {
        const res = await window.storage.get(STORAGE_KEY, true);
        const merged = res ? { ...emptyData, ...JSON.parse(res.value) } : emptyData;
        if (!Array.isArray(merged.fidelidad)) merged.fidelidad = DEFAULT_FIDELIDAD;
        if (!Array.isArray(merged.sucursales) || merged.sucursales.length === 0) merged.sucursales = DEFAULT_SUCURSALES;
        setData(merged);
      } catch {
        setData(emptyData);
      } finally {
        setReady(true);
      }
    })();
    (async () => {
      try {
        const res = await window.storage.get(SESION_KEY, false);
        setSesion(res ? JSON.parse(res.value) : null);
      } catch {
        setSesion(null);
      } finally {
        setSesionReady(true);
      }
    })();
    (async () => {
      try {
        const res = await window.storage.get(SUCURSAL_KEY, false);
        setSucursalAdmin(res ? res.value : null);
      } catch {
        setSucursalAdmin(null);
      }
    })();
  }, []);

  const save = async (next) => {
    setData(next);
    try {
      const ok = await window.storage.set(STORAGE_KEY, JSON.stringify(next), true);
      if (!ok) setErr("No se pudo guardar. Intenta de nuevo.");
      else setErr("");
    } catch {
      setErr("No se pudo guardar. Revisa tu conexión.");
    }
  };

  const elegirSesion = async (s) => {
    setSesion(s);
    setTab(s.rol === "lavador" ? "citas" : "dashboard");
    try {
      await window.storage.set(SESION_KEY, JSON.stringify(s), false);
    } catch {}
  };

  const cerrarSesion = async () => {
    setSesion(null);
    try {
      await window.storage.delete(SESION_KEY, false);
    } catch {}
  };

  const cambiarSucursal = async (id) => {
    setSucursalAdmin(id);
    try {
      await window.storage.set(SUCURSAL_KEY, id, false);
    } catch {}
  };

  // guarda cambios y registra actividad cuando quien edita es un lavador
  const saveConLog = (seccion) => (next) => {
    if (sesion?.rol === "lavador") {
      const entry = { id: uid(), usuario: sesion.nombre, seccion, fecha: Date.now() };
      const actividad = [entry, ...(data.actividad || [])].slice(0, 200);
      return save({ ...next, actividad });
    }
    return save(next);
  };

  if (!ready || !data || !sesionReady) {
    return (
      <div style={{ background: BG }} className="w-full h-full min-h-[600px] flex items-center justify-center">
        <Shell>
          <div className="flex flex-col items-center gap-3 text-teal-100">
            <Droplets className="animate-bounce" size={32} color={ACCENT} />
            <p className="text-sm tracking-wide" style={{ color: MUTED }}>
              Abriendo la llave de agua…
            </p>
          </div>
        </Shell>
      </div>
    );
  }

  if (!sesion) {
    return (
      <Shell>
        <FontStyles />
        <SeleccionUsuario data={data} onElegir={elegirSesion} />
      </Shell>
    );
  }

  const esLavador = sesion.rol === "lavador";
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const sucursalId = esLavador
    ? (data.empleados.find((e) => e.nombre === sesion.nombre)?.sucursalId || sucursales[0].id)
    : (sucursalAdmin && sucursales.find((s) => s.id === sucursalAdmin) ? sucursalAdmin : sucursales[0].id);

  return (
    <Shell>
      <FontStyles />
      <Header
        data={data}
        save={save}
        onConfig={() => setShowConfig(true)}
        sesion={sesion}
        onCerrarSesion={cerrarSesion}
        sucursales={sucursales}
        sucursalId={sucursalId}
        onCambiarSucursal={cambiarSucursal}
        esLavador={esLavador}
      />
      {err && (
        <div className="mx-4 mt-2 text-xs px-3 py-2 rounded-lg" style={{ background: "#3A1E1E", color: "#F4B0A0" }}>
          {err}
        </div>
      )}
      <div className="flex-1 overflow-y-auto pb-24 px-4 pt-3">
        {showConfig && !esLavador ? (
          <Configuracion data={data} save={save} onBack={() => setShowConfig(false)} />
        ) : (
          <>
            {!esLavador && tab === "dashboard" && <Dashboard data={data} save={save} sucursalId={sucursalId} />}
            {tab === "citas" && (
              <Citas
                data={data}
                save={esLavador ? saveConLog("Citas") : save}
                onIniciarServicio={() => setTab("servicios")}
                sucursalId={sucursalId}
              />
            )}
            {!esLavador && tab === "clientes" && <Clientes data={data} save={save} />}
            {!esLavador && tab === "fidelidad" && <Fidelidad data={data} save={save} />}
            {tab === "servicios" && (
              <Servicios
                data={data}
                save={esLavador ? saveConLog("Servicios") : save}
                sucursalId={sucursalId}
                miNombre={esLavador ? sesion.nombre : null}
              />
            )}
            {!esLavador && tab === "empleados" && <Empleados data={data} save={save} sucursalId={sucursalId} sucursales={sucursales} />}
            {tab === "ingresos" && <Finanzas data={data} save={esLavador ? saveConLog("Finanzas") : save} sucursalId={sucursalId} />}
            {tab === "inventario" && <Inventario data={data} save={esLavador ? saveConLog("Inventario") : save} sucursalId={sucursalId} />}
          </>
        )}
      </div>
      {!showConfig && <NavBar tab={tab} setTab={setTab} esLavador={esLavador} />}
    </Shell>
  );
}

/* ---------------- tema ---------------- */
const BG = "#0A2027";
const SURFACE = "#123138";
const SURFACE2 = "#17414B";
const ACCENT = "#35C9C1";
const GOLD = "#F4B740";
const TEXT = "#EAF6F6";
const MUTED = "#7FA8AE";
const DANGER = "#E4572E";

function Shell({ children }) {
  return (
    <div
      style={{ background: BG, fontFamily: "'Inter', sans-serif", color: TEXT }}
      className="w-full min-h-[640px] h-full flex flex-col rounded-2xl overflow-hidden relative"
    >
      {children}
    </div>
  );
}

function FontStyles() {
  return (
    <style>{`
      @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@500;700&display=swap');
      .font-display { font-family: 'Space Grotesk', sans-serif; }
      .font-mono { font-family: 'JetBrains Mono', monospace; }
      ::-webkit-scrollbar { width: 6px; }
      ::-webkit-scrollbar-thumb { background: ${SURFACE2}; border-radius: 4px; }
      input, select { background: ${SURFACE2}; color: ${TEXT}; }
      input::placeholder { color: ${MUTED}; }
      @keyframes wave-move { from { transform: translateX(0); } to { transform: translateX(-50%); } }
      .wave-anim { animation: wave-move 3.5s linear infinite; }
    `}</style>
  );
}

function Card({ children, className = "" }) {
  return (
    <div
      style={{ background: SURFACE, border: `1px solid ${SURFACE2}` }}
      className={`rounded-2xl p-4 ${className}`}
    >
      {children}
    </div>
  );
}

function Header({ data, save, onConfig, sesion, onCerrarSesion, sucursales, sucursalId, onCambiarSucursal, esLavador }) {
  const [editing, setEditing] = useState(false);
  const [name, setName] = useState(data.nombreNegocio);
  return (
    <div className="px-4 pt-4 pb-1 flex items-center justify-between">
      <div>
        {editing && !esLavador ? (
          <input
            autoFocus
            value={name}
            onChange={(e) => setName(e.target.value)}
            onBlur={() => {
              setEditing(false);
              save({ ...data, nombreNegocio: name || "Mi Autolavado" });
            }}
            onKeyDown={(e) => e.key === "Enter" && e.currentTarget.blur()}
            className="font-display text-lg font-bold rounded-lg px-2 py-1 outline-none"
            style={{ border: `1px solid ${ACCENT}` }}
          />
        ) : (
          <h1
            onClick={() => !esLavador && setEditing(true)}
            className="font-display text-lg font-bold flex items-center gap-1.5"
            style={{ cursor: esLavador ? "default" : "pointer" }}
          >
            <Droplets size={20} color={ACCENT} />
            {data.nombreNegocio}
          </h1>
        )}
        <p className="text-xs mt-0.5 capitalize" style={{ color: MUTED }}>
          {new Date().toLocaleDateString("es-MX", { weekday: "long", day: "numeric", month: "long" })}
          {esLavador ? ` · ${sesion.nombre}` : ""}
        </p>
        {!esLavador && sucursales && sucursales.length > 1 && (
          <select
            value={sucursalId}
            onChange={(e) => onCambiarSucursal(e.target.value)}
            className="text-xs mt-1 rounded-md px-1.5 py-0.5 outline-none"
            style={{ background: SURFACE2, color: ACCENT, border: `1px solid ${SURFACE2}` }}
          >
            {sucursales.map((s) => <option key={s.id} value={s.id}>{s.nombre}</option>)}
          </select>
        )}
        {esLavador && sucursales && sucursales.length > 1 && (
          <p className="text-[11px] mt-0.5" style={{ color: ACCENT }}>
            {sucursales.find((s) => s.id === sucursalId)?.nombre}
          </p>
        )}
      </div>
      <div className="flex items-center gap-2">
        {!esLavador && (
          <button
            onClick={onConfig}
            className="w-9 h-9 rounded-xl flex items-center justify-center shrink-0"
            style={{ background: SURFACE2, color: MUTED }}
          >
            <Settings size={17} />
          </button>
        )}
        <button
          onClick={onCerrarSesion}
          className="w-9 h-9 rounded-xl flex items-center justify-center shrink-0"
          style={{ background: SURFACE2, color: MUTED }}
          title="Cambiar usuario"
        >
          <LogOut size={16} />
        </button>
      </div>
    </div>
  );
}

function SeleccionUsuario({ data, onElegir }) {
  const [pidiendoPin, setPidiendoPin] = useState(null); // { tipo: 'admin' | 'lavador', empleado? }
  const [pin, setPin] = useState("");
  const [errorPin, setErrorPin] = useState(false);

  const intentarAdmin = () => {
    if (data.adminPin) {
      setPidiendoPin({ tipo: "admin" });
      setPin("");
      setErrorPin(false);
    } else {
      onElegir({ rol: "admin" });
    }
  };

  const intentarLavador = (e) => {
    if (e.pin) {
      setPidiendoPin({ tipo: "lavador", empleado: e });
      setPin("");
      setErrorPin(false);
    } else {
      onElegir({ rol: "lavador", nombre: e.nombre });
    }
  };

  const confirmarPin = () => {
    if (pidiendoPin.tipo === "admin") {
      if (pin === data.adminPin) onElegir({ rol: "admin" });
      else setErrorPin(true);
    } else {
      if (pin === pidiendoPin.empleado.pin) onElegir({ rol: "lavador", nombre: pidiendoPin.empleado.nombre });
      else setErrorPin(true);
    }
  };

  if (pidiendoPin) {
    return (
      <div className="flex-1 flex flex-col justify-center items-center px-6 gap-4">
        <ShieldCheck size={32} color={ACCENT} />
        <div className="text-center">
          <p className="font-display text-lg font-bold">
            {pidiendoPin.tipo === "admin" ? "Administrador" : pidiendoPin.empleado.nombre}
          </p>
          <p className="text-sm mt-1" style={{ color: MUTED }}>Ingresa tu PIN</p>
        </div>
        <input
          autoFocus
          type="password"
          inputMode="numeric"
          maxLength={4}
          value={pin}
          onChange={(e) => { setPin(e.target.value.replace(/\D/g, "").slice(0, 4)); setErrorPin(false); }}
          onKeyDown={(e) => e.key === "Enter" && confirmarPin()}
          className="w-32 text-center text-2xl font-mono tracking-[0.5em] rounded-xl px-3 py-2 outline-none"
          style={{ border: `1px solid ${errorPin ? DANGER : ACCENT}` }}
          placeholder="••••"
        />
        {errorPin && <p className="text-xs" style={{ color: DANGER }}>PIN incorrecto, intenta de nuevo.</p>}
        <div className="w-full flex flex-col gap-2 mt-1">
          <button
            onClick={confirmarPin}
            style={{ background: ACCENT, color: BG }}
            className="w-full rounded-xl py-3 font-semibold text-sm"
          >
            Entrar
          </button>
          <button
            onClick={() => setPidiendoPin(null)}
            style={{ color: MUTED }}
            className="w-full rounded-xl py-2 text-sm"
          >
            Cancelar
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="flex-1 flex flex-col justify-center items-center px-6 gap-4">
      <Droplets size={36} color={ACCENT} />
      <div className="text-center">
        <p className="font-display text-xl font-bold">{data.nombreNegocio}</p>
        <p className="text-sm mt-1" style={{ color: MUTED }}>¿Quién eres?</p>
      </div>
      <div className="w-full flex flex-col gap-2 mt-2">
        <button
          onClick={intentarAdmin}
          className="w-full rounded-xl py-3 font-semibold text-sm flex items-center justify-center gap-2"
          style={{ background: ACCENT, color: BG }}
        >
          <ShieldCheck size={16} /> Soy el administrador
        </button>

        {data.empleados.length > 0 ? (
          <>
            <p className="text-xs mt-3 mb-1" style={{ color: MUTED }}>O selecciona tu nombre si eres del equipo:</p>
            {data.empleados.map((e) => (
              <button
                key={e.id}
                onClick={() => intentarLavador(e)}
                className="w-full rounded-xl py-3 text-sm flex items-center justify-center gap-2"
                style={{ background: SURFACE, border: `1px solid ${SURFACE2}`, color: TEXT }}
              >
                <UserRound size={16} color={ACCENT} /> {e.nombre}
              </button>
            ))}
          </>
        ) : (
          <p className="text-xs mt-3 text-center" style={{ color: MUTED }}>
            Agrega a tu equipo desde Configuración para que puedan entrar con su nombre.
          </p>
        )}
      </div>
    </div>
  );
}

function NavBar({ tab, setTab, esLavador }) {
  const todos = [
    { id: "dashboard", label: "Inicio", icon: Droplets },
    { id: "citas", label: "Citas", icon: CalendarDays },
    { id: "servicios", label: "Servicios", icon: Car },
    { id: "clientes", label: "Clientes", icon: Users },
    { id: "fidelidad", label: "Fidelidad", icon: Gift },
    { id: "inventario", label: "Inventario", icon: Package },
    { id: "empleados", label: "Equipo", icon: UserRound },
    { id: "ingresos", label: "Finanzas", icon: Wallet },
  ];
  const permitidos = ["citas", "servicios", "inventario", "ingresos"];
  const items = esLavador ? todos.filter((it) => permitidos.includes(it.id)) : todos;
  return (
    <div
      style={{ background: SURFACE, borderTop: `1px solid ${SURFACE2}` }}
      className={`absolute bottom-0 left-0 right-0 flex overflow-x-auto py-2 px-1 gap-0.5 ${esLavador ? "justify-around" : ""}`}
    >
      {items.map((it) => {
        const active = tab === it.id;
        return (
          <button
            key={it.id}
            onClick={() => setTab(it.id)}
            className="flex flex-col items-center gap-0.5 px-2 py-1 rounded-xl transition-colors shrink-0"
            style={{ color: active ? ACCENT : MUTED, minWidth: "52px" }}
          >
            <it.icon size={17} strokeWidth={active ? 2.5 : 2} />
            <span className="text-[9px] font-medium leading-none whitespace-nowrap">{it.label}</span>
          </button>
        );
      })}
    </div>
  );
}

/* ---------------- Dashboard ---------------- */
/* ---------------- Configuración ---------------- */
function Configuracion({ data, save, onBack }) {
  const [nombre, setNombre] = useState(data.nombreNegocio);
  const [adminPin, setAdminPin] = useState(data.adminPin || "");
  const [form, setForm] = useState(null); // {index, nombre, precio}

  const tipos = data.tiposServicio && data.tiposServicio.length ? data.tiposServicio : DEFAULT_TIPOS_SERVICIO;

  const guardarNombre = () => save({ ...data, nombreNegocio: nombre.trim() || "Mi Autolavado" });
  const guardarAdminPin = () => save({ ...data, adminPin: adminPin.replace(/\D/g, "").slice(0, 4) });

  const startNew = () => setForm({ index: null, nombre: "", precio: "" });
  const startEdit = (t, i) => setForm({ index: i, nombre: t.nombre, precio: t.precio });

  const guardarTipo = () => {
    if (!form.nombre.trim() || !form.precio) return;
    let nuevos;
    const entrada = { nombre: form.nombre.trim(), precio: Number(form.precio) };
    if (form.index === null) nuevos = [...tipos, entrada];
    else nuevos = tipos.map((t, i) => (i === form.index ? entrada : t));
    save({ ...data, tiposServicio: nuevos });
    setForm(null);
  };

  const eliminarTipo = (i) => save({ ...data, tiposServicio: tipos.filter((_, idx) => idx !== i) });

  const adicionales = data.serviciosAdicionales && data.serviciosAdicionales.length ? data.serviciosAdicionales : DEFAULT_ADICIONALES;
  const [formAdicional, setFormAdicional] = useState(null); // {index, nombre, precio}
  const startNewAdicional = () => setFormAdicional({ index: null, nombre: "", precio: "" });
  const startEditAdicional = (t, i) => setFormAdicional({ index: i, nombre: t.nombre, precio: t.precio });

  const guardarAdicional = () => {
    if (!formAdicional.nombre.trim() || !formAdicional.precio) return;
    let nuevos;
    const entrada = { nombre: formAdicional.nombre.trim(), precio: Number(formAdicional.precio) };
    if (formAdicional.index === null) nuevos = [...adicionales, entrada];
    else nuevos = adicionales.map((t, i) => (i === formAdicional.index ? entrada : t));
    save({ ...data, serviciosAdicionales: nuevos });
    setFormAdicional(null);
  };

  const eliminarAdicional = (i) => save({ ...data, serviciosAdicionales: adicionales.filter((_, idx) => idx !== i) });

  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const [formSucursal, setFormSucursal] = useState(null); // {id, nombre}

  const startNewSucursal = () => setFormSucursal({ id: null, nombre: "" });
  const startEditSucursal = (s) => setFormSucursal({ id: s.id, nombre: s.nombre });

  const guardarSucursal = () => {
    if (!formSucursal.nombre.trim()) return;
    let nuevas;
    if (formSucursal.id) nuevas = sucursales.map((s) => (s.id === formSucursal.id ? { ...s, nombre: formSucursal.nombre.trim() } : s));
    else nuevas = [...sucursales, { id: uid(), nombre: formSucursal.nombre.trim() }];
    save({ ...data, sucursales: nuevas });
    setFormSucursal(null);
  };

  const eliminarSucursal = (id) => {
    if (sucursales.length <= 1) return;
    save({ ...data, sucursales: sucursales.filter((s) => s.id !== id) });
  };

  const exportarJSON = () => descargarArchivo(`respaldo-${data.nombreNegocio}-${todayStr()}.json`, JSON.stringify(data, null, 2), "application/json");

  const exportarServicios = () => {
    const csv = arrayToCsv(data.servicios, [
      { label: "Fecha", value: "fecha" },
      { label: "Cliente", value: "cliente" },
      { label: "Placas", value: "placas" },
      { label: "Vehículo", value: "tipoVehiculo" },
      { label: "Servicio", value: "tipo" },
      { label: "Precio", value: "precio" },
      { label: "Propina", value: (r) => r.propina || 0 },
      { label: "Método de pago", value: "metodo" },
      { label: "Pagado", value: (r) => (r.pagado ? "Sí" : "No") },
      { label: "Empleado", value: "empleado" },
      { label: "Estado", value: (r) => (r.estado === "finalizado" ? "Finalizado" : "En progreso") },
    ]);
    descargarArchivo(`servicios-${todayStr()}.csv`, csv, "text/csv");
  };

  const exportarGastos = () => {
    const csv = arrayToCsv(data.gastos || [], [
      { label: "Fecha", value: "fecha" },
      { label: "Concepto", value: "concepto" },
      { label: "Categoría", value: "categoria" },
      { label: "Monto", value: "monto" },
    ]);
    descargarArchivo(`gastos-${todayStr()}.csv`, csv, "text/csv");
  };

  const exportarClientes = () => {
    const csv = arrayToCsv(data.clientes, [
      { label: "Nombre", value: "nombre" },
      { label: "Teléfono", value: "telefono" },
      { label: "Vehículo", value: "vehiculo" },
      { label: "Placas", value: "placas" },
      { label: "Notas", value: "notas" },
    ]);
    descargarArchivo(`clientes-${todayStr()}.csv`, csv, "text/csv");
  };

  return (
    <div className="flex flex-col gap-3">
      <button onClick={onBack} className="flex items-center gap-1.5 text-sm mb-1" style={{ color: MUTED }}>
        <ArrowLeft size={16} /> Regresar
      </button>

      <Card className="flex flex-col gap-2">
        <p className="text-xs" style={{ color: MUTED }}>Nombre del negocio</p>
        <div className="flex gap-2">
          <input
            value={nombre}
            onChange={(e) => setNombre(e.target.value)}
            onBlur={guardarNombre}
            onKeyDown={(e) => e.key === "Enter" && e.currentTarget.blur()}
            className="flex-1 rounded-lg px-3 py-2 text-sm outline-none"
          />
        </div>
      </Card>

      <Card className="flex flex-col gap-2">
        <p className="text-xs" style={{ color: MUTED }}>PIN del administrador (opcional)</p>
        <input
          type="password"
          inputMode="numeric"
          maxLength={4}
          value={adminPin}
          onChange={(e) => setAdminPin(e.target.value.replace(/\D/g, "").slice(0, 4))}
          onBlur={guardarAdminPin}
          onKeyDown={(e) => e.key === "Enter" && e.currentTarget.blur()}
          placeholder="Déjalo vacío para no pedir PIN"
          className="rounded-lg px-3 py-2 text-sm outline-none tracking-[0.3em]"
        />
        <p className="text-[11px]" style={{ color: MUTED }}>
          Si lo configuras, se pedirá cada vez que alguien elija "Soy el administrador".
        </p>
      </Card>

      <p className="text-xs uppercase tracking-wide mt-1" style={{ color: MUTED }}>Sucursales</p>
      {!formSucursal ? (
        <button
          onClick={startNewSucursal}
          style={{ background: SURFACE2, color: ACCENT }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Agregar sucursal
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre de la sucursal" value={formSucursal.nombre} onChange={(v) => setFormSucursal({ ...formSucursal, nombre: v })} placeholder="Ej. Sucursal Centro" />
          <FormButtons onCancel={() => setFormSucursal(null)} onSave={guardarSucursal} />
        </Card>
      )}
      {sucursales.map((s) => (
        <Card key={s.id} className="flex items-center justify-between">
          <p className="font-semibold text-sm">{s.nombre}</p>
          <div className="flex gap-1">
            <IconBtn onClick={() => startEditSucursal(s)}><Pencil size={14} /></IconBtn>
            {sucursales.length > 1 && (
              <IconBtn onClick={() => eliminarSucursal(s.id)} danger><Trash2 size={14} /></IconBtn>
            )}
          </div>
        </Card>
      ))}
      <p className="text-[11px]" style={{ color: MUTED }}>
        Servicios, gastos, citas, inventario y empleados se llevan por separado en cada sucursal. Clientes, tipos de servicio y fidelidad son compartidos entre todas.
      </p>

      <p className="text-xs uppercase tracking-wide mt-1" style={{ color: MUTED }}>Tipos de servicio</p>

      {!form ? (
        <button
          onClick={startNew}
          style={{ background: ACCENT, color: BG }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Agregar tipo de servicio
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre" value={form.nombre} onChange={(v) => setForm({ ...form, nombre: v })} placeholder="Ej. Lavado Express" />
          <Field label="Precio" type="number" value={form.precio} onChange={(v) => setForm({ ...form, precio: v })} />
          <FormButtons onCancel={() => setForm(null)} onSave={guardarTipo} />
        </Card>
      )}

      {tipos.map((t, i) => (
        <Card key={t.nombre + i} className="flex items-center justify-between">
          <div>
            <p className="font-semibold text-sm">{t.nombre}</p>
            <p className="text-xs font-mono" style={{ color: ACCENT }}>{money(t.precio)}</p>
          </div>
          <div className="flex gap-1">
            <IconBtn onClick={() => startEdit(t, i)}><Pencil size={14} /></IconBtn>
            <IconBtn onClick={() => eliminarTipo(i)} danger><Trash2 size={14} /></IconBtn>
          </div>
        </Card>
      ))}

      <p className="text-xs uppercase tracking-wide mt-2" style={{ color: MUTED }}>Servicios adicionales (+Cera, +Motor, etc.)</p>
      {!formAdicional ? (
        <button
          onClick={startNewAdicional}
          style={{ background: SURFACE2, color: ACCENT }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Agregar servicio adicional
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre" value={formAdicional.nombre} onChange={(v) => setFormAdicional({ ...formAdicional, nombre: v })} placeholder="Ej. Cera" />
          <Field label="Precio" type="number" value={formAdicional.precio} onChange={(v) => setFormAdicional({ ...formAdicional, precio: v })} />
          <FormButtons onCancel={() => setFormAdicional(null)} onSave={guardarAdicional} />
        </Card>
      )}
      {adicionales.map((t, i) => (
        <Card key={t.nombre + i} className="flex items-center justify-between">
          <div>
            <p className="font-semibold text-sm">+ {t.nombre}</p>
            <p className="text-xs font-mono" style={{ color: ACCENT }}>{money(t.precio)}</p>
          </div>
          <div className="flex gap-1">
            <IconBtn onClick={() => startEditAdicional(t, i)}><Pencil size={14} /></IconBtn>
            <IconBtn onClick={() => eliminarAdicional(i)} danger><Trash2 size={14} /></IconBtn>
          </div>
        </Card>
      ))}
      <p className="text-[11px]" style={{ color: MUTED }}>
        Al registrar un servicio podrás marcar cualquiera de estos como extra; su precio se suma automáticamente al total.
      </p>

      <p className="text-xs uppercase tracking-wide mt-2" style={{ color: MUTED }}>Exportar y respaldo</p>
      <Card className="flex flex-col gap-2">
        <p className="text-xs" style={{ color: MUTED }}>
          Descarga tu información para verla en Excel o guardarla como respaldo.
        </p>
        <button onClick={exportarServicios} className="w-full rounded-lg py-2.5 text-sm font-medium flex items-center justify-center gap-2" style={{ background: SURFACE2, color: ACCENT }}>
          <Download size={14} /> Servicios (CSV)
        </button>
        <button onClick={exportarGastos} className="w-full rounded-lg py-2.5 text-sm font-medium flex items-center justify-center gap-2" style={{ background: SURFACE2, color: ACCENT }}>
          <Download size={14} /> Gastos (CSV)
        </button>
        <button onClick={exportarClientes} className="w-full rounded-lg py-2.5 text-sm font-medium flex items-center justify-center gap-2" style={{ background: SURFACE2, color: ACCENT }}>
          <Download size={14} /> Clientes (CSV)
        </button>
        <button onClick={exportarJSON} className="w-full rounded-lg py-2.5 text-sm font-semibold flex items-center justify-center gap-2" style={{ background: ACCENT, color: BG }}>
          <Download size={14} /> Respaldo completo (JSON)
        </button>
      </Card>

      <p className="text-xs uppercase tracking-wide mt-2" style={{ color: MUTED }}>Actividad del equipo</p>
      {(!data.actividad || data.actividad.length === 0) ? (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            Aquí verás lo que hagan tus lavadores en Citas, Inventario y Finanzas cuando entren con su nombre.
          </p>
        </Card>
      ) : (
        <Card>
          <div className="flex flex-col gap-2.5">
            {data.actividad.slice(0, 25).map((a) => (
              <div key={a.id} className="flex items-center justify-between text-xs">
                <span className="flex items-center gap-1.5">
                  <Activity size={12} color={ACCENT} />
                  <span className="font-semibold">{a.usuario}</span> actualizó {a.seccion}
                </span>
                <span style={{ color: MUTED }}>{tiempoRelativo(a.fecha)}</span>
              </div>
            ))}
          </div>
        </Card>
      )}
    </div>
  );
}

/* ---------------- Dashboard ---------------- */
/* ---------------- Análisis de días y horarios ---------------- */
function AnalisisHorarios({ misServicios, onBack }) {
  const [periodo, setPeriodo] = useState("30dias");

  const filtrados = useMemo(() => {
    if (periodo === "todo") return misServicios;
    const limite = Date.now() - 30 * 86400000;
    return misServicios.filter((s) => new Date(`${s.fecha}T00:00:00`).getTime() >= limite);
  }, [misServicios, periodo]);

  const NOMBRES_DIA = ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"];
  const ORDEN_SEMANA = [1, 2, 3, 4, 5, 6, 0]; // lunes a domingo

  const porDia = useMemo(() => {
    const counts = new Array(7).fill(0);
    filtrados.forEach((s) => {
      const d = new Date(`${s.fecha}T00:00:00`).getDay();
      counts[d]++;
    });
    return ORDEN_SEMANA.map((i) => ({ dia: i, label: NOMBRES_DIA[i].slice(0, 3), nombre: NOMBRES_DIA[i], count: counts[i] }));
  }, [filtrados]);
  const maxDia = Math.max(1, ...porDia.map((d) => d.count));
  const diaTop = porDia.reduce((a, b) => (b.count > a.count ? b : a), porDia[0]);

  const formatHora = (h) => {
    const per = h < 12 ? "AM" : "PM";
    const h12 = h % 12 === 0 ? 12 : h % 12;
    return `${h12}${per}`;
  };

  const porHora = useMemo(() => {
    const counts = new Array(24).fill(0);
    filtrados.forEach((s) => {
      if (!s.horaInicio) return;
      counts[new Date(s.horaInicio).getHours()]++;
    });
    return counts;
  }, [filtrados]);
  const conDatos = porHora.map((c, h) => ({ h, c })).filter((x) => x.c > 0);
  const horaMin = conDatos.length ? Math.min(...conDatos.map((x) => x.h)) : 8;
  const horaMax = conDatos.length ? Math.max(...conDatos.map((x) => x.h)) : 20;
  const rangoHoras = [];
  for (let h = horaMin; h <= horaMax; h++) rangoHoras.push({ h, c: porHora[h] });
  const maxHora = Math.max(1, ...rangoHoras.map((r) => r.c));
  const horaTop = rangoHoras.length ? rangoHoras.reduce((a, b) => (b.c > a.c ? b : a)) : null;

  const totalServicios = filtrados.length;

  return (
    <div className="flex flex-col gap-3">
      <button onClick={onBack} className="flex items-center gap-1.5 text-sm mb-1" style={{ color: MUTED }}>
        <ArrowLeft size={16} /> Regresar
      </button>

      <div className="flex gap-2">
        {[["30dias", "Últimos 30 días"], ["todo", "Todo el historial"]].map(([id, label]) => (
          <button
            key={id}
            onClick={() => setPeriodo(id)}
            style={{ background: periodo === id ? ACCENT : SURFACE2, color: periodo === id ? BG : TEXT }}
            className="flex-1 rounded-lg py-2 text-xs font-medium"
          >
            {label}
          </button>
        ))}
      </div>

      {totalServicios === 0 ? (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            No hay suficientes servicios registrados en este periodo para hacer el análisis.
          </p>
        </Card>
      ) : (
        <>
          <Card className="flex items-center gap-3">
            <BarChart3 size={18} color={ACCENT} className="shrink-0" />
            <p className="text-sm">
              Tu día más ocupado es <span className="font-semibold" style={{ color: ACCENT }}>{diaTop.nombre}</span>
              {horaTop && (
                <> y tu horario pico es alrededor de las <span className="font-semibold" style={{ color: ACCENT }}>{formatHora(horaTop.h)}</span></>
              )}
              .
            </p>
          </Card>

          <Card>
            <p className="text-xs mb-2" style={{ color: MUTED }}>Autos por día de la semana</p>
            <div className="flex items-end justify-between gap-1.5 h-24">
              {porDia.map((d) => (
                <div key={d.dia} className="flex-1 flex flex-col items-center gap-1">
                  <span className="text-[10px] font-mono" style={{ color: MUTED }}>{d.count}</span>
                  <div
                    className="w-full rounded-t-md"
                    style={{
                      height: `${Math.max(4, (d.count / maxDia) * 72)}px`,
                      background: d.dia === diaTop.dia ? ACCENT : SURFACE2,
                    }}
                  />
                  <span className="text-[10px]" style={{ color: MUTED }}>{d.label}</span>
                </div>
              ))}
            </div>
          </Card>

          <Card>
            <p className="text-xs mb-2" style={{ color: MUTED }}>Autos por horario del día</p>
            <div className="flex items-end justify-between gap-1 h-24 overflow-x-auto">
              {rangoHoras.map((r) => (
                <div key={r.h} className="flex-1 flex flex-col items-center gap-1 min-w-[20px]">
                  {r.c > 0 && <span className="text-[9px] font-mono" style={{ color: MUTED }}>{r.c}</span>}
                  <div
                    className="w-full rounded-t-md"
                    style={{
                      height: `${Math.max(3, (r.c / maxHora) * 72)}px`,
                      background: horaTop && r.h === horaTop.h ? GOLD : SURFACE2,
                    }}
                  />
                  <span className="text-[8px]" style={{ color: MUTED }}>{r.h}</span>
                </div>
              ))}
            </div>
            <p className="text-[11px] mt-2" style={{ color: MUTED }}>Hora del día (formato 24h)</p>
          </Card>

          <Card>
            <p className="text-xs" style={{ color: MUTED }}>
              Basado en {totalServicios} servicio{totalServicios !== 1 ? "s" : ""} registrado{totalServicios !== 1 ? "s" : ""} en este periodo.
              Te puede servir para programar tu equipo y tener más apoyo en tus días/horarios de mayor demanda.
            </p>
          </Card>
        </>
      )}
    </div>
  );
}

/* ---------------- Dashboard ---------------- */
function Dashboard({ data, save, sucursalId }) {
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const misServicios = data.servicios.filter((s) => pertenece(s, sucursalId, sucursales));
  const misGastos = (data.gastos || []).filter((g) => pertenece(g, sucursalId, sucursales));
  const misInventario = (data.inventario || []).filter((p) => pertenece(p, sucursalId, sucursales));
  const misCitas = (data.citas || []).filter((c) => pertenece(c, sucursalId, sucursales));

  const hoy = todayStr();
  const serviciosHoy = misServicios.filter((s) => s.fecha === hoy);
  const ingresoHoy = serviciosHoy.reduce((a, s) => a + Number(s.precio), 0);
  const pendientes = misServicios.filter((s) => !s.pagado);
  const pendienteMonto = pendientes.reduce((a, s) => a + Number(s.precio), 0);
  const gastosHoy = misGastos.filter((g) => g.fecha === hoy).reduce((a, g) => a + Number(g.monto), 0);
  const netoHoy = ingresoHoy - gastosHoy;
  const efectivoIngresoHoy = serviciosHoy
    .filter((s) => s.pagado && (s.metodo || "efectivo") === "efectivo")
    .reduce((a, s) => a + Number(s.precio), 0);
  const efectivoGastoHoy = misGastos
    .filter((g) => g.fecha === hoy && (g.metodo || "efectivo") === "efectivo")
    .reduce((a, g) => a + Number(g.monto), 0);
  const efectivoCajaHoy = efectivoIngresoHoy - efectivoGastoHoy;
  const propinaHoy = serviciosHoy.reduce((a, s) => a + Number(s.propina || 0), 0);
  const enProgresoCount = misServicios.filter((s) => s.estado !== "finalizado").length;
  const pct = Math.min(100, Math.round((ingresoHoy / (data.metaDiaria || 1)) * 100));

  const last7 = useMemo(() => {
    const arr = [];
    for (let i = 6; i >= 0; i--) {
      const d = new Date();
      d.setDate(d.getDate() - i);
      const key = d.toISOString().split("T")[0];
      const total = misServicios
        .filter((s) => s.fecha === key)
        .reduce((a, s) => a + Number(s.precio), 0);
      arr.push({ key, total, label: d.toLocaleDateString("es-MX", { weekday: "short" })[0].toUpperCase() });
    }
    return arr;
  }, [misServicios]);
  const maxDia = Math.max(1, ...last7.map((d) => d.total));

  const empleadoTop = useMemo(() => {
    const mes = hoy.slice(0, 7);
    const counts = {};
    misServicios
      .filter((s) => s.fecha.startsWith(mes) && s.empleado)
      .forEach((s) => { counts[s.empleado] = (counts[s.empleado] || 0) + 1; });
    const arr = Object.entries(counts).sort((a, b) => b[1] - a[1]);
    return arr[0];
  }, [misServicios]);

  const stockBajo = misInventario.filter((p) => Number(p.stock) <= Number(p.minimo));
  const citasHoy = misCitas.filter((c) => c.fecha === hoy && c.estado === "pendiente").sort((a, b) => (a.hora < b.hora ? -1 : 1));
  const citaTimestamp = (c) => new Date(`${c.fecha}T${c.hora}:00`).getTime();
  const citasProximaHora = citasHoy.filter((c) => {
    const t = citaTimestamp(c);
    return t >= Date.now() && t - Date.now() <= 3600000;
  });
  const mananaStr = (() => { const d = new Date(); d.setDate(d.getDate() + 1); return d.toISOString().split("T")[0]; })();
  const citasSinConfirmar = misCitas.filter((c) => c.fecha === mananaStr && c.estado === "pendiente" && !c.confirmada);
  const [editandoMeta, setEditandoMeta] = useState(false);
  const [metaInput, setMetaInput] = useState(data.metaDiaria);

  // alerta sonora/visual mientras la app está abierta (no es un push real: eso requiere backend/service worker,
  // algo que este tipo de app no puede tener; esta es la mejor alternativa dentro de lo posible aquí)
  const avisadasRef = useRef(new Set());
  useEffect(() => {
    citasProximaHora.forEach((c) => {
      if (avisadasRef.current.has(c.id)) return;
      avisadasRef.current.add(c.id);
      try {
        const ctx = new (window.AudioContext || window.webkitAudioContext)();
        const osc = ctx.createOscillator();
        const gain = ctx.createGain();
        osc.type = "sine";
        osc.frequency.value = 880;
        gain.gain.setValueAtTime(0.15, ctx.currentTime);
        gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.5);
        osc.connect(gain);
        gain.connect(ctx.destination);
        osc.start();
        osc.stop(ctx.currentTime + 0.5);
      } catch {}
      if (typeof Notification !== "undefined" && Notification.permission === "granted") {
        try { new Notification("Cita muy pronto", { body: `${c.cliente} · ${c.servicio} a las ${c.hora}` }); } catch {}
      }
    });
  }, [citasProximaHora]);

  const [permisoNotif, setPermisoNotif] = useState(typeof Notification !== "undefined" ? Notification.permission : "unsupported");
  const pedirPermisoNotif = () => {
    if (typeof Notification === "undefined") return;
    Notification.requestPermission().then((p) => setPermisoNotif(p));
  };

  const guardarMeta = () => {
    setEditandoMeta(false);
    const valor = Number(metaInput);
    if (valor > 0) save({ ...data, metaDiaria: valor });
    else setMetaInput(data.metaDiaria);
  };

  const [mostrarAnalisis, setMostrarAnalisis] = useState(false);
  if (mostrarAnalisis) {
    return <AnalisisHorarios misServicios={misServicios} onBack={() => setMostrarAnalisis(false)} />;
  }

  return (
    <div className="flex flex-col gap-3">
      {permisoNotif === "default" && (
        <button
          onClick={pedirPermisoNotif}
          className="w-full rounded-xl py-2 text-xs font-medium flex items-center justify-center gap-1.5"
          style={{ background: SURFACE2, color: ACCENT }}
        >
          <Bell size={13} /> Activar aviso de citas próximas (mientras tengas la app abierta)
        </button>
      )}

      {/* medidor de agua */}
      <Card className="flex items-center gap-4">
        <WaterGauge pct={pct} />
        <div className="flex-1">
          <p className="text-xs" style={{ color: MUTED }}>Meta del día</p>
          <p className="font-mono text-2xl font-bold">{money(ingresoHoy)}</p>
          {editandoMeta ? (
            <div className="flex items-center gap-1.5 mt-1">
              <span className="text-xs" style={{ color: MUTED }}>de $</span>
              <input
                autoFocus
                type="number"
                value={metaInput}
                onChange={(e) => setMetaInput(e.target.value)}
                onBlur={guardarMeta}
                onKeyDown={(e) => e.key === "Enter" && e.currentTarget.blur()}
                className="w-20 rounded-md px-1.5 py-0.5 text-xs outline-none"
                style={{ border: `1px solid ${ACCENT}` }}
              />
            </div>
          ) : (
            <button
              onClick={() => { setMetaInput(data.metaDiaria); setEditandoMeta(true); }}
              className="text-xs flex items-center gap-1 mt-0.5"
              style={{ color: MUTED }}
            >
              de {money(data.metaDiaria)} · {pct}% <Pencil size={11} />
            </button>
          )}
        </div>
      </Card>

      <Card className="flex items-center gap-3" style={{ borderColor: "#2E6B4F" }}>
        <Banknote size={20} color="#6FE0A8" className="shrink-0" />
        <div>
          <p className="text-xs" style={{ color: MUTED }}>Efectivo en caja hoy</p>
          <p className="font-mono text-xl font-bold" style={{ color: "#6FE0A8" }}>{money(efectivoCajaHoy)}</p>
          {ingresoHoy - efectivoIngresoHoy > 0 && (
            <p className="text-[10px] mt-0.5" style={{ color: GOLD }}>
              +{money(ingresoHoy - efectivoIngresoHoy)} en transferencia/tarjeta (no cuenta para la caja)
            </p>
          )}
        </div>
      </Card>

      <div className="grid grid-cols-2 gap-3">
        <Card>
          <Car size={16} color={ACCENT} />
          <p className="font-mono text-xl font-bold mt-1">{serviciosHoy.length}</p>
          <p className="text-xs" style={{ color: MUTED }}>
            servicios hoy{enProgresoCount > 0 ? ` · ${enProgresoCount} en curso` : ""}
          </p>
        </Card>
        <Card>
          <Clock size={16} color={GOLD} />
          <p className="font-mono text-xl font-bold mt-1">{money(pendienteMonto)}</p>
          <p className="text-xs" style={{ color: MUTED }}>{pendientes.length} por cobrar</p>
        </Card>
        <Card>
          <Sparkles size={16} color={GOLD} />
          <p className="font-mono text-xl font-bold mt-1">{money(propinaHoy)}</p>
          <p className="text-xs" style={{ color: MUTED }}>propinas de hoy</p>
        </Card>
        <Card>
          <Receipt size={16} color={DANGER} />
          <p className="font-mono text-xl font-bold mt-1">{money(gastosHoy)}</p>
          <p className="text-xs" style={{ color: MUTED }}>gastos de hoy</p>
        </Card>
        <Card className="col-span-2">
          <Scale size={16} color={netoHoy >= 0 ? "#6FE0A8" : DANGER} />
          <p className="font-mono text-xl font-bold mt-1" style={{ color: netoHoy >= 0 ? TEXT : DANGER }}>
            {money(netoHoy)}
          </p>
          <p className="text-xs" style={{ color: MUTED }}>ganancia neta hoy</p>
        </Card>
      </div>

      <Card>
        <p className="text-xs mb-2" style={{ color: MUTED }}>Últimos 7 días</p>
        <div className="flex items-end justify-between gap-1.5 h-20">
          {last7.map((d) => (
            <div key={d.key} className="flex-1 flex flex-col items-center gap-1">
              <div
                className="w-full rounded-t-md"
                style={{
                  height: `${Math.max(6, (d.total / maxDia) * 64)}px`,
                  background: d.key === hoy ? ACCENT : SURFACE2,
                }}
              />
              <span className="text-[10px]" style={{ color: MUTED }}>{d.label}</span>
            </div>
          ))}
        </div>
      </Card>

      <button
        onClick={() => setMostrarAnalisis(true)}
        className="w-full rounded-xl py-2.5 text-sm font-semibold flex items-center justify-center gap-1.5"
        style={{ background: SURFACE2, color: ACCENT }}
      >
        <BarChart3 size={15} /> Ver días y horarios con más autos
      </button>

      {citasProximaHora.length > 0 && (
        <Card className="flex items-start gap-3" style={{ borderColor: GOLD, background: "#241D0E" }}>
          <Clock size={18} color={GOLD} className="shrink-0 mt-0.5" />
          <div>
            <p className="text-sm font-semibold">¡Cita muy pronto!</p>
            <div className="flex flex-col gap-0.5 mt-1">
              {citasProximaHora.map((c) => (
                <p key={c.id} className="text-xs" style={{ color: GOLD }}>
                  {c.cliente} · {c.servicio} — {tiempoHasta(citaTimestamp(c))} ({c.hora})
                </p>
              ))}
            </div>
          </div>
        </Card>
      )}

      {citasSinConfirmar.length > 0 && (
        <Card className="flex items-start gap-3" style={{ borderColor: ACCENT }}>
          <CalendarCheck size={18} color={ACCENT} className="shrink-0 mt-0.5" />
          <div className="flex-1">
            <p className="text-sm font-semibold">Confirma las citas de mañana</p>
            <div className="flex flex-col gap-2 mt-1.5">
              {citasSinConfirmar.map((c) => (
                <div key={c.id} className="flex items-center justify-between">
                  <p className="text-xs">
                    {c.hora} · {c.cliente}{c.telefono ? ` · ${c.telefono}` : ""}
                  </p>
                  <button
                    onClick={() => save({ ...data, citas: data.citas.map((x) => (x.id === c.id ? { ...x, confirmada: true } : x)) })}
                    className="text-[10px] px-2 py-1 rounded-full font-medium"
                    style={{ background: "#1E4A3A", color: "#6FE0A8" }}
                  >
                    Confirmar
                  </button>
                </div>
              ))}
            </div>
          </div>
        </Card>
      )}

      {citasHoy.length > 0 && (
        <Card>
          <p className="text-sm font-semibold flex items-center gap-1.5 mb-2">
            <CalendarDays size={16} color={ACCENT} /> Citas de hoy
          </p>
          <div className="flex flex-col gap-1.5">
            {citasHoy.map((c) => {
              const t = citaTimestamp(c);
              const pronto = t >= Date.now() && t - Date.now() <= 3600000;
              return (
                <div key={c.id} className="flex justify-between text-xs">
                  <span>{c.hora} · {c.cliente} · {c.servicio}</span>
                  {pronto && <span style={{ color: GOLD }}>{tiempoHasta(t)}</span>}
                </div>
              );
            })}
          </div>
        </Card>
      )}

      {empleadoTop ? (
        <Card className="flex items-center gap-3">
          <Sparkles size={18} color={GOLD} />
          <p className="text-sm">
            <span className="font-semibold">{empleadoTop[0]}</span> lleva el mes con{" "}
            <span className="font-semibold">{empleadoTop[1]}</span> servicios
          </p>
        </Card>
      ) : (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            Registra tu primer servicio para ver aquí el progreso del equipo.
          </p>
        </Card>
      )}

      {stockBajo.length > 0 && (
        <Card className="flex items-start gap-3" style={{ borderColor: GOLD }}>
          <AlertTriangle size={18} color={GOLD} className="shrink-0 mt-0.5" />
          <div>
            <p className="text-sm font-semibold">Stock bajo</p>
            <p className="text-xs" style={{ color: MUTED }}>
              {stockBajo.map((p) => p.nombre).join(", ")} {stockBajo.length === 1 ? "está por agotarse" : "están por agotarse"}.
            </p>
          </div>
        </Card>
      )}
    </div>
  );
}

function WaterGauge({ pct }) {
  const size = 72;
  const waterY = size - (size * pct) / 100;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} className="shrink-0">
      <defs>
        <clipPath id="circleClip">
          <circle cx={size / 2} cy={size / 2} r={size / 2 - 3} />
        </clipPath>
      </defs>
      <circle cx={size / 2} cy={size / 2} r={size / 2 - 3} fill={SURFACE2} />
      <g clipPath="url(#circleClip)">
        <rect x="0" y={waterY} width={size} height={size} fill={ACCENT} opacity="0.85" />
        <g className="wave-anim">
          <path
            d={`M0,${waterY} Q ${size / 4},${waterY - 5} ${size / 2},${waterY} T ${size},${waterY} T ${size * 1.5},${waterY} Z`}
            fill={ACCENT}
          />
        </g>
      </g>
      <circle cx={size / 2} cy={size / 2} r={size / 2 - 3} fill="none" stroke={SURFACE2} strokeWidth="2" />
      <text x="50%" y="54%" textAnchor="middle" fontSize="15" fontWeight="700" fill={TEXT} fontFamily="Space Grotesk">
        {pct}%
      </text>
    </svg>
  );
}

/* ---------------- Clientes ---------------- */
/* ---------------- Citas ---------------- */
function Citas({ data, save, onIniciarServicio, sucursalId }) {
  const [form, setForm] = useState(null);
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const citas = (data.citas || []).filter((c) => pertenece(c, sucursalId, sucursales));
  const misEmpleados = data.empleados.filter((e) => pertenece(e, sucursalId, sucursales));
  const tipos = data.tiposServicio && data.tiposServicio.length ? data.tiposServicio : DEFAULT_TIPOS_SERVICIO;

  const blank = () => ({
    id: null,
    cliente: "",
    telefono: "",
    tipoVehiculo: TIPOS_VEHICULO[0],
    servicio: tipos[0].nombre,
    fecha: todayStr(),
    hora: "09:00",
    notas: "",
    estado: "pendiente",
    confirmada: false,
  });

  const startNew = () => setForm(blank());

  const guardar = () => {
    if (!form.cliente.trim()) return;
    let nuevas;
    if (form.id) nuevas = data.citas.map((c) => (c.id === form.id ? form : c));
    else nuevas = [...data.citas, { ...form, id: uid(), sucursalId }];
    save({ ...data, citas: nuevas });
    setForm(null);
  };

  const eliminar = (id) => save({ ...data, citas: data.citas.filter((c) => c.id !== id) });
  const cambiarEstado = (c, estado) => save({ ...data, citas: data.citas.map((x) => (x.id === c.id ? { ...x, estado } : x)) });
  const confirmar = (c) => save({ ...data, citas: data.citas.map((x) => (x.id === c.id ? { ...x, confirmada: true } : x)) });

  const iniciarServicio = (c) => {
    const tipoInfo = tipos.find((t) => t.nombre === c.servicio);
    const cliente = data.clientes.find((cl) => cl.nombre.trim().toLowerCase() === c.cliente.trim().toLowerCase());
    const nuevoServicio = {
      id: uid(),
      fecha: todayStr(),
      cliente: c.cliente,
      placas: cliente?.placas || "",
      tipoVehiculo: c.tipoVehiculo,
      tipo: c.servicio,
      precio: tipoInfo ? tipoInfo.precio : 0,
      empleado: misEmpleados[0]?.nombre || "",
      metodo: "efectivo",
      pagado: false,
      estado: "en_progreso",
      horaInicio: Date.now(),
      horaFin: null,
      propina: 0,
      sucursalId,
    };
    save({
      ...data,
      servicios: [nuevoServicio, ...data.servicios],
      citas: data.citas.map((x) => (x.id === c.id ? { ...x, estado: "atendida" } : x)),
    });
    onIniciarServicio && onIniciarServicio();
  };

  const ordenadas = [...citas].sort((a, b) => (a.fecha + a.hora < b.fecha + b.hora ? -1 : 1));
  const hoy = todayStr();
  const proximas = ordenadas.filter((c) => c.estado === "pendiente" && c.fecha >= hoy);
  const pasadas = ordenadas.filter((c) => c.estado !== "pendiente" || c.fecha < hoy);

  const badge = (estado) => {
    if (estado === "atendida") return { bg: "#1E4A3A", color: "#6FE0A8", label: "Atendida" };
    if (estado === "cancelada") return { bg: "#3A1E1E", color: "#F4B0A0", label: "Cancelada" };
    return { bg: "#4A3B1E", color: GOLD, label: "Pendiente" };
  };

  const CitaCard = ({ c }) => {
    const b = badge(c.estado);
    return (
      <Card>
        <div className="flex items-center justify-between">
          <div>
            <p className="font-semibold text-sm">{c.cliente}</p>
            <p className="text-xs" style={{ color: MUTED }}>
              {c.tipoVehiculo} · {c.servicio}
            </p>
            <p className="text-xs font-mono mt-1" style={{ color: ACCENT }}>
              {fecha(c.fecha)} · {c.hora}
            </p>
            {c.estado === "pendiente" && (
              <p className="text-[10px] mt-0.5" style={{ color: c.confirmada ? "#6FE0A8" : GOLD }}>
                {c.confirmada ? "✓ Confirmada" : "Sin confirmar"}
              </p>
            )}
            {c.notas && <p className="text-xs mt-1" style={{ color: MUTED }}>{c.notas}</p>}
          </div>
          <div className="flex flex-col items-end gap-1.5">
            <span className="text-[10px] px-2 py-1 rounded-full font-medium" style={{ background: b.bg, color: b.color }}>
              {b.label}
            </span>
            <div className="flex gap-1">
              <IconBtn onClick={() => setForm(c)}><Pencil size={13} /></IconBtn>
              <IconBtn onClick={() => eliminar(c.id)} danger><Trash2 size={13} /></IconBtn>
            </div>
          </div>
        </div>
        {c.estado === "pendiente" && (
          <div className="flex gap-2 mt-3">
            {!c.confirmada && (
              <button
                onClick={() => confirmar(c)}
                className="rounded-lg py-2 px-3 text-xs font-medium flex items-center justify-center gap-1"
                style={{ background: SURFACE2, color: GOLD }}
              >
                <CalendarCheck size={13} />
              </button>
            )}
            <button
              onClick={() => iniciarServicio(c)}
              className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1"
              style={{ background: ACCENT, color: BG }}
            >
              <PlayCircle size={13} /> Iniciar servicio
            </button>
            <button
              onClick={() => cambiarEstado(c, "cancelada")}
              className="rounded-lg py-2 px-3 text-xs font-medium flex items-center justify-center gap-1"
              style={{ background: SURFACE2, color: MUTED }}
            >
              <CalendarX size={13} />
            </button>
          </div>
        )}
      </Card>
    );
  };

  return (
    <div className="flex flex-col gap-3">
      {!form ? (
        <button
          onClick={startNew}
          style={{ background: ACCENT, color: BG }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Agendar cita
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Cliente</label>
            <input
              list="clientes-citas"
              value={form.cliente}
              onChange={(e) => {
                const val = e.target.value;
                const match = data.clientes.find((cl) => cl.nombre.trim().toLowerCase() === val.trim().toLowerCase());
                setForm({
                  ...form,
                  cliente: val,
                  telefono: match ? match.telefono || form.telefono : form.telefono,
                });
              }}
              placeholder="Nombre del cliente"
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            />
            <datalist id="clientes-citas">
              {data.clientes.map((c) => <option key={c.id} value={c.nombre} />)}
            </datalist>
          </div>
          {(() => {
            const match = data.clientes.find((cl) => cl.nombre.trim().toLowerCase() === form.cliente.trim().toLowerCase());
            return match?.notas ? (
              <div className="rounded-lg px-3 py-2 text-xs flex items-start gap-2" style={{ background: "#4A3B1E", color: GOLD }}>
                <StickyNote size={13} className="shrink-0 mt-0.5" /> {match.notas}
              </div>
            ) : null;
          })()}
          <Field label="Teléfono (opcional)" value={form.telefono} onChange={(v) => setForm({ ...form, telefono: v })} />
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Tipo de vehículo</label>
            <select
              value={form.tipoVehiculo}
              onChange={(e) => setForm({ ...form, tipoVehiculo: e.target.value })}
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            >
              {TIPOS_VEHICULO.map((v) => <option key={v}>{v}</option>)}
            </select>
          </div>
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Servicio</label>
            <select
              value={form.servicio}
              onChange={(e) => setForm({ ...form, servicio: e.target.value })}
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            >
              {tipos.map((t) => <option key={t.nombre}>{t.nombre}</option>)}
            </select>
          </div>
          <div className="flex gap-2">
            <div className="flex-1">
              <Field label="Fecha" type="date" value={form.fecha} onChange={(v) => setForm({ ...form, fecha: v })} />
            </div>
            <div className="flex-1">
              <Field label="Hora" type="time" value={form.hora} onChange={(v) => setForm({ ...form, hora: v })} />
            </div>
          </div>
          <Field label="Notas (opcional)" value={form.notas} onChange={(v) => setForm({ ...form, notas: v })} />
          <FormButtons onCancel={() => setForm(null)} onSave={guardar} />
        </Card>
      )}

      {proximas.length === 0 && pasadas.length === 0 && !form && (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            No tienes citas agendadas. Usa el botón de arriba para agregar la primera.
          </p>
        </Card>
      )}

      {proximas.length > 0 && (
        <>
          <p className="text-xs uppercase tracking-wide mt-1" style={{ color: MUTED }}>Próximas</p>
          {proximas.map((c) => <CitaCard key={c.id} c={c} />)}
        </>
      )}

      {pasadas.length > 0 && (
        <>
          <p className="text-xs uppercase tracking-wide mt-2" style={{ color: MUTED }}>Historial</p>
          {pasadas.map((c) => <CitaCard key={c.id} c={c} />)}
        </>
      )}
    </div>
  );
}

/* ---------------- Fidelidad ---------------- */
function Fidelidad({ data, save }) {
  const [vistaPrincipal, setVistaPrincipal] = useState("sellos");
  const [q, setQ] = useState("");
  const [form, setForm] = useState(null); // {id, nombre, metaSellos, premio} programa a crear/editar

  const programas = data.fidelidad && data.fidelidad.length ? data.fidelidad : DEFAULT_FIDELIDAD;
  const [activoId, setActivoId] = useState(programas[0]?.id);

  useEffect(() => {
    if (!programas.find((p) => p.id === activoId) && programas[0]) setActivoId(programas[0].id);
  }, [data.fidelidad]);

  const programaActivo = programas.find((p) => p.id === activoId) || programas[0];
  const idxActivo = programas.findIndex((p) => p.id === programaActivo?.id);

  const startNewPrograma = () => setForm({ id: null, nombre: "", metaSellos: "", premio: "" });
  const startEditPrograma = (p) => setForm({ id: p.id, nombre: p.nombre, metaSellos: p.metaSellos, premio: p.premio });

  const guardarPrograma = () => {
    if (!form.nombre.trim() || !form.metaSellos || !form.premio.trim()) return;
    let nuevos;
    if (form.id) {
      nuevos = programas.map((p) => (p.id === form.id ? { ...p, nombre: form.nombre.trim(), metaSellos: Number(form.metaSellos), premio: form.premio.trim() } : p));
    } else {
      const nuevo = { id: uid(), nombre: form.nombre.trim(), metaSellos: Number(form.metaSellos), premio: form.premio.trim() };
      nuevos = [...programas, nuevo];
      setActivoId(nuevo.id);
    }
    save({ ...data, fidelidad: nuevos });
    setForm(null);
  };

  const eliminarPrograma = (id) => {
    const nuevos = programas.filter((p) => p.id !== id);
    save({ ...data, fidelidad: nuevos });
    setForm(null);
  };

  const actualizarProgreso = (c, valor) => {
    const progreso = { ...(c.progreso || {}) };
    progreso[programaActivo.id] = Math.max(0, valor);
    save({ ...data, clientes: data.clientes.map((x) => (x.id === c.id ? { ...x, progreso } : x)) });
  };
  const sumar = (c) => actualizarProgreso(c, getSellos(c, programaActivo, idxActivo) + 1);
  const restar = (c) => actualizarProgreso(c, getSellos(c, programaActivo, idxActivo) - 1);
  const canjear = (c) => actualizarProgreso(c, 0);

  const filtrados = data.clientes.filter((c) => c.nombre.toLowerCase().includes(q.toLowerCase()));
  const meta = Number(programaActivo?.metaSellos) || 1;
  const conPremio = programaActivo ? filtrados.filter((c) => getSellos(c, programaActivo, idxActivo) >= meta) : [];
  const enProgreso = programaActivo ? filtrados.filter((c) => getSellos(c, programaActivo, idxActivo) < meta) : [];

  const Punchcard = ({ c }) => {
    const sellos = getSellos(c, programaActivo, idxActivo);
    const lista = Array.from({ length: meta }, (_, i) => i < sellos);
    const listo = sellos >= meta;
    return (
      <Card style={listo ? { borderColor: GOLD } : {}}>
        <div className="flex items-center justify-between mb-2">
          <div>
            <p className="font-semibold text-sm">{c.nombre}</p>
            <p className="text-xs" style={{ color: MUTED }}>{sellos}/{meta} servicios</p>
          </div>
          {listo && (
            <span className="text-[10px] px-2 py-1 rounded-full font-medium flex items-center gap-1" style={{ background: "#4A3B1E", color: GOLD }}>
              <PartyPopper size={11} /> Premio listo
            </span>
          )}
        </div>
        <div className="flex flex-wrap gap-1.5 mb-3">
          {lista.map((lleno, i) => (
            <div
              key={i}
              className="w-6 h-6 rounded-full flex items-center justify-center shrink-0"
              style={{
                background: lleno ? ACCENT : "transparent",
                border: lleno ? "none" : `1.5px dashed ${SURFACE2}`,
              }}
            >
              {lleno && <Check size={13} color={BG} strokeWidth={3} />}
            </div>
          ))}
        </div>
        <div className="flex gap-2">
          <button onClick={() => restar(c)} className="rounded-lg py-2 px-3 text-xs flex items-center justify-center" style={{ background: SURFACE2, color: MUTED }}>
            <Minus size={13} />
          </button>
          <button onClick={() => sumar(c)} className="flex-1 rounded-lg py-2 text-xs font-medium flex items-center justify-center gap-1" style={{ background: SURFACE2, color: ACCENT }}>
            <Plus size={13} /> Sello
          </button>
          {listo && (
            <button onClick={() => canjear(c)} className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1" style={{ background: GOLD, color: BG }}>
              <Gift size={13} /> Canjear
            </button>
          )}
        </div>
      </Card>
    );
  };

  return (
    <div className="flex flex-col gap-3">
      <div className="flex gap-2 rounded-xl p-1" style={{ background: SURFACE2 }}>
        <button
          onClick={() => setVistaPrincipal("sellos")}
          style={{ background: vistaPrincipal === "sellos" ? ACCENT : "transparent", color: vistaPrincipal === "sellos" ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1.5"
        >
          <Gift size={13} /> Sellos
        </button>
        <button
          onClick={() => setVistaPrincipal("membresias")}
          style={{ background: vistaPrincipal === "membresias" ? ACCENT : "transparent", color: vistaPrincipal === "membresias" ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1.5"
        >
          <Repeat size={13} /> Membresías
        </button>
      </div>

      {vistaPrincipal === "membresias" ? (
        <Membresias data={data} save={save} />
      ) : (
        <>
      {/* selector de programas */}
      <div className="flex gap-2 overflow-x-auto pb-1">
        {programas.map((p) => (
          <button
            key={p.id}
            onClick={() => setActivoId(p.id)}
            className="shrink-0 rounded-xl px-3 py-2 text-xs font-semibold whitespace-nowrap"
            style={{
              background: p.id === programaActivo?.id ? ACCENT : SURFACE2,
              color: p.id === programaActivo?.id ? BG : TEXT,
            }}
          >
            {p.nombre}
          </button>
        ))}
        <button
          onClick={startNewPrograma}
          className="shrink-0 rounded-xl px-3 py-2 text-xs font-semibold flex items-center gap-1"
          style={{ background: SURFACE2, color: ACCENT }}
        >
          <Plus size={13} /> Programa
        </button>
      </div>

      {!form && programaActivo && (
        <Card className="flex items-center justify-between">
          <div>
            <p className="text-xs" style={{ color: MUTED }}>Este programa</p>
            <p className="text-sm font-semibold mt-0.5">{programaActivo.metaSellos} servicios · {programaActivo.premio}</p>
          </div>
          <div className="flex gap-1">
            <IconBtn onClick={() => startEditPrograma(programaActivo)}><Pencil size={14} /></IconBtn>
            <IconBtn onClick={() => eliminarPrograma(programaActivo.id)} danger><Trash2 size={14} /></IconBtn>
          </div>
        </Card>
      )}

      {form && (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre del programa" value={form.nombre} onChange={(v) => setForm({ ...form, nombre: v })} placeholder="Ej. 5 lavados" />
          <Field label="Servicios necesarios" type="number" value={form.metaSellos} onChange={(v) => setForm({ ...form, metaSellos: v })} />
          <Field label="Premio" value={form.premio} onChange={(v) => setForm({ ...form, premio: v })} placeholder="Ej. 50% de descuento" />
          <FormButtons onCancel={() => setForm(null)} onSave={guardarPrograma} />
        </Card>
      )}

      {!programaActivo && !form && (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>Agrega tu primer programa de fidelidad con el botón de arriba.</p>
        </Card>
      )}

      {programaActivo && (
        <>
          <div className="flex items-center gap-2 rounded-xl px-3" style={{ background: SURFACE2 }}>
            <Search size={15} color={MUTED} />
            <input
              value={q}
              onChange={(e) => setQ(e.target.value)}
              placeholder="Buscar cliente…"
              className="bg-transparent flex-1 py-2.5 text-sm outline-none"
            />
          </div>

          {filtrados.length === 0 && (
            <Card>
              <p className="text-sm" style={{ color: MUTED }}>
                {data.clientes.length === 0
                  ? "Registra clientes desde Servicios o Clientes para empezar a llevar su tarjeta de fidelidad."
                  : "No hay clientes que coincidan con tu búsqueda."}
              </p>
            </Card>
          )}

          {conPremio.length > 0 && (
            <>
              <p className="text-xs uppercase tracking-wide mt-1" style={{ color: MUTED }}>Con premio disponible</p>
              {conPremio.map((c) => <Punchcard key={c.id} c={c} />)}
            </>
          )}

          {enProgreso.length > 0 && (
            <>
              <p className="text-xs uppercase tracking-wide mt-2" style={{ color: MUTED }}>En progreso</p>
              {enProgreso.map((c) => <Punchcard key={c.id} c={c} />)}
            </>
          )}
        </>
      )}
        </>
      )}
    </div>
  );
}

function Membresias({ data, save }) {
  const [form, setForm] = useState(null); // {id, nombre, precio, duracionDias, lavadosIncluidos}
  const [asignandoId, setAsignandoId] = useState(null);
  const [planElegido, setPlanElegido] = useState("");
  const [q, setQ] = useState("");

  const planes = data.membresias || [];

  const startNew = () => setForm({ id: null, nombre: "", precio: "", duracionDias: "30", lavadosIncluidos: "" });
  const startEdit = (p) => setForm({ id: p.id, nombre: p.nombre, precio: p.precio, duracionDias: p.duracionDias, lavadosIncluidos: p.lavadosIncluidos || "" });

  const guardarPlan = () => {
    if (!form.nombre.trim() || !form.precio || !form.duracionDias) return;
    const entrada = {
      id: form.id || uid(),
      nombre: form.nombre.trim(),
      precio: Number(form.precio),
      duracionDias: Number(form.duracionDias),
      lavadosIncluidos: form.lavadosIncluidos ? Number(form.lavadosIncluidos) : 0, // 0 = ilimitado
    };
    let nuevos;
    if (form.id) nuevos = planes.map((p) => (p.id === form.id ? entrada : p));
    else nuevos = [...planes, entrada];
    save({ ...data, membresias: nuevos });
    setForm(null);
  };

  const eliminarPlan = (id) => save({ ...data, membresias: planes.filter((p) => p.id !== id) });

  const asignar = (cliente) => {
    const plan = planes.find((p) => p.id === planElegido);
    if (!plan) return;
    const fechaInicio = todayStr();
    const fin = new Date();
    fin.setDate(fin.getDate() + plan.duracionDias);
    const membresia = { planId: plan.id, fechaInicio, fechaFin: fin.toISOString().split("T")[0], lavadosUsados: 0 };
    save({ ...data, clientes: data.clientes.map((c) => (c.id === cliente.id ? { ...c, membresia } : c)) });
    setAsignandoId(null);
    setPlanElegido("");
  };

  const cancelar = (cliente) => save({ ...data, clientes: data.clientes.map((c) => (c.id === cliente.id ? { ...c, membresia: null } : c)) });

  const estadoDe = (cliente) => {
    const m = cliente.membresia;
    if (!m) return null;
    const plan = planes.find((p) => p.id === m.planId);
    const vencida = m.fechaFin < todayStr();
    const agotada = plan && plan.lavadosIncluidos > 0 && m.lavadosUsados >= plan.lavadosIncluidos;
    return { m, plan, vencida, agotada, activa: !vencida && !agotada };
  };

  const filtrados = data.clientes.filter((c) => c.nombre.toLowerCase().includes(q.toLowerCase()));

  return (
    <div className="flex flex-col gap-3">
      {!form ? (
        <button
          onClick={startNew}
          style={{ background: ACCENT, color: BG }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Nuevo plan
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre del plan" value={form.nombre} onChange={(v) => setForm({ ...form, nombre: v })} placeholder="Ej. Lavados ilimitados" />
          <Field label="Precio" type="number" value={form.precio} onChange={(v) => setForm({ ...form, precio: v })} />
          <Field label="Duración (días)" type="number" value={form.duracionDias} onChange={(v) => setForm({ ...form, duracionDias: v })} placeholder="Ej. 30" />
          <Field label="Lavados incluidos (vacío = ilimitados)" type="number" value={form.lavadosIncluidos} onChange={(v) => setForm({ ...form, lavadosIncluidos: v })} />
          <FormButtons onCancel={() => setForm(null)} onSave={guardarPlan} />
        </Card>
      )}

      {planes.length === 0 && !form && (
        <Card><p className="text-sm" style={{ color: MUTED }}>Aún no tienes planes de membresía.</p></Card>
      )}

      {planes.map((p) => (
        <Card key={p.id} className="flex items-center justify-between">
          <div>
            <p className="font-semibold text-sm">{p.nombre}</p>
            <p className="text-xs font-mono mt-0.5" style={{ color: ACCENT }}>
              {money(p.precio)} · {p.duracionDias} días · {p.lavadosIncluidos > 0 ? `${p.lavadosIncluidos} lavados` : "Ilimitados"}
            </p>
          </div>
          <div className="flex gap-1">
            <IconBtn onClick={() => startEdit(p)}><Pencil size={14} /></IconBtn>
            <IconBtn onClick={() => eliminarPlan(p.id)} danger><Trash2 size={14} /></IconBtn>
          </div>
        </Card>
      ))}

      {planes.length > 0 && (
        <>
          <p className="text-xs uppercase tracking-wide mt-1" style={{ color: MUTED }}>Membresías de clientes</p>
          <div className="flex items-center gap-2 rounded-xl px-3" style={{ background: SURFACE2 }}>
            <Search size={15} color={MUTED} />
            <input
              value={q}
              onChange={(e) => setQ(e.target.value)}
              placeholder="Buscar cliente…"
              className="bg-transparent flex-1 py-2.5 text-sm outline-none"
            />
          </div>
          {filtrados.map((c) => {
            const est = estadoDe(c);
            return (
              <Card key={c.id}>
                <div className="flex items-center justify-between">
                  <div>
                    <p className="font-semibold text-sm">{c.nombre}</p>
                    {est ? (
                      <>
                        <p className="text-xs" style={{ color: MUTED }}>{est.plan?.nombre || "Plan eliminado"}</p>
                        <p className="text-xs font-mono mt-0.5" style={{ color: est.activa ? "#6FE0A8" : DANGER }}>
                          {est.vencida ? "Vencida" : est.agotada ? "Lavados agotados" : "Activa"} · vence {fecha(est.m.fechaFin)}
                          {est.plan?.lavadosIncluidos > 0 ? ` · ${est.m.lavadosUsados}/${est.plan.lavadosIncluidos} usados` : ""}
                        </p>
                      </>
                    ) : (
                      <p className="text-xs" style={{ color: MUTED }}>Sin membresía</p>
                    )}
                  </div>
                  {est && (
                    <button onClick={() => cancelar(c)} className="text-xs px-2 py-1 rounded-full" style={{ background: SURFACE2, color: DANGER }}>
                      Cancelar
                    </button>
                  )}
                </div>
                {asignandoId === c.id ? (
                  <div className="flex flex-col gap-2 mt-2.5 pt-2.5" style={{ borderTop: `1px solid ${SURFACE2}` }}>
                    <select
                      value={planElegido}
                      onChange={(e) => setPlanElegido(e.target.value)}
                      className="w-full rounded-lg px-3 py-2 text-sm outline-none"
                    >
                      <option value="">Selecciona un plan</option>
                      {planes.map((p) => <option key={p.id} value={p.id}>{p.nombre} · {money(p.precio)}</option>)}
                    </select>
                    <FormButtons onCancel={() => setAsignandoId(null)} onSave={() => asignar(c)} />
                  </div>
                ) : (
                  <button
                    onClick={() => { setAsignandoId(c.id); setPlanElegido(""); }}
                    className="text-xs font-medium mt-2.5 pt-2.5 flex items-center gap-1 w-full"
                    style={{ color: ACCENT, borderTop: `1px solid ${SURFACE2}` }}
                  >
                    <Repeat size={13} /> {est ? "Renovar / cambiar plan" : "Asignar membresía"}
                  </button>
                )}
              </Card>
            );
          })}
        </>
      )}
    </div>
  );
}

function Clientes({ data, save }) {
  const [q, setQ] = useState("");
  const [form, setForm] = useState(null);
  const [verHistorial, setVerHistorial] = useState(null); // id de cliente
  const [verInactivos, setVerInactivos] = useState(false);

  const filtered = data.clientes.filter((c) =>
    (c.nombre + c.vehiculo + c.placas).toLowerCase().includes(q.toLowerCase())
  );

  const startNew = () => setForm({ id: null, nombre: "", telefono: "", vehiculo: "", placas: "", sellos: 0, notas: "" });

  const guardar = () => {
    if (!form.nombre.trim()) return;
    let clientes;
    if (form.id) {
      clientes = data.clientes.map((c) => (c.id === form.id ? form : c));
    } else {
      clientes = [...data.clientes, { ...form, id: uid() }];
    }
    save({ ...data, clientes });
    setForm(null);
  };

  const eliminar = (id) => save({ ...data, clientes: data.clientes.filter((c) => c.id !== id) });

  // servicios asociados a un cliente: por nombre, y también por placa (cubre el caso de que el auto cambie de dueño)
  const historialDe = (c) => {
    const porPlaca = c.placas
      ? data.servicios.filter((s) => s.placas && s.placas.trim().toUpperCase() === c.placas.trim().toUpperCase())
      : [];
    const porNombre = data.servicios.filter((s) => s.cliente === c.nombre);
    const mapa = new Map();
    [...porPlaca, ...porNombre].forEach((s) => mapa.set(s.id, s));
    return [...mapa.values()].sort((a, b) => (a.fecha < b.fecha ? 1 : -1));
  };

  const statsFor = (c) => {
    const propios = historialDe(c);
    const ultimaVisita = propios.reduce((max, s) => (!max || s.fecha > max ? s.fecha : max), null);
    return { visitas: propios.length, gastado: propios.reduce((a, s) => a + Number(s.precio), 0), ultimaVisita, servicios: propios };
  };

  const inactivos = useMemo(() => {
    const hoy = todayStr();
    return data.clientes
      .map((c) => ({ c, st: statsFor(c) }))
      .filter(({ st }) => st.ultimaVisita && diasEntre(st.ultimaVisita, hoy) >= 30)
      .sort((a, b) => diasEntre(b.st.ultimaVisita, hoy) - diasEntre(a.st.ultimaVisita, hoy));
  }, [data.clientes, data.servicios]);

  const porMes = useMemo(() => {
    const primeraVisita = {};
    data.servicios.forEach((s) => {
      if (!primeraVisita[s.cliente] || s.fecha < primeraVisita[s.cliente]) primeraVisita[s.cliente] = s.fecha;
    });
    const meses = [];
    for (let i = 5; i >= 0; i--) {
      const d = new Date();
      d.setMonth(d.getMonth() - i);
      meses.push({ key: d.toISOString().slice(0, 7), label: d.toLocaleDateString("es-MX", { month: "short" }) });
    }
    return meses.map(({ key, label }) => {
      const clientesDelMes = new Set(data.servicios.filter((s) => s.fecha.slice(0, 7) === key).map((s) => s.cliente));
      let nuevos = 0, recurrentes = 0;
      clientesDelMes.forEach((c) => {
        if (primeraVisita[c] && primeraVisita[c].slice(0, 7) === key) nuevos++;
        else recurrentes++;
      });
      return { key, label, nuevos, recurrentes };
    });
  }, [data.servicios]);
  const maxMes = Math.max(1, ...porMes.map((m) => m.nuevos + m.recurrentes));

  return (
    <div className="flex flex-col gap-3">
      {data.servicios.length > 0 && (
        <Card>
          <p className="text-xs mb-2" style={{ color: MUTED }}>Clientes nuevos vs. recurrentes (últimos 6 meses)</p>
          <div className="flex items-end justify-between gap-2 h-24">
            {porMes.map((m) => {
              const total = m.nuevos + m.recurrentes;
              const alturaTotal = Math.max(total > 0 ? 10 : 0, (total / maxMes) * 80);
              const alturaNuevos = total > 0 ? (m.nuevos / total) * alturaTotal : 0;
              const alturaRecurrentes = alturaTotal - alturaNuevos;
              return (
                <div key={m.key} className="flex-1 flex flex-col items-center gap-1">
                  <div className="w-full flex flex-col justify-end" style={{ height: "80px" }}>
                    {alturaNuevos > 0 && <div className="w-full rounded-t-sm" style={{ height: `${alturaNuevos}px`, background: ACCENT }} />}
                    {alturaRecurrentes > 0 && (
                      <div className={alturaNuevos === 0 ? "w-full rounded-t-sm" : "w-full"} style={{ height: `${alturaRecurrentes}px`, background: GOLD }} />
                    )}
                  </div>
                  <span className="text-[10px] capitalize" style={{ color: MUTED }}>{m.label}</span>
                </div>
              );
            })}
          </div>
          <div className="flex gap-4 mt-2 text-[11px]">
            <p><span style={{ color: ACCENT }}>●</span> Nuevos</p>
            <p><span style={{ color: GOLD }}>●</span> Recurrentes</p>
          </div>
        </Card>
      )}

      {inactivos.length > 0 && (
        <Card>
          <button onClick={() => setVerInactivos(!verInactivos)} className="w-full flex items-center justify-between">
            <p className="text-sm font-semibold flex items-center gap-1.5" style={{ color: GOLD }}>
              <UserX size={15} /> {inactivos.length} cliente{inactivos.length > 1 ? "s" : ""} inactivo{inactivos.length > 1 ? "s" : ""} (30+ días)
            </p>
            <ChevronRight size={16} style={{ transform: verInactivos ? "rotate(90deg)" : "none", color: MUTED }} />
          </button>
          {verInactivos && (
            <div className="flex flex-col gap-2 mt-3">
              {inactivos.map(({ c, st }) => (
                <div key={c.id} className="flex items-center justify-between text-xs">
                  <div>
                    <p className="font-medium">{c.nombre}{c.telefono ? ` · ${c.telefono}` : ""}</p>
                    <p style={{ color: MUTED }}>Última visita: {fecha(st.ultimaVisita)} ({diasEntre(st.ultimaVisita, todayStr())} días)</p>
                  </div>
                </div>
              ))}
            </div>
          )}
        </Card>
      )}

      <div className="flex gap-2">
        <div className="flex-1 flex items-center gap-2 rounded-xl px-3" style={{ background: SURFACE2 }}>
          <Search size={15} color={MUTED} />
          <input
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder="Buscar cliente o placa…"
            className="bg-transparent flex-1 py-2.5 text-sm outline-none"
          />
        </div>
        <button onClick={startNew} style={{ background: ACCENT }} className="rounded-xl px-3 flex items-center justify-center">
          <Plus size={18} color={BG} />
        </button>
      </div>

      {form && (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre" value={form.nombre} onChange={(v) => setForm({ ...form, nombre: v })} />
          <Field label="Teléfono" value={form.telefono} onChange={(v) => setForm({ ...form, telefono: v })} />
          <Field label="Vehículo" value={form.vehiculo} onChange={(v) => setForm({ ...form, vehiculo: v })} placeholder="Ej. Nissan Versa gris" />
          <Field label="Placas" value={form.placas} onChange={(v) => setForm({ ...form, placas: v })} />
          <TextArea label="Notas (preferencias, alergias, etc.)" value={form.notas || ""} onChange={(v) => setForm({ ...form, notas: v })} placeholder="Ej. No le gusta que se use cera" />
          <FormButtons onCancel={() => setForm(null)} onSave={guardar} />
        </Card>
      )}

      {filtered.length === 0 && !form && (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            {data.clientes.length === 0
              ? "Aún no tienes clientes. Agrega el primero con el botón +."
              : "No hay clientes que coincidan con tu búsqueda."}
          </p>
        </Card>
      )}

      {filtered.map((c) => {
        const st = statsFor(c);
        const expandido = verHistorial === c.id;
        return (
          <Card key={c.id}>
            <div className="flex items-center justify-between">
              <div>
                <p className="font-semibold text-sm">{c.nombre}</p>
                <p className="text-xs" style={{ color: MUTED }}>{c.vehiculo}{c.placas ? ` · ${c.placas}` : ""}</p>
                <p className="text-xs font-mono mt-1" style={{ color: ACCENT }}>
                  {st.visitas} visitas · {money(st.gastado)}
                </p>
                {st.ultimaVisita && (
                  <p className="text-xs" style={{ color: MUTED }}>Última visita: {fecha(st.ultimaVisita)}</p>
                )}
                {c.notas && (
                  <p className="text-xs mt-1 flex items-start gap-1" style={{ color: GOLD }}>
                    <StickyNote size={11} className="shrink-0 mt-0.5" /> {c.notas}
                  </p>
                )}
              </div>
              <div className="flex gap-1">
                <IconBtn onClick={() => setForm(c)}><Pencil size={14} /></IconBtn>
                <IconBtn onClick={() => eliminar(c.id)} danger><Trash2 size={14} /></IconBtn>
              </div>
            </div>
            {st.visitas > 0 && (
              <button
                onClick={() => setVerHistorial(expandido ? null : c.id)}
                className="text-xs font-medium mt-2.5 pt-2.5 flex items-center gap-1 w-full"
                style={{ color: ACCENT, borderTop: `1px solid ${SURFACE2}` }}
              >
                <History size={13} /> {expandido ? "Ocultar historial" : `Ver historial (${st.visitas})`}
              </button>
            )}
            {expandido && (
              <div className="flex flex-col gap-1.5 mt-2">
                {st.servicios.map((s) => (
                  <div key={s.id} className="flex items-center justify-between text-xs">
                    <span>
                      {fecha(s.fecha)} · {s.tipo}
                      {s.cliente !== c.nombre ? ` · ${s.cliente}` : ""}
                    </span>
                    <span className="font-mono" style={{ color: MUTED }}>{money(s.precio)}</span>
                  </div>
                ))}
              </div>
            )}
          </Card>
        );
      })}
    </div>
  );
}

/* ---------------- Servicios ---------------- */
function Servicios({ data, save, sucursalId, miNombre }) {
  const [showForm, setShowForm] = useState(false);
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const misEmpleados = data.empleados.filter((e) => pertenece(e, sucursalId, sucursales));
  const misServicios = data.servicios.filter((s) => pertenece(s, sucursalId, sucursales));
  const [form, setForm] = useState(blankServicio());

  function blankServicio() {
    const tipos = data.tiposServicio && data.tiposServicio.length ? data.tiposServicio : DEFAULT_TIPOS_SERVICIO;
    return {
      id: null,
      fecha: todayStr(),
      cliente: "",
      placas: "",
      tipoVehiculo: TIPOS_VEHICULO[0],
      tipo: tipos[0].nombre,
      precio: tipos[0].precio,
      extras: [],
      empleado: misEmpleados[0]?.nombre || "",
      metodo: "efectivo",
      pagado: false,
      estado: "en_progreso",
      horaInicio: null,
      horaFin: null,
      propina: 0,
    };
  }

  const abrirEditarServicio = (s) => {
    setForm({ extras: [], ...s });
    setShowForm(true);
  };

  const toggleExtra = (extra) => {
    const yaEsta = (form.extras || []).some((e) => e.nombre === extra.nombre);
    if (yaEsta) {
      setForm({ ...form, extras: form.extras.filter((e) => e.nombre !== extra.nombre), precio: Math.max(0, Number(form.precio) - Number(extra.precio)) });
    } else {
      setForm({ ...form, extras: [...(form.extras || []), extra], precio: Number(form.precio) + Number(extra.precio) });
    }
  };

  const guardar = () => {
    if (!form.cliente.trim()) return;
    let servicios;
    const clientesActualizados = form.id
      ? data.clientes
      : upsertCliente(data.clientes, form.cliente, form.placas, form.tipoVehiculo);
    if (form.id) {
      servicios = data.servicios.map((s) => (s.id === form.id ? form : s));
    } else {
      servicios = [{ ...form, id: uid(), estado: "en_progreso", horaInicio: Date.now(), horaFin: null, sucursalId }, ...data.servicios];
    }
    save({ ...data, servicios, clientes: clientesActualizados });
    setForm(blankServicio());
    setShowForm(false);
  };

  const [finalizando, setFinalizando] = useState(null); // id del servicio a finalizar
  const [propinaInput, setPropinaInput] = useState("");
  const [descuentoFidelidad, setDescuentoFidelidad] = useState(null); // {programaId, tipo: '50'|'gratis'}
  const [reciboId, setReciboId] = useState(null);

  const calificar = (s, estrellas) => save({ ...data, servicios: data.servicios.map((x) => (x.id === s.id ? { ...x, calificacion: estrellas } : x)) });

  const finalizarServicio = (s) => {
    const propina = Number(propinaInput) || 0;
    const programas = data.fidelidad && data.fidelidad.length ? data.fidelidad : DEFAULT_FIDELIDAD;
    const esMembresia = descuentoFidelidad?.origen === "membresia";
    const esFidelidad = descuentoFidelidad?.origen === "fidelidad";
    const precioFinal = esMembresia
      ? 0
      : esFidelidad
      ? (descuentoFidelidad.tipo === "gratis" ? 0 : Math.round(Number(s.precio) / 2))
      : s.precio;
    const clientesActualizados = data.clientes.map((c) => {
      if (c.nombre.trim().toLowerCase() !== s.cliente.trim().toLowerCase()) return c;
      const progreso = { ...(c.progreso || {}) };
      programas.forEach((p, i) => {
        progreso[p.id] = esFidelidad && descuentoFidelidad.programaId === p.id ? 0 : getSellos(c, p, i) + 1;
      });
      let membresia = c.membresia;
      if (esMembresia && membresia) membresia = { ...membresia, lavadosUsados: (Number(membresia.lavadosUsados) || 0) + 1 };
      return { ...c, progreso, membresia };
    });
    save({
      ...data,
      servicios: data.servicios.map((x) =>
        x.id === s.id
          ? {
              ...x,
              estado: "finalizado",
              horaFin: Date.now(),
              propina,
              precio: precioFinal,
              premioAplicado: esMembresia
                ? "Cubierto por membresía"
                : esFidelidad
                ? programas.find((p) => p.id === descuentoFidelidad.programaId)?.nombre || null
                : null,
            }
          : x
      ),
      clientes: clientesActualizados,
    });
    setFinalizando(null);
    setPropinaInput("");
    setDescuentoFidelidad(null);
  };

  const togglePago = (s) => save({ ...data, servicios: data.servicios.map((x) => (x.id === s.id ? { ...x, pagado: !x.pagado } : x)) });
  const eliminar = (id) => save({ ...data, servicios: data.servicios.filter((s) => s.id !== id) });

  const [editandoTiempo, setEditandoTiempo] = useState(null); // id del servicio
  const [inicioInput, setInicioInput] = useState("");
  const [finInput, setFinInput] = useState("");

  const abrirEditarTiempo = (s) => {
    setEditandoTiempo(s.id);
    setInicioInput(tsToInputLocal(s.horaInicio || Date.now()));
    setFinInput(tsToInputLocal(s.horaFin || Date.now()));
  };

  const guardarTiempo = (s) => {
    const nuevoInicio = inputLocalToTs(inicioInput);
    const nuevoFin = s.estado === "finalizado" ? inputLocalToTs(finInput) : s.horaFin;
    save({ ...data, servicios: data.servicios.map((x) => (x.id === s.id ? { ...x, horaInicio: nuevoInicio, horaFin: nuevoFin } : x)) });
    setEditandoTiempo(null);
  };

  const porFecha = useMemo(() => {
    const groups = {};
    [...misServicios]
      .sort((a, b) => (a.fecha < b.fecha ? 1 : -1))
      .forEach((s) => {
        groups[s.fecha] = groups[s.fecha] || [];
        groups[s.fecha].push(s);
      });
    return groups;
  }, [misServicios]);

  const miDia = useMemo(() => {
    if (!miNombre) return null;
    const hoy = todayStr();
    const propios = misServicios.filter((s) => s.fecha === hoy && s.empleado === miNombre);
    const generado = propios.reduce((a, s) => a + Number(s.precio), 0);
    const propinas = propios.reduce((a, s) => a + Number(s.propina || 0), 0);
    const finalizados = propios.filter((s) => s.estado === "finalizado").length;
    const enCurso = propios.length - finalizados;
    const misEmp = data.empleados.find((e) => e.nombre === miNombre);
    const comisionGanada = generado * ((Number(misEmp?.comision) || 0) / 100);
    return { total: propios.length, finalizados, enCurso, generado, propinas, comisionGanada, comision: Number(misEmp?.comision) || 0 };
  }, [misServicios, miNombre, data.empleados]);

  if (reciboId) {
    const servicioRecibo = data.servicios.find((s) => s.id === reciboId);
    if (servicioRecibo) {
      return <ReciboServicio servicio={servicioRecibo} data={data} onBack={() => setReciboId(null)} />;
    }
  }

  return (
    <div className="flex flex-col gap-3">
      {miDia && (
        <Card>
          <p className="text-xs mb-2" style={{ color: MUTED }}>Tu día de hoy</p>
          <div className="grid grid-cols-2 gap-2">
            <div>
              <p className="font-mono text-xl font-bold">{miDia.total}</p>
              <p className="text-[11px]" style={{ color: MUTED }}>
                servicios{miDia.enCurso > 0 ? ` (${miDia.enCurso} en curso)` : ""}
              </p>
            </div>
            <div>
              <p className="font-mono text-xl font-bold" style={{ color: ACCENT }}>{money(miDia.generado)}</p>
              <p className="text-[11px]" style={{ color: MUTED }}>generado</p>
            </div>
            <div>
              <p className="font-mono text-xl font-bold" style={{ color: GOLD }}>{money(miDia.propinas)}</p>
              <p className="text-[11px]" style={{ color: MUTED }}>propinas</p>
            </div>
            {miDia.comision > 0 && (
              <div>
                <p className="font-mono text-xl font-bold" style={{ color: "#6FE0A8" }}>{money(miDia.comisionGanada)}</p>
                <p className="text-[11px]" style={{ color: MUTED }}>tu comisión ({miDia.comision}%)</p>
              </div>
            )}
          </div>
        </Card>
      )}

      {!showForm ? (
        <button
          onClick={() => { setForm(blankServicio()); setShowForm(true); }}
          style={{ background: ACCENT, color: BG }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Registrar servicio
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <p className="text-sm font-semibold" style={{ color: ACCENT }}>
            {form.id ? "Editar servicio" : "Nuevo servicio"}
          </p>
          <Field label="Fecha" type="date" value={form.fecha} onChange={(v) => setForm({ ...form, fecha: v })} />
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Cliente</label>
            <input
              list="clientes-list"
              value={form.cliente}
              onChange={(e) => {
                const val = e.target.value;
                const match = data.clientes.find((c) => c.nombre.trim().toLowerCase() === val.trim().toLowerCase());
                setForm({
                  ...form,
                  cliente: val,
                  placas: match ? match.placas || form.placas : form.placas,
                });
              }}
              placeholder="Nombre del cliente"
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            />
            <datalist id="clientes-list">
              {data.clientes.map((c) => <option key={c.id} value={c.nombre} />)}
            </datalist>
          </div>
          {(() => {
            const match = data.clientes.find((c) => c.nombre.trim().toLowerCase() === form.cliente.trim().toLowerCase());
            return match?.notas ? (
              <div className="rounded-lg px-3 py-2 text-xs flex items-start gap-2" style={{ background: "#4A3B1E", color: GOLD }}>
                <StickyNote size={13} className="shrink-0 mt-0.5" /> {match.notas}
              </div>
            ) : null;
          })()}
          <Field label="Placa" value={form.placas} onChange={(v) => setForm({ ...form, placas: v })} placeholder="Ej. ABC-123" />
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Tipo de vehículo</label>
            <select
              value={form.tipoVehiculo}
              onChange={(e) => setForm({ ...form, tipoVehiculo: e.target.value })}
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            >
              {TIPOS_VEHICULO.map((v) => <option key={v}>{v}</option>)}
            </select>
          </div>
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Tipo de servicio</label>
            <select
              value={form.tipo}
              onChange={(e) => {
                const tipos = data.tiposServicio && data.tiposServicio.length ? data.tiposServicio : DEFAULT_TIPOS_SERVICIO;
                const t = tipos.find((x) => x.nombre === e.target.value);
                const extrasTotal = (form.extras || []).reduce((a, ex) => a + Number(ex.precio), 0);
                setForm({ ...form, tipo: e.target.value, precio: t ? t.precio + extrasTotal : form.precio });
              }}
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            >
              {(data.tiposServicio && data.tiposServicio.length ? data.tiposServicio : DEFAULT_TIPOS_SERVICIO).map((t) => (
                <option key={t.nombre}>{t.nombre}</option>
              ))}
              <option>Otro</option>
            </select>
          </div>
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Servicios adicionales (opcional)</label>
            <div className="flex flex-wrap gap-1.5 mt-1">
              {(data.serviciosAdicionales && data.serviciosAdicionales.length ? data.serviciosAdicionales : DEFAULT_ADICIONALES).map((extra) => {
                const activo = (form.extras || []).some((e) => e.nombre === extra.nombre);
                return (
                  <button
                    key={extra.nombre}
                    type="button"
                    onClick={() => toggleExtra(extra)}
                    className="text-xs px-2.5 py-1.5 rounded-lg font-medium flex items-center gap-1"
                    style={{ background: activo ? ACCENT : SURFACE2, color: activo ? BG : TEXT }}
                  >
                    {activo ? <Check size={11} /> : <Plus size={11} />} {extra.nombre} · {money(extra.precio)}
                  </button>
                );
              })}
            </div>
          </div>
          <Field label="Precio total" type="number" value={form.precio} onChange={(v) => setForm({ ...form, precio: v })} />
          {misEmpleados.length > 0 && (
            <div>
              <label className="text-xs" style={{ color: MUTED }}>Empleado</label>
              <select
                value={form.empleado}
                onChange={(e) => setForm({ ...form, empleado: e.target.value })}
                className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
              >
                <option value="">Sin asignar</option>
                {misEmpleados.map((e) => <option key={e.id}>{e.nombre}</option>)}
              </select>
            </div>
          )}
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Método de pago</label>
            <div className="flex gap-2 mt-1">
              {METODOS_PAGO.map((m) => (
                <button
                  key={m.id}
                  onClick={() => setForm({ ...form, metodo: m.id })}
                  style={{
                    background: form.metodo === m.id ? ACCENT : SURFACE2,
                    color: form.metodo === m.id ? BG : TEXT,
                  }}
                  className="flex-1 rounded-lg py-2 text-xs flex flex-col items-center gap-1"
                >
                  <m.icon size={14} /> {m.label}
                </button>
              ))}
            </div>
          </div>
          <label className="flex items-center gap-2 text-sm mt-1">
            <input type="checkbox" checked={form.pagado} onChange={(e) => setForm({ ...form, pagado: e.target.checked })} />
            Ya está pagado
          </label>
          <FormButtons onCancel={() => setShowForm(false)} onSave={guardar} />
        </Card>
      )}

      {Object.keys(porFecha).length === 0 && !showForm && (
        <Card><p className="text-sm" style={{ color: MUTED }}>Sin servicios registrados todavía.</p></Card>
      )}

      {Object.entries(porFecha).map(([f, list]) => (
        <div key={f}>
          <p className="text-xs uppercase tracking-wide mb-1.5 mt-1 capitalize" style={{ color: MUTED }}>{fecha(f)}</p>
          <div className="flex flex-col gap-2">
            {list.map((s) => {
              const enProgreso = s.estado !== "finalizado";
              return (
                <Card key={s.id}>
                  <div className="flex items-center justify-between">
                    <div>
                      <p className="font-semibold text-sm">
                        {s.cliente}{s.placas ? <span style={{ color: MUTED }} className="font-normal"> · {s.placas}</span> : ""}
                      </p>
                      <p className="text-xs" style={{ color: MUTED }}>
                        {s.tipoVehiculo ? `${s.tipoVehiculo} · ` : ""}{s.tipo}{s.empleado ? ` · ${s.empleado}` : ""}
                      </p>
                      {s.extras && s.extras.length > 0 && (
                        <p className="text-[11px] mt-0.5" style={{ color: ACCENT }}>
                          + {s.extras.map((e) => e.nombre).join(", ")}
                        </p>
                      )}
                    </div>
                    <div className="flex items-center gap-2">
                      {!enProgreso && <p className="font-mono text-sm font-semibold">{money(s.precio)}</p>}
                      {enProgreso ? (
                        <span
                          className="text-[10px] px-2 py-1 rounded-full font-medium flex items-center gap-1"
                          style={{ background: "#4A3B1E", color: GOLD }}
                        >
                          <span className="w-1.5 h-1.5 rounded-full animate-pulse" style={{ background: GOLD }} />
                          {s.horaInicio ? <LiveTimer startMs={s.horaInicio} /> : "En progreso"}
                        </span>
                      ) : (
                        <button
                          onClick={() => togglePago(s)}
                          style={{ background: s.pagado ? "#1E4A3A" : "#4A331E", color: s.pagado ? "#6FE0A8" : GOLD }}
                          className="text-[10px] px-2 py-1 rounded-full font-medium"
                        >
                          {s.pagado ? "Pagado" : "Pendiente"}
                        </button>
                      )}
                      {enProgreso && (
                        <IconBtn onClick={() => abrirEditarTiempo(s)}><Clock size={13} /></IconBtn>
                      )}
                      <IconBtn onClick={() => abrirEditarServicio(s)}><Pencil size={13} /></IconBtn>
                      <IconBtn onClick={() => eliminar(s.id)} danger><Trash2 size={13} /></IconBtn>
                    </div>
                  </div>

                  {editandoTiempo === s.id && (
                    <div className="mt-3 pt-3 flex flex-col gap-2" style={{ borderTop: `1px solid ${SURFACE2}` }}>
                      <p className="text-xs font-semibold flex items-center gap-1.5" style={{ color: ACCENT }}>
                        <Clock size={13} /> Ajustar hora {s.estado === "finalizado" ? "de inicio y fin" : "de inicio"}
                      </p>
                      <Field label="Hora en que inició" type="datetime-local" value={inicioInput} onChange={setInicioInput} />
                      {s.estado === "finalizado" && (
                        <Field label="Hora en que terminó" type="datetime-local" value={finInput} onChange={setFinInput} />
                      )}
                      <FormButtons onCancel={() => setEditandoTiempo(null)} onSave={() => guardarTiempo(s)} />
                    </div>
                  )}

                  {enProgreso && finalizando !== s.id && (
                    <button
                      onClick={() => { setFinalizando(s.id); setPropinaInput(""); }}
                      style={{ background: ACCENT, color: BG }}
                      className="w-full mt-3 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1.5"
                    >
                      <Check size={13} /> Finalizar servicio
                    </button>
                  )}

                  {finalizando === s.id && (
                    <div className="mt-3 pt-3 flex flex-col gap-2" style={{ borderTop: `1px solid ${SURFACE2}` }}>
                      <Field label="Propina (opcional)" type="number" value={propinaInput} onChange={setPropinaInput} placeholder="0" />
                      {(() => {
                        const cliente = data.clientes.find((c) => c.nombre.trim().toLowerCase() === s.cliente.trim().toLowerCase());
                        if (!cliente) return null;
                        const programas = data.fidelidad && data.fidelidad.length ? data.fidelidad : DEFAULT_FIDELIDAD;
                        const elegibles = programas
                          .map((p, i) => ({ p, i, proyectado: getSellos(cliente, p, i) + 1 }))
                          .filter((x) => x.proyectado >= (Number(x.p.metaSellos) || 1));

                        const planes = data.membresias || [];
                        const m = cliente.membresia;
                        const planCliente = m ? planes.find((p) => p.id === m.planId) : null;
                        const membresiaValida =
                          m && planCliente && m.fechaFin >= todayStr() &&
                          (!planCliente.lavadosIncluidos || m.lavadosUsados < planCliente.lavadosIncluidos);

                        if (elegibles.length === 0 && !membresiaValida) return null;
                        return (
                          <div className="rounded-lg p-2.5" style={{ background: "#241D0E" }}>
                            <p className="text-xs font-semibold flex items-center gap-1.5 mb-1.5" style={{ color: GOLD }}>
                              <Gift size={13} /> Beneficios disponibles
                            </p>
                            <div className="flex flex-col gap-1.5">
                              <button
                                onClick={() => setDescuentoFidelidad(null)}
                                className="text-left text-xs px-2 py-1.5 rounded-md"
                                style={{ background: !descuentoFidelidad ? ACCENT : SURFACE2, color: !descuentoFidelidad ? BG : TEXT }}
                              >
                                No aplicar
                              </button>
                              {membresiaValida && (
                                <button
                                  onClick={() => setDescuentoFidelidad({ origen: "membresia" })}
                                  className="text-left text-xs px-2 py-1.5 rounded-md flex items-center gap-1.5"
                                  style={{ background: descuentoFidelidad?.origen === "membresia" ? ACCENT : SURFACE2, color: descuentoFidelidad?.origen === "membresia" ? BG : TEXT }}
                                >
                                  <Repeat size={12} /> Cubierto por membresía: {planCliente.nombre}
                                </button>
                              )}
                              {elegibles.map(({ p }) => {
                                const esGratis = /gratis/i.test(p.premio);
                                const tipo = esGratis ? "gratis" : "50";
                                const activo = descuentoFidelidad?.origen === "fidelidad" && descuentoFidelidad?.programaId === p.id;
                                return (
                                  <button
                                    key={p.id}
                                    onClick={() => setDescuentoFidelidad({ origen: "fidelidad", programaId: p.id, tipo })}
                                    className="text-left text-xs px-2 py-1.5 rounded-md"
                                    style={{ background: activo ? ACCENT : SURFACE2, color: activo ? BG : TEXT }}
                                  >
                                    Aplicar {p.nombre} · {p.premio}
                                  </button>
                                );
                              })}
                            </div>
                          </div>
                        );
                      })()}
                      <FormButtons onCancel={() => { setFinalizando(null); setDescuentoFidelidad(null); }} onSave={() => finalizarServicio(s)} />
                    </div>
                  )}

                  {!enProgreso && (
                    <>
                      <p className="text-[10px] mt-1.5 flex items-center gap-1" style={{ color: MUTED }}>
                        <span>
                          {s.horaInicio && s.horaFin ? `Duró ${duracionTexto(s.horaFin - s.horaInicio)}` : "Sin tiempo registrado"}
                          {s.propina > 0 ? ` · Propina ${money(s.propina)}` : ""}
                          {s.premioAplicado ? (
                            <span style={{ color: GOLD }}> · 🎁 {s.premioAplicado}</span>
                          ) : ""}
                        </span>
                        <button onClick={() => abrirEditarTiempo(s)} className="underline">editar tiempo</button>
                      </p>
                      <div className="flex items-center justify-between mt-2.5 pt-2.5" style={{ borderTop: `1px solid ${SURFACE2}` }}>
                        <div className="flex items-center gap-0.5">
                          {[1, 2, 3, 4, 5].map((n) => (
                            <button key={n} onClick={() => calificar(s, n)}>
                              <Star
                                size={16}
                                color={n <= (s.calificacion || 0) ? GOLD : SURFACE2}
                                fill={n <= (s.calificacion || 0) ? GOLD : "none"}
                                strokeWidth={1.5}
                              />
                            </button>
                          ))}
                        </div>
                        <button
                          onClick={() => setReciboId(s.id)}
                          className="text-xs font-medium flex items-center gap-1"
                          style={{ color: ACCENT }}
                        >
                          <FileText size={13} /> Recibo
                        </button>
                      </div>
                    </>
                  )}
                </Card>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

/* ---------------- Recibo digital ---------------- */
function ReciboServicio({ servicio: s, data, onBack }) {
  const cliente = data.clientes.find((c) => c.nombre.trim().toLowerCase() === s.cliente.trim().toLowerCase());
  const fechaHora = new Date(s.horaFin || Date.now()).toLocaleString("es-MX", {
    day: "numeric", month: "long", year: "numeric", hour: "2-digit", minute: "2-digit",
  });
  const metodoLabel = METODOS_PAGO.find((m) => m.id === s.metodo)?.label || s.metodo;
  const extras = s.extras || [];
  const extrasTotal = extras.reduce((a, e) => a + Number(e.precio), 0);
  const precioBase = Math.max(0, Number(s.precio) - extrasTotal);
  const total = Number(s.precio) + Number(s.propina || 0);

  const textoWhatsapp = () => {
    let t = `🧾 *Recibo · ${data.nombreNegocio}*\n📅 ${fechaHora}\n\n`;
    t += `Cliente: ${s.cliente}\n`;
    if (s.placas) t += `Placas: ${s.placas}\n`;
    t += `Vehículo: ${s.tipoVehiculo}\n`;
    t += `Servicio: ${s.tipo} (${money(precioBase)})\n`;
    extras.forEach((e) => { t += `+ ${e.nombre}: ${money(e.precio)}\n`; });
    if (s.empleado) t += `Atendido por: ${s.empleado}\n`;
    t += `\nPrecio: ${money(s.precio)}\n`;
    if (s.premioAplicado) t += `Premio aplicado: ${s.premioAplicado}\n`;
    if (s.propina > 0) t += `Propina: ${money(s.propina)}\n`;
    t += `*Total: ${money(total)}*\n`;
    t += `Método de pago: ${metodoLabel} · ${s.pagado ? "Pagado" : "Pendiente"}\n`;
    t += `\n¡Gracias por tu preferencia! 🚗💦`;
    return t;
  };

  const compartirWhatsapp = () => {
    const tel = cliente?.telefono ? cliente.telefono.replace(/\D/g, "") : "";
    window.open(`https://wa.me/${tel}?text=${encodeURIComponent(textoWhatsapp())}`, "_blank");
  };

  return (
    <div className="flex flex-col gap-3">
      <button onClick={onBack} className="flex items-center gap-1.5 text-sm mb-1" style={{ color: MUTED }}>
        <ArrowLeft size={16} /> Regresar
      </button>

      <Card className="flex flex-col items-center text-center gap-1 py-6">
        <Droplets size={28} color={ACCENT} />
        <p className="font-display text-lg font-bold mt-1">{data.nombreNegocio}</p>
        <p className="text-xs" style={{ color: MUTED }}>{fechaHora}</p>
      </Card>

      <Card className="flex flex-col gap-2">
        <div className="flex justify-between text-sm">
          <span style={{ color: MUTED }}>Cliente</span>
          <span className="font-semibold">{s.cliente}</span>
        </div>
        {s.placas && (
          <div className="flex justify-between text-sm">
            <span style={{ color: MUTED }}>Placas</span>
            <span>{s.placas}</span>
          </div>
        )}
        <div className="flex justify-between text-sm">
          <span style={{ color: MUTED }}>Vehículo</span>
          <span>{s.tipoVehiculo}</span>
        </div>
        <div className="flex justify-between text-sm">
          <span style={{ color: MUTED }}>Servicio</span>
          <span>{s.tipo}</span>
        </div>
        {s.empleado && (
          <div className="flex justify-between text-sm">
            <span style={{ color: MUTED }}>Atendido por</span>
            <span>{s.empleado}</span>
          </div>
        )}
      </Card>

      <Card className="flex flex-col gap-2">
        <div className="flex justify-between text-sm">
          <span style={{ color: MUTED }}>{s.tipo}</span>
          <span className="font-mono">{money(precioBase)}</span>
        </div>
        {extras.map((e) => (
          <div key={e.nombre} className="flex justify-between text-sm">
            <span style={{ color: MUTED }}>+ {e.nombre}</span>
            <span className="font-mono">{money(e.precio)}</span>
          </div>
        ))}
        {s.premioAplicado && (
          <div className="flex justify-between text-sm" style={{ color: GOLD }}>
            <span>🎁 Premio aplicado</span>
            <span>{s.premioAplicado}</span>
          </div>
        )}
        {s.propina > 0 && (
          <div className="flex justify-between text-sm">
            <span style={{ color: MUTED }}>Propina</span>
            <span className="font-mono">{money(s.propina)}</span>
          </div>
        )}
        <div className="flex justify-between pt-2 mt-1" style={{ borderTop: `1px solid ${SURFACE2}` }}>
          <span className="font-semibold">Total</span>
          <span className="font-mono text-lg font-bold" style={{ color: ACCENT }}>{money(total)}</span>
        </div>
        <p className="text-xs" style={{ color: MUTED }}>
          {metodoLabel} · {s.pagado ? "Pagado" : "Pendiente de pago"}
        </p>
      </Card>

      <div className="flex gap-2">
        <button
          onClick={compartirWhatsapp}
          className="flex-1 rounded-xl py-2.5 text-sm font-semibold flex items-center justify-center gap-1.5"
          style={{ background: "#25D366", color: "#0B2027" }}
        >
          <Share2 size={15} /> WhatsApp
        </button>
        <button
          onClick={() => window.print()}
          className="flex-1 rounded-xl py-2.5 text-sm font-semibold flex items-center justify-center gap-1.5"
          style={{ background: SURFACE2, color: TEXT }}
        >
          <Printer size={15} /> Imprimir
        </button>
      </div>
    </div>
  );
}

/* ---------------- Empleados ---------------- */
function Empleados({ data, save, sucursalId, sucursales }) {
  const [form, setForm] = useState(null);
  const listaSucursales = sucursales && sucursales.length ? sucursales : DEFAULT_SUCURSALES;
  const misEmpleados = data.empleados.filter((e) => pertenece(e, sucursalId, listaSucursales));

  const guardar = () => {
    if (!form.nombre.trim()) return;
    let empleados;
    if (form.id) empleados = data.empleados.map((e) => (e.id === form.id ? form : e));
    else empleados = [...data.empleados, { ...form, id: uid(), sucursalId }];
    save({ ...data, empleados });
    setForm(null);
  };
  const eliminar = (id) => save({ ...data, empleados: data.empleados.filter((e) => e.id !== id) });

  const statsFor = (nombre, comision) => {
    const propios = data.servicios.filter((s) => s.empleado === nombre);
    const generado = propios.reduce((a, s) => a + Number(s.precio), 0);
    const calificados = propios.filter((s) => Number(s.calificacion) > 0);
    const promedioCalificacion = calificados.length
      ? calificados.reduce((a, s) => a + Number(s.calificacion), 0) / calificados.length
      : 0;
    return {
      servicios: propios.length,
      generado,
      propinas: propios.reduce((a, s) => a + Number(s.propina || 0), 0),
      comisionGanada: generado * ((Number(comision) || 0) / 100),
      promedioCalificacion,
      totalCalificados: calificados.length,
    };
  };

  return (
    <div className="flex flex-col gap-3">
      {!form ? (
        <button
          onClick={() => setForm({ id: null, nombre: "", puesto: "Lavador", telefono: "", pin: "", comision: "" })}
          style={{ background: ACCENT, color: BG }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Agregar empleado
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre" value={form.nombre} onChange={(v) => setForm({ ...form, nombre: v })} />
          <Field label="Puesto" value={form.puesto} onChange={(v) => setForm({ ...form, puesto: v })} placeholder="Ej. Lavador, encargado…" />
          <Field label="Teléfono" value={form.telefono} onChange={(v) => setForm({ ...form, telefono: v })} />
          {listaSucursales.length > 1 && (
            <div>
              <label className="text-xs" style={{ color: MUTED }}>Sucursal</label>
              <select
                value={form.sucursalId || sucursalId}
                onChange={(e) => setForm({ ...form, sucursalId: e.target.value })}
                className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
              >
                {listaSucursales.map((s) => <option key={s.id} value={s.id}>{s.nombre}</option>)}
              </select>
            </div>
          )}
          <Field
            label="Comisión por servicio (%)"
            type="number"
            value={form.comision ?? ""}
            onChange={(v) => setForm({ ...form, comision: v })}
            placeholder="Ej. 20"
          />
          <Field
            label="PIN de acceso (4 dígitos, opcional)"
            value={form.pin || ""}
            onChange={(v) => setForm({ ...form, pin: v.replace(/\D/g, "").slice(0, 4) })}
            placeholder="Ej. 1234"
          />
          <FormButtons onCancel={() => setForm(null)} onSave={guardar} />
        </Card>
      )}

      {misEmpleados.length === 0 && !form && (
        <Card><p className="text-sm" style={{ color: MUTED }}>Aún no registras a tu equipo.</p></Card>
      )}

      {misEmpleados.map((e) => {
        const st = statsFor(e.nombre, e.comision);
        return (
          <Card key={e.id} className="flex items-center justify-between">
            <div>
              <p className="font-semibold text-sm">{e.nombre}</p>
              <p className="text-xs" style={{ color: MUTED }}>
                {e.puesto}{e.pin ? " · PIN protegido" : ""}{Number(e.comision) > 0 ? ` · ${e.comision}% de comisión` : ""}
              </p>
              <p className="text-xs font-mono mt-1" style={{ color: ACCENT }}>
                {st.servicios} servicios · {money(st.generado)}
                {st.propinas > 0 ? ` · ${money(st.propinas)} en propinas` : ""}
              </p>
              {st.totalCalificados > 0 && (
                <p className="text-xs font-mono mt-0.5 flex items-center gap-1" style={{ color: GOLD }}>
                  <Star size={11} fill={GOLD} strokeWidth={0} /> {st.promedioCalificacion.toFixed(1)} ({st.totalCalificados} calificaciones)
                </p>
              )}
              {Number(e.comision) > 0 && (
                <p className="text-xs font-mono mt-0.5" style={{ color: GOLD }}>
                  {money(st.comisionGanada)} en comisión acumulada
                </p>
              )}
            </div>
            <div className="flex gap-1">
              <IconBtn onClick={() => setForm(e)}><Pencil size={14} /></IconBtn>
              <IconBtn onClick={() => eliminar(e.id)} danger><Trash2 size={14} /></IconBtn>
            </div>
          </Card>
        );
      })}
    </div>
  );
}

/* ---------------- Finanzas (ingresos + gastos) ---------------- */
function Finanzas({ data, save, sucursalId }) {
  const [vista, setVista] = useState("ingresos");
  const [periodo, setPeriodo] = useState("hoy");
  const [mostrarReporte, setMostrarReporte] = useState(false);
  const hoy = todayStr();
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;

  const enRango = (f) => {
    if (periodo === "hoy") return f === hoy;
    if (periodo === "semana") {
      const d = new Date(f), now = new Date();
      const diff = (now - d) / 86400000;
      return diff >= 0 && diff < 7;
    }
    if (periodo === "mes") return f.slice(0, 7) === hoy.slice(0, 7);
    return true;
  };

  const servFiltrados = data.servicios.filter((s) => pertenece(s, sucursalId, sucursales) && enRango(s.fecha));
  const totalIngreso = servFiltrados.reduce((a, s) => a + Number(s.precio), 0);
  const gastosFiltrados = (data.gastos || []).filter((g) => pertenece(g, sucursalId, sucursales) && enRango(g.fecha));
  const totalGastos = gastosFiltrados.reduce((a, g) => a + Number(g.monto), 0);
  const neto = totalIngreso - totalGastos;

  const efectivoIngreso = servFiltrados
    .filter((s) => s.pagado && (s.metodo || "efectivo") === "efectivo")
    .reduce((a, s) => a + Number(s.precio), 0);
  const efectivoGasto = gastosFiltrados
    .filter((g) => (g.metodo || "efectivo") === "efectivo")
    .reduce((a, g) => a + Number(g.monto), 0);
  const efectivoCaja = efectivoIngreso - efectivoGasto;
  const otrosMetodos = totalIngreso - servFiltrados.filter((s) => (s.metodo || "efectivo") === "efectivo").reduce((a, s) => a + Number(s.precio), 0);

  const misEmpleados = (data.empleados || []).filter((e) => pertenece(e, sucursalId, sucursales));
  const comisionesTotal = misEmpleados.reduce((a, e) => {
    const generado = servFiltrados.filter((s) => s.empleado === e.nombre).reduce((x, s) => x + Number(s.precio), 0);
    return a + generado * ((Number(e.comision) || 0) / 100);
  }, 0);
  const utilidadReal = neto - comisionesTotal;

  const misCarteras = (data.carteras && data.carteras.length ? data.carteras : DEFAULT_CARTERAS).filter((c) => pertenece(c, sucursalId, sucursales));
  const totalApartado = misCarteras.reduce((a, c) => a + Number(c.saldo || 0), 0);
  const disponibleReal = efectivoCaja - totalApartado;

  const periodoSelector = (
    <div className="flex gap-2">
      {[["hoy", "Hoy"], ["semana", "Semana"], ["mes", "Mes"], ["todo", "Todo"]].map(([id, label]) => (
        <button
          key={id}
          onClick={() => setPeriodo(id)}
          style={{ background: periodo === id ? ACCENT : SURFACE2, color: periodo === id ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-medium"
        >
          {label}
        </button>
      ))}
    </div>
  );

  if (mostrarReporte) {
    return (
      <ReporteFinanciero
        data={data}
        periodo={periodo}
        servFiltrados={servFiltrados}
        gastosFiltrados={gastosFiltrados}
        totalIngreso={totalIngreso}
        totalGastos={totalGastos}
        neto={neto}
        sucursalId={sucursalId}
        onBack={() => setMostrarReporte(false)}
      />
    );
  }

  return (
    <div className="flex flex-col gap-3">
      {periodoSelector}

      <button
        onClick={() => setMostrarReporte(true)}
        className="w-full rounded-xl py-2.5 text-sm font-semibold flex items-center justify-center gap-1.5"
        style={{ background: SURFACE2, color: ACCENT }}
      >
        <FileText size={15} /> Ver reporte para compartir
      </button>

      <Card>
        <p className="text-xs" style={{ color: MUTED }}>Ganancia neta (ingresos − gastos)</p>
        <p className="font-mono text-2xl font-bold" style={{ color: neto >= 0 ? "#6FE0A8" : DANGER }}>
          {money(neto)}
        </p>
        <div className="flex gap-4 mt-2 text-xs">
          <p><span style={{ color: ACCENT }}>●</span> Ingresos {money(totalIngreso)}</p>
          <p><span style={{ color: DANGER }}>●</span> Gastos {money(totalGastos)}</p>
        </div>
      </Card>

      {comisionesTotal > 0 && (
        <Card style={{ borderColor: ACCENT }}>
          <p className="text-xs flex items-center gap-1.5" style={{ color: MUTED }}>
            <UserRound size={13} /> Utilidad real (después de comisiones a lavadores)
          </p>
          <p className="font-mono text-2xl font-bold mt-0.5" style={{ color: utilidadReal >= 0 ? ACCENT : DANGER }}>
            {money(utilidadReal)}
          </p>
          <p className="text-[11px] mt-1" style={{ color: MUTED }}>
            {money(neto)} de ganancia neta − {money(comisionesTotal)} en comisiones pendientes de pagar
          </p>
        </Card>
      )}

      <Card style={{ borderColor: "#2E6B4F" }}>
        <p className="text-xs flex items-center gap-1.5" style={{ color: MUTED }}>
          <Banknote size={13} /> Efectivo en caja (lo que debe haber físicamente)
        </p>
        <p className="font-mono text-2xl font-bold mt-0.5" style={{ color: "#6FE0A8" }}>{money(efectivoCaja)}</p>
        <p className="text-[11px] mt-1" style={{ color: MUTED }}>
          {money(efectivoIngreso)} cobrado en efectivo − {money(efectivoGasto)} en gastos pagados en efectivo
        </p>
        {otrosMetodos > 0 && (
          <p className="text-[11px] mt-2 pt-2" style={{ color: GOLD, borderTop: `1px solid ${SURFACE2}` }}>
            {money(otrosMetodos)} más en transferencia/tarjeta — ese dinero está en el banco, no en la caja.
          </p>
        )}
        {totalApartado > 0 && (
          periodo === "todo" ? (
            <div className="mt-2 pt-2" style={{ borderTop: `1px solid ${SURFACE2}` }}>
              <div className="flex justify-between text-[11px]">
                <span style={{ color: GOLD }}><PiggyBank size={11} className="inline mr-1" />Apartado en carteras</span>
                <span className="font-mono" style={{ color: GOLD }}>− {money(totalApartado)}</span>
              </div>
              <div className="flex justify-between text-sm font-semibold mt-1">
                <span>Disponible real</span>
                <span className="font-mono" style={{ color: disponibleReal >= 0 ? ACCENT : DANGER }}>{money(disponibleReal)}</span>
              </div>
            </div>
          ) : (
            <p className="text-[11px] mt-2 pt-2" style={{ color: GOLD, borderTop: `1px solid ${SURFACE2}` }}>
              <PiggyBank size={11} className="inline mr-1" />
              Tienes {money(totalApartado)} apartado en carteras (ve "Todo" para ver tu disponible real)
            </p>
          )
        )}
      </Card>

      <div className="flex gap-1.5 rounded-xl p-1 overflow-x-auto" style={{ background: SURFACE2 }}>
        <button
          onClick={() => setVista("ingresos")}
          style={{ background: vista === "ingresos" ? ACCENT : "transparent", color: vista === "ingresos" ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1"
        >
          <Wallet size={13} /> Ingresos
        </button>
        <button
          onClick={() => setVista("gastos")}
          style={{ background: vista === "gastos" ? ACCENT : "transparent", color: vista === "gastos" ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1"
        >
          <Receipt size={13} /> Gastos
        </button>
        <button
          onClick={() => setVista("comisiones")}
          style={{ background: vista === "comisiones" ? ACCENT : "transparent", color: vista === "comisiones" ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1"
        >
          <UserRound size={13} /> Comisiones
        </button>
        <button
          onClick={() => setVista("utilidad")}
          style={{ background: vista === "utilidad" ? ACCENT : "transparent", color: vista === "utilidad" ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1"
        >
          <Scale size={13} /> Utilidad
        </button>
        <button
          onClick={() => setVista("carteras")}
          style={{ background: vista === "carteras" ? ACCENT : "transparent", color: vista === "carteras" ? BG : TEXT }}
          className="flex-1 rounded-lg py-2 text-xs font-semibold flex items-center justify-center gap-1 shrink-0"
        >
          <PiggyBank size={13} /> Carteras
        </button>
      </div>

      {vista === "ingresos" && <VistaIngresos filtrados={servFiltrados} />}
      {vista === "gastos" && <VistaGastos data={data} save={save} filtrados={gastosFiltrados} periodo={periodo} />}
      {vista === "comisiones" && <VistaComisiones data={data} filtrados={servFiltrados} sucursalId={sucursalId} />}
      {vista === "utilidad" && (
        <VistaUtilidad
          totalIngreso={totalIngreso}
          totalGastos={totalGastos}
          gastosFiltrados={gastosFiltrados}
          comisionesTotal={comisionesTotal}
          neto={neto}
          utilidadReal={utilidadReal}
        />
      )}
      {vista === "carteras" && <VistaCarteras data={data} save={save} sucursalId={sucursalId} />}
    </div>
  );
}

function VistaComisiones({ data, filtrados, sucursalId }) {
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const misEmpleados = (data.empleados || []).filter((e) => pertenece(e, sucursalId, sucursales));
  const conComision = misEmpleados.filter((e) => Number(e.comision) > 0);
  const filas = misEmpleados.map((e) => {
    const propios = filtrados.filter((s) => s.empleado === e.nombre);
    const generado = propios.reduce((a, s) => a + Number(s.precio), 0);
    const comisionGanada = generado * ((Number(e.comision) || 0) / 100);
    return { empleado: e, servicios: propios.length, generado, comisionGanada };
  });
  const totalAPagar = filas.reduce((a, f) => a + f.comisionGanada, 0);

  return (
    <div className="flex flex-col gap-3">
      {conComision.length === 0 ? (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            Ningún empleado tiene un % de comisión configurado. Ponlo desde Equipo para ver aquí cuánto les toca pagar.
          </p>
        </Card>
      ) : (
        <>
          <Card>
            <p className="text-xs" style={{ color: MUTED }}>Total a pagar en comisiones</p>
            <p className="font-mono text-2xl font-bold" style={{ color: GOLD }}>{money(totalAPagar)}</p>
          </Card>
          {filas.filter((f) => Number(f.empleado.comision) > 0).map((f) => (
            <Card key={f.empleado.id} className="flex items-center justify-between">
              <div>
                <p className="font-semibold text-sm">{f.empleado.nombre}</p>
                <p className="text-xs" style={{ color: MUTED }}>
                  {f.servicios} servicios · {money(f.generado)} generado · {f.empleado.comision}%
                </p>
              </div>
              <p className="font-mono text-sm font-bold" style={{ color: GOLD }}>{money(f.comisionGanada)}</p>
            </Card>
          ))}
        </>
      )}
    </div>
  );
}

function VistaUtilidad({ totalIngreso, totalGastos, gastosFiltrados, comisionesTotal, neto, utilidadReal }) {
  const porCategoria = useMemo(() => {
    const g = {};
    gastosFiltrados.forEach((x) => { g[x.categoria] = (g[x.categoria] || 0) + Number(x.monto); });
    return Object.entries(g).sort((a, b) => b[1] - a[1]);
  }, [gastosFiltrados]);

  const sueldosFijos = porCategoria.find(([cat]) => cat === "Sueldos")?.[1] || 0;
  const insumos = porCategoria.find(([cat]) => cat === "Insumos y jabones")?.[1] || 0;
  const otrosGastos = totalGastos - sueldosFijos - insumos;

  const Fila = ({ label, monto, resta, destacado, color }) => (
    <div className="flex justify-between items-center py-2" style={{ borderBottom: destacado ? "none" : `1px solid ${SURFACE2}` }}>
      <span className={destacado ? "text-sm font-semibold" : "text-sm"} style={{ color: destacado ? TEXT : MUTED }}>{label}</span>
      <span className={destacado ? "font-mono text-lg font-bold" : "font-mono text-sm"} style={{ color: color || TEXT }}>
        {resta ? "− " : ""}{money(monto)}
      </span>
    </div>
  );

  return (
    <div className="flex flex-col gap-3">
      <Card>
        <p className="text-xs mb-1" style={{ color: MUTED }}>De tus ingresos a tu utilidad real, paso a paso</p>
        <div className="flex flex-col">
          <Fila label="Ingresos totales" monto={totalIngreso} color={ACCENT} />
          <Fila label="− Sueldos fijos" monto={sueldosFijos} resta color={DANGER} />
          <Fila label="− Insumos y productos" monto={insumos} resta color={DANGER} />
          <Fila label="− Otros gastos" monto={otrosGastos} resta color={DANGER} />
          <Fila label="− Comisiones a lavadores" monto={comisionesTotal} resta color={DANGER} />
          <div className="pt-2 mt-1" style={{ borderTop: `2px solid ${SURFACE2}` }}>
            <Fila label="Utilidad real" monto={utilidadReal} destacado color={utilidadReal >= 0 ? "#6FE0A8" : DANGER} />
          </div>
        </div>
      </Card>

      <Card>
        <p className="text-xs" style={{ color: MUTED }}>
          "Ganancia neta" ({money(neto)}) solo resta gastos. "Utilidad real" también descuenta lo que les debes
          a tus lavadores por comisión — así sabes lo que de verdad te queda a ti.
        </p>
      </Card>
    </div>
  );
}

/* ---------------- Carteras (dinero apartado) ---------------- */
function VistaCarteras({ data, save, sucursalId }) {
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const carteras = (data.carteras && data.carteras.length ? data.carteras : DEFAULT_CARTERAS).filter((c) => pertenece(c, sucursalId, sucursales));

  const [formNueva, setFormNueva] = useState(null); // {nombre}
  const [accion, setAccion] = useState(null); // {carteraId, tipo: 'apartar'|'usar', monto, nota, categoria}

  const totalApartado = carteras.reduce((a, c) => a + Number(c.saldo || 0), 0);

  const crearCartera = () => {
    if (!formNueva.nombre.trim()) return;
    const todas = data.carteras && data.carteras.length ? data.carteras : DEFAULT_CARTERAS;
    save({ ...data, carteras: [...todas, { id: uid(), nombre: formNueva.nombre.trim(), saldo: 0, sucursalId }] });
    setFormNueva(null);
  };

  const eliminarCartera = (id) => {
    const todas = data.carteras && data.carteras.length ? data.carteras : DEFAULT_CARTERAS;
    save({ ...data, carteras: todas.filter((c) => c.id !== id) });
  };

  const abrirApartar = (c) => setAccion({ carteraId: c.id, tipo: "apartar", monto: "", nota: "" });
  const abrirUsar = (c) => setAccion({ carteraId: c.id, tipo: "usar", monto: "", nota: "", categoria: "Insumos y jabones" });

  const confirmarAccion = () => {
    const monto = Number(accion.monto);
    if (!monto || monto <= 0) return;
    const todas = data.carteras && data.carteras.length ? data.carteras : DEFAULT_CARTERAS;
    const cartera = todas.find((c) => c.id === accion.carteraId);
    if (!cartera) return;

    if (accion.tipo === "apartar") {
      const carterasActualizadas = todas.map((c) => (c.id === cartera.id ? { ...c, saldo: Number(c.saldo || 0) + monto } : c));
      const movimiento = { id: uid(), carteraId: cartera.id, tipo: "aparte", monto, fecha: todayStr(), nota: accion.nota };
      save({ ...data, carteras: carterasActualizadas, movimientosCartera: [movimiento, ...(data.movimientosCartera || [])] });
    } else {
      const montoUsado = Math.min(monto, Number(cartera.saldo || 0));
      const carterasActualizadas = todas.map((c) => (c.id === cartera.id ? { ...c, saldo: Math.max(0, Number(c.saldo || 0) - monto) } : c));
      const nuevoGasto = {
        id: uid(),
        fecha: todayStr(),
        concepto: accion.nota.trim() || `Compra con dinero apartado: ${cartera.nombre}`,
        categoria: accion.categoria || "Insumos y jabones",
        monto: montoUsado,
        metodo: "efectivo",
        sucursalId,
      };
      const movimiento = { id: uid(), carteraId: cartera.id, tipo: "uso", monto: montoUsado, fecha: todayStr(), nota: accion.nota };
      save({
        ...data,
        carteras: carterasActualizadas,
        gastos: [nuevoGasto, ...(data.gastos || [])],
        movimientosCartera: [movimiento, ...(data.movimientosCartera || [])],
      });
    }
    setAccion(null);
  };

  return (
    <div className="flex flex-col gap-3">
      <Card>
        <p className="text-xs" style={{ color: MUTED }}>Total apartado</p>
        <p className="font-mono text-2xl font-bold" style={{ color: GOLD }}>{money(totalApartado)}</p>
        <p className="text-[11px] mt-1" style={{ color: MUTED }}>
          Este dinero sigue físicamente en tu caja, pero ya está reservado — no cuenta como disponible.
        </p>
      </Card>

      {!formNueva ? (
        <button
          onClick={() => setFormNueva({ nombre: "" })}
          style={{ background: SURFACE2, color: ACCENT }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Nueva cartera
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre de la cartera" value={formNueva.nombre} onChange={(v) => setFormNueva({ nombre: v })} placeholder="Ej. Insumos y productos" />
          <FormButtons onCancel={() => setFormNueva(null)} onSave={crearCartera} />
        </Card>
      )}

      {carteras.length === 0 && !formNueva && (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            Aún no tienes carteras. Crea una para empezar a apartar dinero, por ejemplo "Insumos y productos".
          </p>
        </Card>
      )}

      {carteras.map((c) => (
        <Card key={c.id}>
          <div className="flex items-center justify-between">
            <div>
              <p className="font-semibold text-sm flex items-center gap-1.5">
                <PiggyBank size={14} color={GOLD} /> {c.nombre}
              </p>
              <p className="font-mono text-lg font-bold mt-1" style={{ color: GOLD }}>{money(c.saldo || 0)}</p>
            </div>
            <IconBtn onClick={() => eliminarCartera(c.id)} danger><Trash2 size={14} /></IconBtn>
          </div>

          {accion?.carteraId === c.id ? (
            <div className="mt-3 pt-3 flex flex-col gap-2" style={{ borderTop: `1px solid ${SURFACE2}` }}>
              <p className="text-xs font-semibold" style={{ color: accion.tipo === "apartar" ? ACCENT : GOLD }}>
                {accion.tipo === "apartar" ? "Apartar dinero en esta cartera" : "Usar dinero de esta cartera"}
              </p>
              <Field
                label="Monto"
                type="number"
                value={accion.monto}
                onChange={(v) => setAccion({ ...accion, monto: v })}
                placeholder={accion.tipo === "usar" ? `Máximo ${money(c.saldo || 0)}` : ""}
              />
              {accion.tipo === "usar" && (
                <div>
                  <label className="text-xs" style={{ color: MUTED }}>Categoría del gasto</label>
                  <select
                    value={accion.categoria}
                    onChange={(e) => setAccion({ ...accion, categoria: e.target.value })}
                    className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
                  >
                    {CATEGORIAS_GASTO.map((cat) => <option key={cat}>{cat}</option>)}
                  </select>
                </div>
              )}
              <Field
                label={accion.tipo === "usar" ? "¿En qué lo usaste? (opcional)" : "Nota (opcional)"}
                value={accion.nota}
                onChange={(v) => setAccion({ ...accion, nota: v })}
                placeholder={accion.tipo === "usar" ? "Ej. Jabón y cera" : ""}
              />
              <FormButtons onCancel={() => setAccion(null)} onSave={confirmarAccion} />
            </div>
          ) : (
            <div className="flex gap-2 mt-3">
              <button
                onClick={() => abrirApartar(c)}
                className="flex-1 rounded-lg py-2 text-xs font-medium flex items-center justify-center gap-1"
                style={{ background: SURFACE2, color: ACCENT }}
              >
                <ArrowDownCircle size={13} /> Apartar
              </button>
              <button
                onClick={() => abrirUsar(c)}
                disabled={!c.saldo}
                className="flex-1 rounded-lg py-2 text-xs font-medium flex items-center justify-center gap-1"
                style={{ background: SURFACE2, color: c.saldo ? GOLD : MUTED, opacity: c.saldo ? 1 : 0.5 }}
              >
                <ArrowUpCircle size={13} /> Usar
              </button>
            </div>
          )}
        </Card>
      ))}
    </div>
  );
}

/* ---------------- Reporte compartible ---------------- */
const PERIODO_LABEL = { hoy: "Hoy", semana: "Últimos 7 días", mes: "Este mes", todo: "Historial completo" };

function ReporteFinanciero({ data, periodo, servFiltrados, gastosFiltrados, totalIngreso, totalGastos, neto, sucursalId, onBack }) {
  const propinas = servFiltrados.reduce((a, s) => a + Number(s.propina || 0), 0);
  const cobrado = servFiltrados.filter((s) => s.pagado).reduce((a, s) => a + Number(s.precio), 0);
  const pendiente = totalIngreso - cobrado;
  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const nombreSucursal = sucursales.find((s) => s.id === sucursalId)?.nombre;

  const efectivoIngreso = servFiltrados
    .filter((s) => s.pagado && (s.metodo || "efectivo") === "efectivo")
    .reduce((a, s) => a + Number(s.precio), 0);
  const efectivoGasto = gastosFiltrados
    .filter((g) => (g.metodo || "efectivo") === "efectivo")
    .reduce((a, g) => a + Number(g.monto), 0);
  const efectivoCaja = efectivoIngreso - efectivoGasto;
  const transferenciaTarjeta = totalIngreso - servFiltrados.filter((s) => (s.metodo || "efectivo") === "efectivo").reduce((a, s) => a + Number(s.precio), 0);

  const porTipo = useMemo(() => {
    const g = {};
    servFiltrados.forEach((s) => { g[s.tipo] = (g[s.tipo] || 0) + Number(s.precio); });
    return Object.entries(g).sort((a, b) => b[1] - a[1]);
  }, [servFiltrados]);

  const porCategoriaGasto = useMemo(() => {
    const g = {};
    gastosFiltrados.forEach((x) => { g[x.categoria] = (g[x.categoria] || 0) + Number(x.monto); });
    return Object.entries(g).sort((a, b) => b[1] - a[1]);
  }, [gastosFiltrados]);

  const comisiones = (data.empleados || [])
    .filter((e) => pertenece(e, sucursalId, sucursales) && Number(e.comision) > 0)
    .map((e) => {
      const generado = servFiltrados.filter((s) => s.empleado === e.nombre).reduce((a, s) => a + Number(s.precio), 0);
      return { nombre: e.nombre, monto: generado * (Number(e.comision) / 100) };
    })
    .filter((c) => c.monto > 0);
  const comisionesTotal = comisiones.reduce((a, c) => a + c.monto, 0);
  const utilidadReal = neto - comisionesTotal;

  const fechaHoy = new Date().toLocaleDateString("es-MX", { day: "numeric", month: "long", year: "numeric" });

  const textoWhatsapp = () => {
    let t = `📊 *Reporte ${data.nombreNegocio}*\n🗓️ ${PERIODO_LABEL[periodo]} (generado ${fechaHoy})\n\n`;
    t += `💰 Ingresos: ${money(totalIngreso)}\n`;
    t += `💸 Gastos: ${money(totalGastos)}\n`;
    t += `📈 Ganancia neta: ${money(neto)}\n`;
    if (comisionesTotal > 0) t += `📉 Utilidad real (tras comisiones): ${money(utilidadReal)}\n`;
    t += `\n💵 Efectivo en caja: ${money(efectivoCaja)}\n`;
    if (transferenciaTarjeta > 0) t += `🏦 Transferencia/tarjeta: ${money(transferenciaTarjeta)} (no está en caja)\n`;
    t += `🎁 Propinas: ${money(propinas)}\n`;
    t += `🚗 Servicios realizados: ${servFiltrados.length}\n`;
    if (pendiente > 0) t += `⏳ Por cobrar: ${money(pendiente)}\n`;
    if (porTipo.length > 0) {
      t += `\n*Por tipo de servicio:*\n`;
      porTipo.forEach(([tipo, monto]) => { t += `• ${tipo}: ${money(monto)}\n`; });
    }
    if (comisiones.length > 0) {
      t += `\n*Comisiones a pagar:*\n`;
      comisiones.forEach((c) => { t += `• ${c.nombre}: ${money(c.monto)}\n`; });
    }
    return t;
  };

  const compartirWhatsapp = () => {
    window.open(`https://wa.me/?text=${encodeURIComponent(textoWhatsapp())}`, "_blank");
  };

  return (
    <div className="flex flex-col gap-3">
      <button onClick={onBack} className="flex items-center gap-1.5 text-sm mb-1" style={{ color: MUTED }}>
        <ArrowLeft size={16} /> Regresar
      </button>

      <Card>
        <p className="font-display text-lg font-bold">{data.nombreNegocio}</p>
        <p className="text-xs" style={{ color: MUTED }}>
          {nombreSucursal ? `${nombreSucursal} · ` : ""}{PERIODO_LABEL[periodo]} · generado el {fechaHoy}
        </p>
      </Card>

      <Card>
        <p className="text-xs" style={{ color: MUTED }}>Ganancia neta</p>
        <p className="font-mono text-3xl font-bold" style={{ color: neto >= 0 ? "#6FE0A8" : DANGER }}>{money(neto)}</p>
        <div className="grid grid-cols-2 gap-2 mt-3 text-xs">
          <p><span style={{ color: ACCENT }}>●</span> Ingresos: {money(totalIngreso)}</p>
          <p><span style={{ color: DANGER }}>●</span> Gastos: {money(totalGastos)}</p>
          <p><span style={{ color: GOLD }}>●</span> Propinas: {money(propinas)}</p>
          <p><span style={{ color: MUTED }}>●</span> Servicios: {servFiltrados.length}</p>
        </div>
        {pendiente > 0 && (
          <p className="text-xs mt-2" style={{ color: GOLD }}>Aún por cobrar: {money(pendiente)}</p>
        )}
      </Card>

      {comisionesTotal > 0 && (
        <Card style={{ borderColor: ACCENT }}>
          <p className="text-xs" style={{ color: MUTED }}>Utilidad real (después de comisiones)</p>
          <p className="font-mono text-2xl font-bold" style={{ color: utilidadReal >= 0 ? ACCENT : DANGER }}>{money(utilidadReal)}</p>
          <p className="text-[11px] mt-1" style={{ color: MUTED }}>
            {money(neto)} de ganancia neta − {money(comisionesTotal)} en comisiones a lavadores
          </p>
        </Card>
      )}

      <Card style={{ borderColor: "#2E6B4F" }}>
        <p className="text-xs flex items-center gap-1.5" style={{ color: MUTED }}>
          <Banknote size={13} /> Efectivo en caja
        </p>
        <p className="font-mono text-2xl font-bold mt-0.5" style={{ color: "#6FE0A8" }}>{money(efectivoCaja)}</p>
        {transferenciaTarjeta > 0 && (
          <p className="text-[11px] mt-1.5" style={{ color: GOLD }}>
            + {money(transferenciaTarjeta)} en transferencia/tarjeta (ese dinero está en el banco, no en caja)
          </p>
        )}
      </Card>

      {porTipo.length > 0 && (
        <Card>
          <p className="text-xs mb-2" style={{ color: MUTED }}>Ingresos por tipo de servicio</p>
          <div className="flex flex-col gap-1.5">
            {porTipo.map(([tipo, monto]) => (
              <div key={tipo} className="flex justify-between text-xs">
                <span>{tipo}</span>
                <span className="font-mono">{money(monto)}</span>
              </div>
            ))}
          </div>
        </Card>
      )}

      {porCategoriaGasto.length > 0 && (
        <Card>
          <p className="text-xs mb-2" style={{ color: MUTED }}>Gastos por categoría</p>
          <div className="flex flex-col gap-1.5">
            {porCategoriaGasto.map(([cat, monto]) => (
              <div key={cat} className="flex justify-between text-xs">
                <span>{cat}</span>
                <span className="font-mono" style={{ color: DANGER }}>-{money(monto)}</span>
              </div>
            ))}
          </div>
        </Card>
      )}

      {comisiones.length > 0 && (
        <Card>
          <p className="text-xs mb-2" style={{ color: MUTED }}>Comisiones a pagar</p>
          <div className="flex flex-col gap-1.5">
            {comisiones.map((c) => (
              <div key={c.nombre} className="flex justify-between text-xs">
                <span>{c.nombre}</span>
                <span className="font-mono" style={{ color: GOLD }}>{money(c.monto)}</span>
              </div>
            ))}
          </div>
        </Card>
      )}

      <div className="flex gap-2">
        <button
          onClick={compartirWhatsapp}
          className="flex-1 rounded-xl py-2.5 text-sm font-semibold flex items-center justify-center gap-1.5"
          style={{ background: "#25D366", color: "#0B2027" }}
        >
          <Share2 size={15} /> WhatsApp
        </button>
        <button
          onClick={() => window.print()}
          className="flex-1 rounded-xl py-2.5 text-sm font-semibold flex items-center justify-center gap-1.5"
          style={{ background: SURFACE2, color: TEXT }}
        >
          <Printer size={15} /> Imprimir
        </button>
      </div>
    </div>
  );
}


function VistaIngresos({ filtrados }) {
  const total = filtrados.reduce((a, s) => a + Number(s.precio), 0);
  const cobrado = filtrados.filter((s) => s.pagado).reduce((a, s) => a + Number(s.precio), 0);
  const pendiente = total - cobrado;
  const propinas = filtrados.reduce((a, s) => a + Number(s.propina || 0), 0);

  const porTipo = useMemo(() => {
    const g = {};
    filtrados.forEach((s) => { g[s.tipo] = (g[s.tipo] || 0) + Number(s.precio); });
    return Object.entries(g).sort((a, b) => b[1] - a[1]);
  }, [filtrados]);

  const porMetodo = useMemo(() => {
    const g = {};
    filtrados.forEach((s) => { g[s.metodo || "efectivo"] = (g[s.metodo || "efectivo"] || 0) + Number(s.precio); });
    return g;
  }, [filtrados]);

  const maxTipo = Math.max(1, ...porTipo.map((t) => t[1]));

  return (
    <div className="flex flex-col gap-3">
      <Card>
        <p className="text-xs" style={{ color: MUTED }}>Ingreso total</p>
        <p className="font-mono text-2xl font-bold">{money(total)}</p>
        <div className="flex gap-4 mt-2 flex-wrap">
          <p className="text-xs"><span style={{ color: "#6FE0A8" }}>●</span> Cobrado {money(cobrado)}</p>
          <p className="text-xs"><span style={{ color: GOLD }}>●</span> Pendiente {money(pendiente)}</p>
          <p className="text-xs"><span style={{ color: ACCENT }}>●</span> Propinas {money(propinas)}</p>
        </div>
      </Card>

      <Card>
        <p className="text-xs mb-2" style={{ color: MUTED }}>Por tipo de servicio</p>
        {porTipo.length === 0 && <p className="text-sm" style={{ color: MUTED }}>Sin datos en este periodo.</p>}
        <div className="flex flex-col gap-2">
          {porTipo.map(([tipo, monto]) => (
            <div key={tipo}>
              <div className="flex justify-between text-xs mb-1">
                <span>{tipo}</span>
                <span className="font-mono">{money(monto)}</span>
              </div>
              <div className="h-1.5 rounded-full" style={{ background: SURFACE2 }}>
                <div className="h-1.5 rounded-full" style={{ width: `${(monto / maxTipo) * 100}%`, background: ACCENT }} />
              </div>
            </div>
          ))}
        </div>
      </Card>

      <Card>
        <p className="text-xs mb-2" style={{ color: MUTED }}>Por método de pago</p>
        <div className="grid grid-cols-3 gap-2">
          {METODOS_PAGO.map((m) => (
            <div key={m.id} className="flex flex-col items-center gap-1 rounded-lg py-2" style={{ background: SURFACE2 }}>
              <m.icon size={16} color={ACCENT} />
              <span className="font-mono text-xs font-semibold">{money(porMetodo[m.id] || 0)}</span>
              <span className="text-[10px]" style={{ color: MUTED }}>{m.label}</span>
            </div>
          ))}
        </div>
      </Card>
    </div>
  );
}

function VistaGastos({ data, save, filtrados, periodo, sucursalId }) {
  const [form, setForm] = useState(null);

  const startNew = () =>
    setForm({ id: null, fecha: todayStr(), concepto: "", categoria: CATEGORIAS_GASTO[0], monto: "", metodo: "efectivo" });

  const guardar = () => {
    if (!form.concepto.trim() || !form.monto) return;
    const gastos = data.gastos || [];
    let nuevos;
    if (form.id) nuevos = gastos.map((g) => (g.id === form.id ? form : g));
    else nuevos = [{ ...form, id: uid(), sucursalId }, ...gastos];
    save({ ...data, gastos: nuevos });
    setForm(null);
  };

  const eliminar = (id) => save({ ...data, gastos: (data.gastos || []).filter((g) => g.id !== id) });

  const porCategoria = useMemo(() => {
    const g = {};
    filtrados.forEach((x) => { g[x.categoria] = (g[x.categoria] || 0) + Number(x.monto); });
    return Object.entries(g).sort((a, b) => b[1] - a[1]);
  }, [filtrados]);
  const maxCat = Math.max(1, ...porCategoria.map((c) => c[1]));

  const ordenados = [...filtrados].sort((a, b) => (a.fecha < b.fecha ? 1 : -1));

  return (
    <div className="flex flex-col gap-3">
      {!form ? (
        <button
          onClick={startNew}
          style={{ background: DANGER, color: "#FCEAE3" }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Registrar gasto
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Fecha" type="date" value={form.fecha} onChange={(v) => setForm({ ...form, fecha: v })} />
          <Field label="Concepto" value={form.concepto} onChange={(v) => setForm({ ...form, concepto: v })} placeholder="Ej. Jabón y cera" />
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Categoría</label>
            <select
              value={form.categoria}
              onChange={(e) => setForm({ ...form, categoria: e.target.value })}
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            >
              {CATEGORIAS_GASTO.map((c) => <option key={c}>{c}</option>)}
            </select>
          </div>
          <Field label="Monto" type="number" value={form.monto} onChange={(v) => setForm({ ...form, monto: v })} />
          <div>
            <label className="text-xs" style={{ color: MUTED }}>¿De dónde salió el dinero?</label>
            <div className="flex gap-2 mt-1">
              {METODOS_PAGO.map((m) => (
                <button
                  key={m.id}
                  onClick={() => setForm({ ...form, metodo: m.id })}
                  style={{
                    background: (form.metodo || "efectivo") === m.id ? DANGER : SURFACE2,
                    color: (form.metodo || "efectivo") === m.id ? "#FCEAE3" : TEXT,
                  }}
                  className="flex-1 rounded-lg py-2 text-xs flex flex-col items-center gap-1"
                >
                  <m.icon size={14} /> {m.label}
                </button>
              ))}
            </div>
          </div>
          <FormButtons onCancel={() => setForm(null)} onSave={guardar} />
        </Card>
      )}

      {porCategoria.length > 0 && (
        <Card>
          <p className="text-xs mb-2" style={{ color: MUTED }}>Gastos por categoría</p>
          <div className="flex flex-col gap-2">
            {porCategoria.map(([cat, monto]) => (
              <div key={cat}>
                <div className="flex justify-between text-xs mb-1">
                  <span>{cat}</span>
                  <span className="font-mono">{money(monto)}</span>
                </div>
                <div className="h-1.5 rounded-full" style={{ background: SURFACE2 }}>
                  <div className="h-1.5 rounded-full" style={{ width: `${(monto / maxCat) * 100}%`, background: DANGER }} />
                </div>
              </div>
            ))}
          </div>
        </Card>
      )}

      {ordenados.length === 0 && !form && (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            Sin gastos registrados {periodo === "todo" ? "" : "en este periodo"}. Usa el botón de arriba para anotar el primero.
          </p>
        </Card>
      )}

      {ordenados.map((g) => (
        <Card key={g.id} className="flex items-center justify-between">
          <div>
            <p className="font-semibold text-sm">{g.concepto}</p>
            <p className="text-xs" style={{ color: MUTED }}>
              {g.categoria} · {fecha(g.fecha)} · {METODOS_PAGO.find((m) => m.id === (g.metodo || "efectivo"))?.label}
            </p>
          </div>
          <div className="flex items-center gap-2">
            <p className="font-mono text-sm font-semibold" style={{ color: DANGER }}>-{money(g.monto)}</p>
            <IconBtn onClick={() => setForm(g)}><Pencil size={13} /></IconBtn>
            <IconBtn onClick={() => eliminar(g.id)} danger><Trash2 size={13} /></IconBtn>
          </div>
        </Card>
      ))}
    </div>
  );
}

/* ---------------- Inventario ---------------- */
function Inventario({ data, save, sucursalId }) {
  const [form, setForm] = useState(null);
  const [movForm, setMovForm] = useState(null); // { productoId, tipo }

  const sucursales = data.sucursales && data.sucursales.length ? data.sucursales : DEFAULT_SUCURSALES;
  const inventario = (data.inventario || []).filter((p) => pertenece(p, sucursalId, sucursales));
  const idsPropios = new Set(inventario.map((p) => p.id));
  const movimientos = (data.movimientosInventario || []).filter((m) => idsPropios.has(m.productoId));

  const startNew = () =>
    setForm({ id: null, nombre: "", unidad: UNIDADES[0], stock: "", minimo: "", costoUnitario: "" });

  const guardarProducto = () => {
    if (!form.nombre.trim()) return;
    let nuevos;
    if (form.id) nuevos = (data.inventario || []).map((p) => (p.id === form.id ? form : p));
    else nuevos = [...(data.inventario || []), { ...form, id: uid(), stock: Number(form.stock) || 0, sucursalId }];
    save({ ...data, inventario: nuevos });
    setForm(null);
  };

  const eliminarProducto = (id) => {
    save({
      ...data,
      inventario: (data.inventario || []).filter((p) => p.id !== id),
      movimientosInventario: (data.movimientosInventario || []).filter((m) => m.productoId !== id),
    });
  };

  const abrirMovimiento = (producto, tipo) =>
    setMovForm({ productoId: producto.id, tipo, cantidad: "", costoTotal: "", nota: "", fecha: todayStr() });

  const guardarMovimiento = () => {
    const cantidad = Number(movForm.cantidad);
    if (!cantidad || cantidad <= 0) return;
    const producto = inventario.find((p) => p.id === movForm.productoId);
    if (!producto) return;

    const nuevoStock =
      movForm.tipo === "compra"
        ? Number(producto.stock) + cantidad
        : Math.max(0, Number(producto.stock) - cantidad);

    const inventarioActualizado = (data.inventario || []).map((p) =>
      p.id === producto.id ? { ...p, stock: nuevoStock } : p
    );

    const nuevoMovimiento = {
      id: uid(),
      productoId: producto.id,
      tipo: movForm.tipo,
      cantidad,
      fecha: movForm.fecha,
      nota: movForm.nota,
    };

    let gastosActualizados = data.gastos || [];
    if (movForm.tipo === "compra") {
      const costoTotal = Number(movForm.costoTotal) || cantidad * Number(producto.costoUnitario || 0);
      gastosActualizados = [
        {
          id: uid(),
          fecha: movForm.fecha,
          concepto: `Compra: ${producto.nombre} x${cantidad} ${producto.unidad}`,
          categoria: "Insumos y jabones",
          monto: costoTotal,
          sucursalId,
        },
        ...gastosActualizados,
      ];
    }

    save({
      ...data,
      inventario: inventarioActualizado,
      movimientosInventario: [nuevoMovimiento, ...(data.movimientosInventario || [])],
      gastos: gastosActualizados,
    });
    setMovForm(null);
  };

  const nombreProducto = (id) => inventario.find((p) => p.id === id)?.nombre || "Producto eliminado";
  const historial = [...movimientos].sort((a, b) => (a.fecha < b.fecha ? 1 : -1)).slice(0, 15);

  return (
    <div className="flex flex-col gap-3">
      {!form ? (
        <button
          onClick={startNew}
          style={{ background: ACCENT, color: BG }}
          className="rounded-xl py-2.5 font-semibold text-sm flex items-center justify-center gap-1.5"
        >
          <Plus size={16} /> Agregar producto
        </button>
      ) : (
        <Card className="flex flex-col gap-2">
          <Field label="Nombre" value={form.nombre} onChange={(v) => setForm({ ...form, nombre: v })} placeholder="Ej. Shampoo para autos" />
          <div>
            <label className="text-xs" style={{ color: MUTED }}>Unidad</label>
            <select
              value={form.unidad}
              onChange={(e) => setForm({ ...form, unidad: e.target.value })}
              className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
            >
              {UNIDADES.map((u) => <option key={u}>{u}</option>)}
            </select>
          </div>
          <Field label={form.id ? "Stock actual" : "Stock inicial"} type="number" value={form.stock} onChange={(v) => setForm({ ...form, stock: v })} />
          <Field label="Alertar cuando el stock sea menor o igual a" type="number" value={form.minimo} onChange={(v) => setForm({ ...form, minimo: v })} />
          <Field label="Costo por unidad" type="number" value={form.costoUnitario} onChange={(v) => setForm({ ...form, costoUnitario: v })} />
          <FormButtons onCancel={() => setForm(null)} onSave={guardarProducto} />
        </Card>
      )}

      {movForm && (
        <Card className="flex flex-col gap-2">
          <p className="text-sm font-semibold flex items-center gap-1.5">
            {movForm.tipo === "compra" ? <PackagePlus size={15} color={ACCENT} /> : <PackageMinus size={15} color={GOLD} />}
            {movForm.tipo === "compra" ? "Registrar compra" : "Registrar uso"} · {nombreProducto(movForm.productoId)}
          </p>
          <Field label="Cantidad" type="number" value={movForm.cantidad} onChange={(v) => setMovForm({ ...movForm, cantidad: v })} />
          {movForm.tipo === "compra" && (
            <Field label="Costo total (opcional)" type="number" value={movForm.costoTotal} onChange={(v) => setMovForm({ ...movForm, costoTotal: v })} placeholder="Se calcula con el costo unitario si lo dejas vacío" />
          )}
          <Field label="Fecha" type="date" value={movForm.fecha} onChange={(v) => setMovForm({ ...movForm, fecha: v })} />
          <Field label="Nota (opcional)" value={movForm.nota} onChange={(v) => setMovForm({ ...movForm, nota: v })} />
          <FormButtons onCancel={() => setMovForm(null)} onSave={guardarMovimiento} />
        </Card>
      )}

      {inventario.length === 0 && !form && (
        <Card>
          <p className="text-sm" style={{ color: MUTED }}>
            Aún no tienes productos. Agrega jabón, cera, toallas o lo que uses a diario.
          </p>
        </Card>
      )}

      {inventario.map((p) => {
        const bajo = Number(p.stock) <= Number(p.minimo);
        return (
          <Card key={p.id} style={bajo ? { borderColor: GOLD } : {}}>
            <div className="flex items-center justify-between">
              <div>
                <p className="font-semibold text-sm flex items-center gap-1.5">
                  <Package size={14} color={bajo ? GOLD : ACCENT} /> {p.nombre}
                </p>
                <p className="font-mono text-lg font-bold mt-1" style={{ color: bajo ? GOLD : TEXT }}>
                  {p.stock} <span className="text-xs font-normal" style={{ color: MUTED }}>{p.unidad}</span>
                </p>
                {p.costoUnitario ? (
                  <p className="text-xs" style={{ color: MUTED }}>{money(p.costoUnitario)} por {p.unidad.replace(/s$/, "")}</p>
                ) : null}
              </div>
              <div className="flex gap-1">
                <IconBtn onClick={() => setForm(p)}><Pencil size={14} /></IconBtn>
                <IconBtn onClick={() => eliminarProducto(p.id)} danger><Trash2 size={14} /></IconBtn>
              </div>
            </div>
            {bajo && (
              <p className="text-xs mt-1 flex items-center gap-1" style={{ color: GOLD }}>
                <AlertTriangle size={12} /> Por debajo del mínimo ({p.minimo} {p.unidad})
              </p>
            )}
            <div className="flex gap-2 mt-3">
              <button
                onClick={() => abrirMovimiento(p, "compra")}
                className="flex-1 rounded-lg py-2 text-xs font-medium flex items-center justify-center gap-1"
                style={{ background: SURFACE2, color: ACCENT }}
              >
                <PackagePlus size={13} /> Entrada
              </button>
              <button
                onClick={() => abrirMovimiento(p, "uso")}
                className="flex-1 rounded-lg py-2 text-xs font-medium flex items-center justify-center gap-1"
                style={{ background: SURFACE2, color: GOLD }}
              >
                <PackageMinus size={13} /> Salida
              </button>
            </div>
          </Card>
        );
      })}

      {historial.length > 0 && (
        <Card>
          <p className="text-xs mb-2" style={{ color: MUTED }}>Movimientos recientes</p>
          <div className="flex flex-col gap-2">
            {historial.map((m) => (
              <div key={m.id} className="flex items-center justify-between text-xs">
                <span>
                  {m.tipo === "compra" ? "+" : "−"}{m.cantidad} {nombreProducto(m.productoId)}
                  {m.nota ? ` · ${m.nota}` : ""}
                </span>
                <span style={{ color: MUTED }}>{fecha(m.fecha)}</span>
              </div>
            ))}
          </div>
        </Card>
      )}
    </div>
  );
}

/* ---------------- utilidades UI ---------------- */
function Field({ label, value, onChange, type = "text", placeholder }) {
  return (
    <div>
      <label className="text-xs" style={{ color: MUTED }}>{label}</label>
      <input
        type={type}
        value={value}
        placeholder={placeholder}
        onChange={(e) => onChange(e.target.value)}
        className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1"
      />
    </div>
  );
}

function TextArea({ label, value, onChange, placeholder }) {
  return (
    <div>
      <label className="text-xs" style={{ color: MUTED }}>{label}</label>
      <textarea
        value={value}
        placeholder={placeholder}
        onChange={(e) => onChange(e.target.value)}
        rows={2}
        className="w-full rounded-lg px-3 py-2 text-sm outline-none mt-1 resize-none"
      />
    </div>
  );
}

function FormButtons({ onCancel, onSave }) {
  return (
    <div className="flex gap-2 mt-1">
      <button onClick={onCancel} className="flex-1 rounded-lg py-2 text-sm flex items-center justify-center gap-1" style={{ background: SURFACE2, color: TEXT }}>
        <X size={14} /> Cancelar
      </button>
      <button onClick={onSave} className="flex-1 rounded-lg py-2 text-sm font-semibold flex items-center justify-center gap-1" style={{ background: ACCENT, color: BG }}>
        <Check size={14} /> Guardar
      </button>
    </div>
  );
}

function IconBtn({ children, onClick, danger }) {
  return (
    <button
      onClick={onClick}
      className="w-7 h-7 rounded-lg flex items-center justify-center"
      style={{ background: SURFACE2, color: danger ? DANGER : MUTED }}
    >
      {children}
    </button>
  );
}

function LiveTimer({ startMs }) {
  const [elapsed, setElapsed] = useState(Date.now() - startMs);
  useEffect(() => {
    const id = setInterval(() => setElapsed(Date.now() - startMs), 1000);
    return () => clearInterval(id);
  }, [startMs]);
  const totalSec = Math.max(0, Math.floor(elapsed / 1000));
  const mm = Math.floor(totalSec / 60);
  const ss = totalSec % 60;
  return (
    <span className="font-mono">
      {mm}:{ss.toString().padStart(2, "0")}
    </span>
  );
}

/* ------------------------------------------------------------------
   Punto de montaje (agregado para ejecutar la app en el navegador).
   El resto del archivo es el codigo original sin cambios.
------------------------------------------------------------------- */
import { createRoot } from "react-dom/client";
createRoot(document.getElementById("root")).render(<App />);
