/* === Main app shell === */

const DEFAULT_TWEAKS = /*EDITMODE-BEGIN*/{
  "density": "comoda"
}/*EDITMODE-END*/;

/* Pequeña "campanita" sintetizada (sin archivos). Se llama al detectar
   que la cantidad de tareas aumentó (alguien creó una tarea). */
function playDing() {
  try {
    const AC = window.AudioContext || window.webkitAudioContext;
    if (!AC) return;
    const ctx = new AC();
    const o = ctx.createOscillator();
    const g = ctx.createGain();
    o.type = "sine";
    o.frequency.setValueAtTime(880, ctx.currentTime);
    o.frequency.exponentialRampToValueAtTime(1320, ctx.currentTime + 0.12);
    g.gain.setValueAtTime(0.0001, ctx.currentTime);
    g.gain.exponentialRampToValueAtTime(0.22, ctx.currentTime + 0.02);
    g.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + 0.45);
    o.connect(g); g.connect(ctx.destination);
    o.start();
    o.stop(ctx.currentTime + 0.5);
    o.onended = () => { try { ctx.close(); } catch (e) {} };
  } catch (e) { /* ignorar */ }
}

const ROLE_TO_USER_ID = {
  admin:   "mgonzalez",     // Controller
  gerente: "apina",          // Manager
  jefe:    "rpina",          // Chef (Cocina)
  staff:   "bgarcia",        // Helper de cocina
  compras: "hrogelio",       // Encargado de compras (también Ayudante Mant)
};

const App = ({ authUserId, onLogout }) => {
  const [tasks, setTasks] = React.useState([]); // se llena desde Convex
  const [compras, setComprasState] = React.useState({ bar: [], cocina: [], amallaves: [], yate: [] }); // se llena desde Convex
  const comprasRef = React.useRef(compras);
  React.useEffect(() => { comprasRef.current = compras; }, [compras]);
  const [userId, setUserId] = React.useState(authUserId); // usuario autenticado (no hay impersonación)
  const [areaId, setAreaId] = React.useState("centro");
  const [selectedId, setSelectedId] = React.useState(null);
  const [formOpen, setFormOpen] = React.useState(false);
  const [formArea, setFormArea] = React.useState(null);
  const [editTaskRef, setEditTaskRef] = React.useState(null);
  const [device, setDevice] = React.useState("desktop"); // "desktop" | "mobile"
  const [toast, setToast] = React.useState(null);

  // === Convex: cargar tareas en vivo y sembrar datos iniciales si está vacío ===
  React.useEffect(() => {
    let unsub = null;
    const connect = () => {
      const c = window.convexClient, api = window.convexApi;
      if (!c || !api) return false;
      c.mutation(api.tasks.seedIfEmpty, { tasks: TASKS_INIT })
        .catch(err => console.error("Convex seed tareas:", err));
      unsub = c.onUpdate(
        api.tasks.list, {},
        (rows) => setTasks(rows),
        (err) => console.error("Convex tareas (suscripción):", err)
      );
      return true;
    };
    if (!connect()) {
      const onReady = () => { window.removeEventListener("convex-ready", onReady); connect(); };
      window.addEventListener("convex-ready", onReady);
      return () => window.removeEventListener("convex-ready", onReady);
    }
    return () => { if (unsub) unsub(); };
  }, []);

  // Detecta cuando se agrega una tarea (cantidad aumenta) y suena la campanita.
  // No suena en la carga inicial (cuando pasa de 0 a N).
  const tasksCountRef = React.useRef(0);
  React.useEffect(() => {
    if (tasks.length > tasksCountRef.current && tasksCountRef.current > 0) {
      playDing();
    }
    tasksCountRef.current = tasks.length;
  }, [tasks.length]);

  // Guardar / borrar una tarea en Convex.
  const saveTask = (task) =>
    window.convexClient &&
    window.convexClient.mutation(window.convexApi.tasks.save, { task })
      .catch(err => console.error("Convex guardar tarea:", err));
  const removeTask = (id) =>
    window.convexClient &&
    window.convexClient.mutation(window.convexApi.tasks.remove, { id })
      .catch(err => console.error("Convex borrar tarea:", err));

  // === Convex: compras en vivo + siembra inicial ===
  const COMPRAS_LISTS_KEYS = ["bar", "cocina", "amallaves", "yate"];
  React.useEffect(() => {
    let unsub = null;
    const reshape = (rows) => {
      const out = { bar: [], cocina: [], amallaves: [], yate: [] };
      rows.forEach(r => { (out[r.list] = out[r.list] || []).push(r); });
      Object.keys(out).forEach(k => out[k].sort((a, b) => (b._creationTime || 0) - (a._creationTime || 0)));
      return out;
    };
    const connect = () => {
      const c = window.convexClient, api = window.convexApi;
      if (!c || !api) return false;
      const flat = [];
      COMPRAS_LISTS_KEYS.forEach(list => (COMPRAS_INIT[list] || []).forEach(it => flat.push({ ...it, list })));
      c.mutation(api.compras.seedIfEmpty, { items: flat })
        .catch(err => console.error("Convex seed compras:", err));
      unsub = c.onUpdate(
        api.compras.list, {},
        (rows) => setComprasState(reshape(rows)),
        (err) => console.error("Convex compras (suscripción):", err)
      );
      return true;
    };
    if (!connect()) {
      const onReady = () => { window.removeEventListener("convex-ready", onReady); connect(); };
      window.addEventListener("convex-ready", onReady);
      return () => window.removeEventListener("convex-ready", onReady);
    }
    return () => { if (unsub) unsub(); };
  }, []);

  // setCompras compatible con los componentes: reconcilia el objeto nuevo contra
  // el actual y envía las mutaciones correspondientes a Convex.
  const COMPRAS_CMP = ["id", "name", "qty", "unit", "status", "priority", "supplier", "note", "addedBy", "addedOn", "photo"];
  const comparableItem = (it) => { const o = {}; COMPRAS_CMP.forEach(k => { o[k] = it[k]; }); return JSON.stringify(o); };
  const setCompras = (updater) => {
    const c = window.convexClient, api = window.convexApi;
    if (!c || !api) return;
    const prev = comprasRef.current || {};
    const next = typeof updater === "function" ? updater(prev) : updater;
    Object.keys(next).forEach(list => {
      const prevItems = prev[list] || [];
      const nextItems = next[list] || [];
      const prevById = new Map(prevItems.map(i => [i.id, i]));
      const nextIds = new Set(nextItems.map(i => i.id));
      nextItems.forEach(it => {
        const before = prevById.get(it.id);
        if (!before || comparableItem(before) !== comparableItem(it)) {
          c.mutation(api.compras.save, { item: { ...it, list } })
            .catch(err => console.error("Convex guardar compra:", err));
        }
      });
      prevItems.forEach(it => {
        if (!nextIds.has(it.id)) {
          c.mutation(api.compras.remove, { id: it.id })
            .catch(err => console.error("Convex borrar compra:", err));
        }
      });
    });
  };

  // Tweaks
  const tweaks = useTweaks ? useTweaks(DEFAULT_TWEAKS) : [DEFAULT_TWEAKS, () => {}];
  const t = tweaks[0]; const setTweak = tweaks[1];

  // Apply density to root
  React.useEffect(() => {
    document.documentElement.setAttribute("data-density", t.density === "compacta" ? "compact" : "comfortable");
  }, [t.density]);

  // Derive role + user from selected userId
  const user = STAFF_BY_ID[userId] || STAFF_BY_ID.mgonzalez;
  const role = user.role;
  const perms = PERMISSIONS[role];

  React.useEffect(() => {
    const allowed = SIDEBAR_BY_ROLE(role, user);
    if (!allowed.includes(areaId)) {
      setAreaId(allowed[0] || "centro");
    }
    if (role === "staff") setDevice("mobile");
    else setDevice("desktop");
  }, [userId]);

  const selected = tasks.find(t => t.id === selectedId);
  const canEditSelected = selected ? perms.canEditTask(selected, user) : false;
  const canDeleteSelected = selected ? perms.canDelete(selected, user) : false;
  const canEditFn = (task) => perms.canEditTask(task, user);

  const visibleTasks = React.useMemo(() => {
    if (role === "admin" || role === "gerente") return tasks;
    const extras = (user.extraAreas || []).map(e => e.area);
    if (role === "jefe") {
      return tasks.filter(t => t.area === user.area || t.assignee === user.id || extras.includes(t.area));
    }
    if (role === "compras") {
      // Compras + áreas secundarias (Héctor también ve Mantenimiento)
      return tasks.filter(t => t.area === "compras" || extras.includes(t.area));
    }
    if (role === "staff") {
      // Helper/Maid/Ayudante ve toda su área + áreas extra
      return tasks.filter(t => t.area === user.area || extras.includes(t.area));
    }
    return tasks;
  }, [tasks, role, user]);

  const handleUpdate = (next) => {
    saveTask({ ...next, lastModifiedBy: user.id, lastModifiedAt: TODAY_ISO });
  };

  const handleDelete = (id) => {
    removeTask(id);
    if (selectedId === id) setSelectedId(null);
  };

  const handleToggle = (id) => {
    const t = tasks.find(x => x.id === id);
    if (!t) return;
    if (!perms.canEditTask(t, user)) return;
    const done = t.status === "terminada";
    let next;
    if (!done) {
      // If recurring, schedule next occurrence
      if (t.recurrence && t.recurrence !== "ninguna") {
        const nextDue = nextOccurrence(t.due, t.recurrence);
        next = { ...t, status: "pendiente", due: nextDue, checklist: (t.checklist || []).map(c => ({ ...c, done: false })) };
      } else {
        next = { ...t, status: "terminada", completedBy: user.id, completedAt: TODAY_ISO };
      }
    } else {
      next = { ...t, status: "pendiente" };
    }
    next.lastModifiedBy = user.id;
    next.lastModifiedAt = TODAY_ISO;
    saveTask(next);
  };

  const handleOpenForm = (a) => {
    if (!perms.canCreateTask("any", user)) return;
    // Default to the area passed in; if none, use the currently open area context;
    // fall back to user's area; otherwise let the form pick.
    const target = a || (areaId !== "centro" ? areaId : null) || user.area || null;
    setFormArea(target);
    setEditTaskRef(null);
    setFormOpen(true);
  };

  const handleEditTask = (task) => {
    if (!perms.canEditTask(task, user)) return;
    setEditTaskRef(task);
    setFormArea(null);
    setFormOpen(true);
  };

  const handleSave = (taskData) => {
    // save crea o actualiza por id en Convex; la suscripción refresca la lista.
    saveTask({ ...taskData, lastModifiedBy: user.id, lastModifiedAt: TODAY_ISO });
    setSelectedId(taskData.id);
    setFormOpen(false);
    setEditTaskRef(null);
  };

  const handleAddToCompras = (list, item) => {
    setCompras(c => ({
      ...c,
      [list]: [
        { id: "c-" + Date.now(), name: item.name, qty: item.qty || 1, unit: item.unit || "pza",
          status: "pendiente", priority: "media", supplier: "", note: "Agregado automáticamente desde inventario",
          addedBy: user.id, addedOn: TODAY_ISO },
        ...c[list],
      ],
    }));
    setToast(`“${item.name}” agregado a Compras · ${list === "bar" ? "Bar" : list === "cocina" ? "Cocina" : "Ama de llaves"}`);
    setTimeout(() => setToast(null), 3000);
  };

  const currentArea = AREA_BY_ID[areaId];
  const title = currentArea?.label || "Centro de mando";

  /* === Render mobile preview === */
  if (device === "mobile") {
    return (
      <div className="cdc-mobile-wrap">
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: 380, marginBottom: 14 }}>
          <div style={{ fontFamily: "var(--cdc-display)", fontSize: 22, fontWeight: 500, color: "var(--cdc-ink)" }}>
            Casa de Casas · Staff
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="cdc-btn" onClick={() => setDevice("desktop")}>
              Vista escritorio
            </button>
            <button className="cdc-btn" onClick={onLogout}>Salir</button>
          </div>
        </div>
        <div className="cdc-phone">
          <MobileApp tasks={visibleTasks} user={user} role={role} onUpdate={handleUpdate} onCreate={handleOpenForm} compras={compras} setCompras={setCompras} />
        </div>
        <div style={{ marginTop: 14, fontSize: 12.5, color: "var(--cdc-ink-3)", textAlign: "center", maxWidth: 420 }}>
          Vista móvil de <strong>{user.name}</strong> ({user.title}) · ve las tareas de su área y puede modificar el estado
        </div>
        {tweaks[0] && (
          <DeskMobileTweaks tweak={t} setTweak={setTweak} device={device} setDevice={setDevice} />
        )}
        <TaskForm
          open={formOpen}
          onClose={() => { setFormOpen(false); setEditTaskRef(null); }}
          onSave={handleSave}
          areaDefault={formArea}
          editTask={editTaskRef}
          role={role}
          user={user}
        />
      </div>
    );
  }

  /* === Desktop === */
  const panelOpen = !!selected;

  return (
    <>
      <div className="cdc-app">
        <Sidebar
          currentArea={areaId}
          setArea={(id) => { setAreaId(id); setSelectedId(null); }}
          role={role}
          user={user}
          onOpenAddArea={() => handleOpenForm()}
        />
        <main className="cdc-main">
          <Topbar
            title={title}
            userId={userId}
            user={user}
            role={role}
            onLogout={onLogout}
            dateIso={TODAY_ISO}
            device={device}
            setDevice={setDevice}
            tasks={visibleTasks}
            onSelectTask={setSelectedId}
          />
          <div className="cdc-content" data-panel-open={panelOpen}>
            <div className="cdc-scroll">
              {areaId === "centro" && (
                <CentroDeMando
                  tasks={visibleTasks}
                  onSelect={setSelectedId}
                  selectedId={selectedId}
                  onToggle={handleToggle}
                  canEditFn={canEditFn}
                />
              )}
              {areaId === "cocina" && (
                <CocinaView
                  tasks={visibleTasks}
                  onSelect={setSelectedId}
                  selectedId={selectedId}
                  onToggle={handleToggle}
                  canEditFn={canEditFn}
                  role={role}
                  user={user}
                  compras={compras}
                  setCompras={setCompras}
                />
              )}
              {areaId === "bar" && (
                <BarView
                  tasks={visibleTasks}
                  onSelect={setSelectedId}
                  selectedId={selectedId}
                  onToggle={handleToggle}
                  canEditFn={canEditFn}
                  role={role}
                  user={user}
                  compras={compras}
                  setCompras={setCompras}
                />
              )}
              {areaId === "amallaves" && (
                <AmaLlavesView
                  tasks={visibleTasks}
                  onSelect={setSelectedId}
                  selectedId={selectedId}
                  onToggle={handleToggle}
                  canEditFn={canEditFn}
                  role={role}
                  user={user}
                  compras={compras}
                  setCompras={setCompras}
                  onCreate={handleOpenForm}
                />
              )}
              {areaId === "yate" && (
                <YateView
                  tasks={visibleTasks}
                  onSelect={setSelectedId}
                  selectedId={selectedId}
                  onToggle={handleToggle}
                  canEditFn={canEditFn}
                  role={role}
                  user={user}
                  compras={compras}
                  setCompras={setCompras}
                  onCreate={handleOpenForm}
                />
              )}
              {areaId === "compras" && (
                <ComprasView
                  compras={compras}
                  setCompras={setCompras}
                  role={role}
                  user={user}
                />
              )}
              {areaId === "mant" && (
                <MantView
                  tasks={visibleTasks}
                  onSelect={setSelectedId}
                  selectedId={selectedId}
                  onToggle={handleToggle}
                  canEditFn={canEditFn}
                  onCreate={handleOpenForm}
                  role={role}
                  user={user}
                />
              )}
              {areaId === "huespedes" && (
                <HuespedesView role={role} user={user} />
              )}
              {areaId === "usuarios" && (
                <UsuariosView user={user} role={role} />
              )}
              {areaId !== "centro" && areaId !== "cocina" && areaId !== "bar" && areaId !== "amallaves" && areaId !== "yate" && areaId !== "mant" && areaId !== "huespedes" && areaId !== "compras" && areaId !== "usuarios" && (
                <AreaView
                  areaId={areaId}
                  tasks={visibleTasks}
                  onSelect={setSelectedId}
                  selectedId={selectedId}
                  onToggle={handleToggle}
                  canEditFn={canEditFn}
                  onCreate={handleOpenForm}
                  role={role}
                />
              )}
            </div>
            {panelOpen && (
              <TaskPanel
                task={selected}
                onClose={() => setSelectedId(null)}
                onUpdate={handleUpdate}
                onDelete={handleDelete}
                onEdit={handleEditTask}
                canEdit={canEditSelected}
                canDelete={canDeleteSelected}
                role={role}
              />
            )}
          </div>
        </main>
      </div>

      <TaskForm
        open={formOpen}
        onClose={() => { setFormOpen(false); setEditTaskRef(null); }}
        onSave={handleSave}
        areaDefault={formArea}
        editTask={editTaskRef}
        role={role}
        user={user}
      />

      {toast && (
        <div style={{
          position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)",
          background: "var(--cdc-ink)", color: "white", padding: "10px 18px", borderRadius: 999,
          boxShadow: "var(--cdc-shadow-lg)", fontSize: 13.5, fontWeight: 500, zIndex: 200,
          display: "flex", alignItems: "center", gap: 8,
        }}>
          <I.Check size={14} stroke={2.4} style={{ color: "var(--cdc-coral)" }} />
          {toast}
        </div>
      )}

      <DeskMobileTweaks tweak={t} setTweak={setTweak} device={device} setDevice={setDevice} />
    </>
  );
};

/* === Tweaks panel === */

const DeskMobileTweaks = ({ tweak, setTweak, device, setDevice }) => {
  if (!window.TweaksPanel) return null;
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Densidad" />
      <TweakRadio
        label="Filas"
        value={tweak.density}
        options={["comoda", "compacta"]}
        onChange={(v) => setTweak("density", v)}
      />
      <TweakSection label="Vista" />
      <TweakRadio
        label="Dispositivo"
        value={device}
        options={["desktop", "mobile"]}
        onChange={(v) => setDevice(v)}
      />
    </TweaksPanel>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<AuthGate App={App} />);
