// Root app shell — sidebar, topbar with search & filters, view router
const { useState, useEffect, useRef } = React;
const NAV = [
  { key: "dashboard", label: "Dashboard", icon: "dashboard", group: "Visão" },
  { key: "hoje",      label: "Hoje",      icon: "today",     group: "Agenda" },
  { key: "semana",    label: "Semana",    icon: "week",      group: "Agenda" },
  { key: "mes",       label: "Mês",       icon: "month",     group: "Agenda" },
  { key: "agendar",   label: "Novo agendamento", icon: "plus", group: "Agenda" },
  { key: "pessoas",   label: "Pessoas",   icon: "people",    group: "CRM" },
  { key: "tarefas",   label: "Tarefas",   icon: "kanban",    group: "Execução" },
  { key: "alertas",   label: "Alertas",   icon: "bell",      group: "Execução" },
  { key: "notas",     label: "Notas",     icon: "note",      group: "Conteúdo" },
];

const VIEW_TITLES = {
  dashboard: { eyebrow: "Visão geral", title: "Dashboard", sub: "Tudo da sua operação em uma tela." },
  hoje:      { eyebrow: "Agenda",      title: "Hoje",      sub: "Atendimentos do dia em linha do tempo." },
  semana:    { eyebrow: "Agenda",      title: "Semana",    sub: "Agenda + tarefas lado a lado." },
  mes:       { eyebrow: "Agenda",      title: "Mês",       sub: "Visão de calendário. Clique num dia para abrir em foco." },
  agendar:   { eyebrow: "Cadastro",    title: "Novo agendamento", sub: "Crie um atendimento e revise antes de salvar." },
  pessoas:   { eyebrow: "CRM",         title: "Pessoas",   sub: "Contatos, tags e histórico de sessões." },
  tarefas:   { eyebrow: "Execução",    title: "Tarefas",   sub: "Kanban — arraste para mudar de coluna." },
  alertas:   { eyebrow: "Execução",    title: "Alertas",   sub: "Pendências e avisos." },
  notas:     { eyebrow: "Conteúdo",    title: "Notas",     sub: "Banco de ideias, ganchos e roteiros." },
};

function Sidebar({ view, setView, store }) {
  const grouped = NAV.reduce((acc, n) => { (acc[n.group] = acc[n.group] || []).push(n); return acc; }, {});
  const todayCount = store.data.appointments.filter(a => a.date === TODAY_ISO).length;
  const alertCount = store.data.alerts.filter(a => a.level === "alta").length;
  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-mark">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
            <rect x="3" y="5" width="18" height="16" rx="3" stroke="currentColor" strokeWidth="1.8"/>
            <path d="M3 10h18" stroke="currentColor" strokeWidth="1.8"/>
            <path d="M8 3v4M16 3v4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
            <circle cx="9" cy="15" r="1.2" fill="currentColor"/>
            <circle cx="13" cy="15" r="1.2" fill="currentColor"/>
            <circle cx="17" cy="15" r="1.2" fill="currentColor"/>
          </svg>
        </div>
        <div className="brand-text">
          <strong>Agenda</strong>
          <span>CRM de atendimentos</span>
        </div>
      </div>

      <nav className="nav">
        {Object.entries(grouped).map(([group, items]) => (
          <div key={group} className="nav-group">
            <div className="nav-group-label">{group}</div>
            {items.map(n => {
              const badge = n.key === "hoje" ? todayCount : n.key === "alertas" ? alertCount : 0;
              return (
                <button key={n.key} className={`nav-item${view === n.key ? " active" : ""}`} onClick={() => setView(n.key)}>
                  <Icon name={n.icon} />
                  <span>{n.label}</span>
                  {badge > 0 && <span className="nav-badge tabular">{badge}</span>}
                </button>
              );
            })}
          </div>
        ))}
      </nav>

      <div className="sidebar-foot">
        <StorageIndicator store={store} />
      </div>
    </aside>
  );
}

function StorageIndicator({ store }) {
  const total = store.data.appointments.length + store.data.people.length + store.data.tasks.length + store.data.notes.length;
  const lastBackup = store.data.settings?.lastBackup;
  const lastLabel = lastBackup ? new Date(lastBackup).toLocaleDateString("pt-BR", { day: "2-digit", month: "short" }) : "nunca";
  const daysSince = lastBackup ? Math.floor((Date.now() - new Date(lastBackup).getTime()) / 86400000) : null;
  const warn = daysSince === null || daysSince > 7;

  const status = store.syncStatus; // loading | online | offline | syncing
  const statusMeta = {
    loading:  { label: "Conectando...", color: "var(--c-fg-soft)" },
    online:   { label: "Online · D1",   color: "var(--c-green)" },
    offline:  { label: "Offline · cache local", color: "var(--c-amber)" },
    syncing:  { label: "Sincronizando...", color: "var(--c-accent)" },
  }[status] || { label: status, color: "var(--c-fg-soft)" };

  const syncLabel = store.lastSyncAt ? store.lastSyncAt.toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit" }) : null;

  return (
    <div className="storage-card">
      <div className="storage-head">
        <div className="storage-led" style={{ background: statusMeta.color, boxShadow: `0 0 0 3px color-mix(in oklab, ${statusMeta.color} 20%, transparent)` }} />
        <div style={{ minWidth: 0, flex: 1 }}>
          <div className="storage-title">{statusMeta.label}</div>
          <div className="storage-sub">
            {total} registros{syncLabel ? ` · sync ${syncLabel}` : ""}
          </div>
        </div>
        <button
          className="icon-btn"
          title={status === "offline" ? "Tentar reconectar" : "Sincronizar agora"}
          onClick={status === "offline" ? store.syncNow : store.pullRemote}
          style={{ width: 24, height: 24 }}
        >
          <Icon name="reset" size={13} />
        </button>
      </div>
      {warn && (
        <div className="storage-backup-warn">
          <Icon name="download" size={11} /> Backup: {lastLabel}
        </div>
      )}
    </div>
  );
}

function TopBar({ view, store, filters, setFilters, openPalette, accent, setAccent }) {
  const meta = VIEW_TITLES[view];
  const fileRef = useRef(null);
  const showFilters = ["hoje","semana","mes"].includes(view);
  const showSearch = ["hoje","semana","mes","pessoas","notas","dashboard"].includes(view);
  const theme = store.data.settings.theme;
  const toggleTheme = () => store.setTheme(theme === "dark" ? "light" : "dark");
  const [accentOpen, setAccentOpen] = useState(false);

  return (
    <header className="topbar">
      <div className="topbar-left">
        <div className="eyebrow">{meta.eyebrow}</div>
        <h1 className="page-title">{meta.title}</h1>
        <p className="page-sub">{meta.sub}</p>
      </div>
      <div className="topbar-right">
        {showSearch && (
          <button className="search search-trigger" onClick={openPalette} title="Paleta de comandos">
            <Icon name="search" />
            <span className="search-placeholder">Buscar tudo...</span>
            <kbd>⌘K</kbd>
          </button>
        )}
        {showFilters && (
          <>
            <select className="select-sm" value={filters.type} onChange={e => setFilters(f => ({ ...f, type: e.target.value }))}>
              <option value="all">Todos os tipos</option>
              {Object.keys(TYPE_META).map(t => <option key={t} value={t}>{t}</option>)}
            </select>
            <select className="select-sm" value={filters.status} onChange={e => setFilters(f => ({ ...f, status: e.target.value }))}>
              <option value="all">Todos os status</option>
              {Object.entries(STATUS_META).map(([k,v]) => <option key={k} value={k}>{v.label}</option>)}
            </select>
          </>
        )}
        <div className="topbar-actions">
          <div className="accent-wrap">
            <button className="icon-btn" title="Cor de acento" onClick={() => setAccentOpen(o => !o)}>
              <span className="accent-swatch" style={{ background: `var(--c-accent)` }} />
            </button>
            {accentOpen && (
              <div className="accent-menu" onMouseLeave={() => setAccentOpen(false)}>
                {Object.entries(ACCENTS).map(([key, a]) => (
                  <button
                    key={key}
                    className={`accent-option${accent === key ? " active" : ""}`}
                    onClick={() => { setAccent(key); setAccentOpen(false); }}
                  >
                    <span className="accent-swatch" style={{ background: a.light }} />
                    <span>{a.name}</span>
                  </button>
                ))}
              </div>
            )}
          </div>
          <button className="icon-btn" title={theme === "dark" ? "Modo claro" : "Modo escuro"} onClick={toggleTheme}>
            <Icon name={theme === "dark" ? "sun" : "moon"} />
          </button>
          <button className="icon-btn" title="Exportar JSON" onClick={store.exportJSON}><Icon name="download" /></button>
          <button className="icon-btn" title="Importar JSON" onClick={() => fileRef.current.click()}><Icon name="upload" /></button>
          <input ref={fileRef} type="file" accept="application/json" style={{ display: "none" }} onChange={e => { if (e.target.files[0]) store.importJSON(e.target.files[0]); }} />
          <button className="icon-btn" title="Restaurar exemplo" onClick={store.resetAll}><Icon name="reset" /></button>
        </div>
      </div>
    </header>
  );
}

// Mobile bottom nav
function MobileTabs({ view, setView }) {
  const tabs = [
    { key: "dashboard", icon: "dashboard", label: "Início" },
    { key: "hoje", icon: "today", label: "Hoje" },
    { key: "agendar", icon: "plus", label: "Novo" },
    { key: "pessoas", icon: "people", label: "Pessoas" },
    { key: "tarefas", icon: "kanban", label: "Tarefas" },
  ];
  return (
    <nav className="mobile-tabs">
      {tabs.map(t => (
        <button key={t.key} className={`mobile-tab${view === t.key ? " active" : ""}`} onClick={() => setView(t.key)}>
          <Icon name={t.icon} size={20} />
          <span>{t.label}</span>
        </button>
      ))}
    </nav>
  );
}

function App() {
  const store = useStore();
  const [view, setView] = useState("dashboard");
  const [filters, setFilters] = useState({ q: "", type: "all", status: "all" });
  const [openApptId, setOpenApptId] = useState(null);
  const [openPersonId, setOpenPersonId] = useState(null);
  const [paletteOpen, setPaletteOpen] = useState(false);
  const [focusDate, setFocusDate] = useState(TODAY_ISO);
  const [weekCursor, setWeekCursor] = useState(fmtISO(startOfWeek(new Date())));
  const [backupNudge, setBackupNudge] = useState(false);

  const openAppt = (a) => { setOpenPersonId(null); setOpenApptId(a.id); };
  const closeAppt = () => setOpenApptId(null);
  const openPerson = (p) => { setOpenApptId(null); setOpenPersonId(p.id); };
  const closePerson = () => setOpenPersonId(null);

  const currentAppt = store.data.appointments.find(a => a.id === openApptId) || null;
  const currentPerson = store.data.people.find(p => p.id === openPersonId) || null;

  // Apply theme + accent to root
  useEffect(() => {
    document.documentElement.dataset.theme = store.data.settings.theme;
    document.documentElement.dataset.accent = store.data.settings.accent || "indigo";
  }, [store.data.settings.theme, store.data.settings.accent]);

  // Esc and ⌘K shortcuts
  useEffect(() => {
    const onKey = (e) => {
      // ⌘K / Ctrl+K — open palette
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setPaletteOpen(true);
        return;
      }
      // ? — quick help (palette)
      if (e.key === "?" && !["INPUT","TEXTAREA","SELECT"].includes(document.activeElement?.tagName)) {
        e.preventDefault();
        setPaletteOpen(true);
        return;
      }
      // Esc — close anything
      if (e.key === "Escape") {
        if (paletteOpen) setPaletteOpen(false);
        else if (openApptId) setOpenApptId(null);
        else if (openPersonId) setOpenPersonId(null);
        else if (backupNudge) setBackupNudge(false);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [paletteOpen, openApptId, openPersonId, backupNudge]);

  // Weekly backup nudge (once on load if > 7 days)
  useEffect(() => {
    const lb = store.data.settings.lastBackup;
    const days = lb ? Math.floor((Date.now() - new Date(lb).getTime()) / 86400000) : 999;
    if (days > 7) setBackupNudge(true);
  }, []);

  // Native reminder loop — check every 30s for appointments approaching reminder window
  useEffect(() => {
    const check = () => {
      if (!("Notification" in window) || Notification.permission !== "granted") return;
      const now = new Date();
      const notified = new Set(store.data.settings.notifiedReminders || []);
      store.data.appointments.forEach(a => {
        if (notified.has(a.id)) return;
        if (a.status === "realizado" || a.status === "cancelado") return;
        if (!a.reminder || a.reminder <= 0) return;
        const dt = new Date(a.date + "T" + a.time + ":00");
        const ms = dt.getTime() - now.getTime();
        const minutesUntil = ms / 60000;
        if (minutesUntil <= a.reminder && minutesUntil > -1) {
          const person = store.data.people.find(p => p.id === a.personId);
          new Notification(`Em ${Math.max(1, Math.round(minutesUntil))} min: ${a.title}`, {
            body: `${person?.name || ""} · ${a.time} · ${a.type}`,
            tag: a.id,
          });
          store.markReminded(a.id);
        }
      });
    };
    const i = setInterval(check, 30000);
    check();
    return () => clearInterval(i);
  }, [store.data.appointments]);

  const requestNotifPerm = () => {
    if ("Notification" in window && Notification.permission === "default") {
      Notification.requestPermission();
    }
  };

  const setAccent = (key) => store.setAccent(key);

  const go = (v) => setView(v);

  return (
    <div className="app-shell">
      <Sidebar view={view} setView={setView} store={store} />
      <main className="main">
        <TopBar
          view={view} store={store} filters={filters} setFilters={setFilters}
          openPalette={() => setPaletteOpen(true)}
          accent={store.data.settings.accent}
          setAccent={setAccent}
        />
        <div className="main-scroll">
          {view === "dashboard" && <Dashboard store={store} go={go} openAppt={openAppt} />}
          {view === "hoje"      && <Today    store={store} filters={filters} openAppt={openAppt} focusDate={focusDate} setFocusDate={setFocusDate} />}
          {view === "semana"    && <Week     store={store} filters={filters} go={go} openAppt={openAppt} weekCursor={weekCursor} setWeekCursor={setWeekCursor} />}
          {view === "mes"       && <Month    store={store} filters={filters} openAppt={openAppt} go={go} setFocusDate={setFocusDate} />}
          {view === "agendar"   && <Agendar  store={store} go={go} />}
          {view === "pessoas"   && <PeopleView store={store} filters={filters} openPerson={openPerson} />}
          {view === "tarefas"   && <Tasks    store={store} />}
          {view === "alertas"   && <Alerts   store={store} />}
          {view === "notas"     && <Notes    store={store} filters={filters} />}
        </div>
      </main>

      <MobileTabs view={view} setView={setView} />

      {currentAppt && <AppointmentDrawer appt={currentAppt} store={store} onClose={closeAppt} openPerson={openPerson} />}
      {currentPerson && <PersonDrawer person={currentPerson} store={store} onClose={closePerson} openAppt={openAppt} />}

      <CommandPalette
        open={paletteOpen}
        onClose={() => setPaletteOpen(false)}
        store={store}
        go={go}
        openAppt={openAppt}
        openPerson={openPerson}
      />

      {backupNudge && (
        <div className="toast">
          <div>
            <div className="toast-title">Faça um backup do JSON</div>
            <div className="toast-sub dim small">Mais de 7 dias sem backup. Tudo está no localStorage deste navegador.</div>
          </div>
          <div style={{ display: "flex", gap: 6 }}>
            <button className="btn btn-ghost small" onClick={() => setBackupNudge(false)}>Depois</button>
            <button className="btn btn-primary small" onClick={() => { store.exportJSON(); setBackupNudge(false); }}>Baixar agora</button>
          </div>
        </div>
      )}

      {"Notification" in window && Notification.permission === "default" && (
        <button className="notif-perm" onClick={requestNotifPerm}>
          <Icon name="bell" size={13} /> Ativar lembretes no navegador
        </button>
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
