// ─────────────────────────────────────────────
// App.jsx — owns routing, layout fetch, found set
// Views: "home" | "list" | "detail"
// ─────────────────────────────────────────────

const { useState, useEffect } = React;

// ── Default theme — matches current hardcoded styles ──
const DEFAULT_THEME = {
  nav_bg:        "#0f2744",
  nav_color:     "#ffffff",
  primary:       "#2563eb",
  accent:        "#f59e0b",
  font:          "'Segoe UI', sans-serif",
  font_size:     "14",
  border_radius: "6",
  card_bg:       "#ffffff",
  page_bg:       "#f8fafc",
  logo_url:      null,
  logo_text:     "DO",
  label_size:    "10px",
  label_color:   "#64748b",
};
window.__DO_THEME__ = DEFAULT_THEME;

function App() {
  const [allObjects,   setAllObjects]   = useState([]);
  const [appSettings,  setAppSettings]  = useState({ save: "manual", timeout: 3000 });
  const [appName,      setAppName]      = useState('');
  const [appDesc,      setAppDesc]      = useState('');
  const [theme,        setTheme]        = useState(DEFAULT_THEME);
  const [layoutReady,  setLayoutReady]  = useState(false);
  const [inactive,     setInactive]     = useState(false);
  const [authReady,    setAuthReady]    = useState(false);
  const [jwt,          setJwt]          = useState(null);
  const [currentUser,  setCurrentUser]  = useState(null);
  const [error,        setError]        = useState(null);

  // View routing
  const [view,         setView]         = useState("home");
  const [currentTable, setCurrentTable] = useState(null);
  const [openId,       setOpenId]       = useState(null);

  // Found set
  const [foundSet,     setFoundSet]     = useState([]);
  const [foundTotal,   setFoundTotal]   = useState(0);
  const [totalRecords, setTotalRecords] = useState(0);

  // List view state — preserved when returning from detail
  const [listOffset,   setListOffset]   = useState(0);
  const [listPageSize, setListPageSize] = useState(25);

  // Search panel toggle — controlled by nav bar
  const [searchOpen,   setSearchOpen]   = useState(false);
  const [profileOpen,  setProfileOpen]  = useState(false);

  // Detail view state lifted for nav bar
  const [detailRecord, setDetailRecord] = useState(null);
  const [detailSaving, setDetailSaving] = useState(false);
  const [detailSaved,  setDetailSaved]  = useState(false);
  const [detailDirty,  setDetailDirty]  = useState(false);
  const [detailLoading,setDetailLoading]= useState(false);
  const [detailIsNew,  setDetailIsNew]  = useState(false);

  // Refs for nav callbacks into child components
  const detailRef = React.useRef(null);
  const listRef   = React.useRef(null);

  // ── Auth check on mount ──────────────────────
  useEffect(() => {
    const stored = localStorage.getItem(window.jwtKey());
    if (!stored) { setAuthReady(true); return; }
    fetch(`${API_BASE}/v6/auth/session`, {
      headers: { Authorization: `Bearer ${stored}` }
    })
      .then(r => r.json())
      .then(data => {
        if (data.status === 'ok') {
          setJwt(stored);
          setCurrentUser(data.user);
        } else {
          localStorage.removeItem(window.jwtKey());
        }
      })
      .catch(() => localStorage.removeItem(window.jwtKey()))
      .finally(() => setAuthReady(true));
  }, []);

  // ── Login handler ────────────────────────────
  function handleLogin(token, user) {
    localStorage.setItem(window.jwtKey(), token);
    setJwt(token);
    setCurrentUser(user);
  }

  // ── Logout handler ───────────────────────────
  function handleLogout() {
    localStorage.removeItem(window.jwtKey());
    setJwt(null);
    setCurrentUser(null);
  }

  // ── User update handler (from Profile) ───────
  async function handleUserUpdate(updatedUser) {
    setCurrentUser(updatedUser);
    try {
      const stored = localStorage.getItem(window.jwtKey());
      if (!stored) return;
      const r    = await fetch(`${API_BASE}/v6/auth/session`, {
        headers: { Authorization: `Bearer ${stored}` }
      });
      const data = await r.json();
      if (data.status === 'ok') setCurrentUser(data.user);
    } catch(e) { /* keep optimistic value */ }
  }

  // ── Fetch layout once JWT is ready ───────────
  useEffect(() => {
    if (!jwt) return;
    apiFetch(`${API_BASE}/v6/layout?app=${APP_ID}`)
      .then(r => r.json())
      .then(data => {
        if (data.status === 'inactive') { setInactive(true); setLayoutReady(true); return; }
        if (data.status !== "ok") throw new Error(data.message);
        setAllObjects(data.layout);
        // App name and desc — from top-level layout response or settings object
        if (data.app_name) setAppName(data.app_name);
        if (data.app_desc) setAppDesc(data.app_desc);
        const s = data.layout.find(o => o.group === "app" && o.type === "settings");
        if (s) {
          setAppSettings({ save: s.save || "manual", timeout: s.timeout || 3000 });
          if (s.app_name) setAppName(s.app_name);
          if (s.app_desc) setAppDesc(s.app_desc);
        }
        const t = data.layout.find(o => o.group === "app" && o.type === "theme");
        if (t) {
          const merged = { ...DEFAULT_THEME, ...t };
          setTheme(merged);
          window.__DO_THEME__ = merged;
        }
        const firstTable = data.layout.find(o => o.group === "schema" && o.type === "table" && o.status === "1");
        if (firstTable) setCurrentTable(firstTable.table);
        setLayoutReady(true);
      })
      .catch(err => setError(err.message));
  }, [jwt]);

  // ── Navigation handlers ──────────────────────
  const scrollTop = () => window.scrollTo({ top: 0, behavior: "instant" });
  const goHome   = ()      => { setView("home");   scrollTop(); };
  const goList   = (table) => { setCurrentTable(table || currentTable); setView("list");   setSearchOpen(false); scrollTop(); };
  const goDetail = (id)    => { setOpenId(id);     setView("detail"); setSearchOpen(false); scrollTop(); };

  const handleOpen = (r_auto, set, total) => {
    setFoundSet(set || []);
    setFoundTotal(total || 0);
    goDetail(r_auto);
  };

  // ── Found set change — called by both ListView and DetailView (search) ──
  const handleFoundSetChange = (set, total, pageSize, offset) => {
    setFoundSet(set);
    setFoundTotal(total);
    if (pageSize !== undefined) setListPageSize(pageSize);
    if (offset   !== undefined) setListOffset(offset);
  };

  const handleTotalRecords = (total) => setTotalRecords(total);

  // ── Nav bar callbacks — delegate to child via ref ──
  const handleNavFirst     = () => detailRef.current?.goFirst();
  const handleNavPrev      = () => detailRef.current?.goPrev()  || listRef.current?.goPrev();
  const handleNavNext      = () => detailRef.current?.goNext()  || listRef.current?.goNext();
  const handleNavLast      = () => detailRef.current?.goLast();
  const handleNavRefresh   = () => detailRef.current?.refresh() || listRef.current?.refresh();
  const handleNavNew       = () => { if (view === "list") goDetail("new"); else detailRef.current?.newRecord(); };
  const handleNavSave      = () => detailRef.current?.save();
  const handleNavDelete    = () => detailRef.current?.deleteRecord();
  const handleNavDuplicate = () => detailRef.current?.duplicate();

  // ── Nav bar position / button state ──────────
  const currentPos = view === "detail" && detailRecord && foundSet?.length > 0
    ? foundSet.indexOf(detailRecord.r_auto)
    : -1;

  const hasPrev = view === "detail"
    ? currentPos > 0
    : listOffset > 0;

  const hasNext = view === "detail"
    ? currentPos >= 0 && currentPos < foundSet.length - 1
    : (listOffset + listPageSize) < (foundTotal || totalRecords);

  // ── Early returns ────────────────────────────
  if (error) return (
    <div style={{ padding: 40, color: "#991b1b", fontFamily: "sans-serif" }}>❌ {error}</div>
  );

  if (!authReady) return (
    <div style={{ padding: 40, color: "#64748b", fontFamily: "sans-serif" }}>Loading…</div>
  );

  if (!jwt) return (
    <DOLogin
      appId={APP_ID}
      theme={theme}
      appName={window.APP_NAME || 'DataObjects'}
      onLogin={handleLogin}
    />
  );

  if (!layoutReady) return (
    <div style={{ padding: 40, color: "#64748b", fontFamily: "sans-serif" }}>Loading…</div>
  );

  if (inactive) return (
    <div style={{ minHeight:'100vh', display:'flex', flexDirection:'column',
                  alignItems:'center', justifyContent:'center',
                  background: theme.page_bg || '#f8fafc',
                  fontFamily: theme.font || "'Segoe UI', sans-serif" }}>
      <div style={{ textAlign:'center', maxWidth:400, padding:'40px 32px',
                    background:'#fff', borderRadius:16,
                    border:'1px solid #e2e8f0',
                    boxShadow:'0 4px 24px rgba(0,0,0,0.06)' }}>
        <div style={{ fontSize:48, marginBottom:20 }}>🔒</div>
        <div style={{ fontSize:20, fontWeight:700, color:'#0f1923', marginBottom:10 }}>
          App Unavailable
        </div>
        <div style={{ fontSize:14, color:'#64748b', lineHeight:1.6 }}>
          This application is currently offline for maintenance.<br />
          Please contact your administrator for assistance.
        </div>
      </div>
    </div>
  );

  const tables = allObjects.filter(o => o.group === "schema" && o.type === "table" && o.status === "1");

  return (
    <div>
      <DONavBar
        view={view}
        allObjects={allObjects}
        currentTable={currentTable}
        theme={theme}
        record={detailRecord}
        foundSet={foundSet}
        foundTotal={foundTotal}
        totalRecords={totalRecords}
        offset={listOffset}
        pageSize={listPageSize}
        saveMode={appSettings.save}
        saving={detailSaving}
        saved={detailSaved}
        dirty={detailDirty}
        loading={detailLoading}
        isNew={detailIsNew}
        hasPrev={hasPrev}
        hasNext={hasNext}
        onHome={goHome}
        onTableSelect={goList}
        onBack={() => goList()}
        onNew={handleNavNew}
        onRefresh={handleNavRefresh}
        onSearch={() => setSearchOpen(!searchOpen)}
        onSave={handleNavSave}
        onFirst={handleNavFirst}
        onPrev={handleNavPrev}
        onNext={handleNavNext}
        onLast={handleNavLast}
        onDelete={handleNavDelete}
        onDuplicate={handleNavDuplicate}
        currentUser={currentUser}
        onLogout={handleLogout}
        onUserUpdate={handleUserUpdate}
        onProfileOpen={() => setProfileOpen(true)}
      />

      <div style={{ ...SA.container, background: theme.page_bg, fontFamily: theme.font, fontSize: theme.font_size ? `${theme.font_size}px` : undefined }}>

        {/* ── HOME VIEW ── */}
        {view === "home" && (
          <div style={{ ...SA.home, background: theme.page_bg }}>
            {/* App name + desc header */}
            <div style={SA.homeTitle}>{appName || window.APP_NAME || 'My App'}</div>
            {appDesc && <div style={SA.homeDesc}>{appDesc}</div>}
            <div style={SA.tableGrid}>
              {[...tables]
                .sort((a,b) => (a.name||"").localeCompare(b.name||""))
                .map((t, i) => {
                  const icon = t.icon && t.icon.trim().length > 0 && !/[?]/.test(t.icon) ? t.icon.trim() : null;
                  const name = (t.name||"").replace(/^[^A-Za-z0-9]+/, "").trim() || t.name;
                  return (
                    <button
                      key={i}
                      style={{ ...SA.tableCard, background: theme.card_bg, borderRadius: theme.border_radius ? `${theme.border_radius}px` : '10px', fontFamily: theme.font }}
                      onClick={() => { setCurrentTable(t.table); if (t.link === 'detail') { setOpenId(null); setView('detail'); scrollTop(); } else goList(t.table); }}
                    >
                      {/* Row 1: Icon + Table Name side by side */}
                      <div style={SA.tableCardRow1}>
                        {icon && <span style={SA.tableCardIcon}>{icon}</span>}
                        <span style={SA.tableCardName}>{name}</span>
                      </div>
                      {/* Row 2: Description */}
                      {t.desc && <div style={SA.tableCardDesc}>{t.desc}</div>}
                    </button>
                  );
                })
              }
            </div>
          </div>
        )}

        {/* ── LIST VIEW ── */}
        {view === "list" && (
          <DOListView
            ref={listRef}
            allObjects={allObjects}
            table={currentTable}
            searchOpen={searchOpen}
            onSearchClose={() => setSearchOpen(false)}
            onOpen={handleOpen}
            onFoundSetChange={handleFoundSetChange}
            onTotalRecords={handleTotalRecords}
          />
        )}

        {/* ── DETAIL VIEW ── */}
        {view === "detail" && (
          <DODetailView
            ref={detailRef}
            allObjects={allObjects}
            appSettings={appSettings}
            theme={theme}
            startId={openId === "new" ? null : openId}
            isNewRecord={openId === "new"}
            table={currentTable}
            searchOpen={searchOpen}
            onSearchClose={() => setSearchOpen(false)}
            foundSet={foundSet}
            foundTotal={foundTotal}
            onFoundSetChange={handleFoundSetChange}
            onBack={() => goList()}
            onTableSelect={goList}
            onRecordChange={setDetailRecord}
            onSavingChange={setDetailSaving}
            onSavedChange={setDetailSaved}
            onDirtyChange={setDetailDirty}
            onLoadingChange={setDetailLoading}
            onNewChange={setDetailIsNew}
          />
        )}
      </div>

      {/* ── PROFILE MODAL ── */}
      {profileOpen && (
        <DOProfile
          user={currentUser}
          jwt={localStorage.getItem(window.jwtKey())}
          appId={APP_ID}
          onClose={() => setProfileOpen(false)}
          onUserUpdate={handleUserUpdate}
        />
      )}
    </div>
  );
}

// ─────────────────────────────────────────────
// STYLES
// ─────────────────────────────────────────────
const SA = {
  container:     { maxWidth: 1200, margin: "20px auto", padding: "0 20px" },
  home:          { padding: "20px 0" },
  homeTitle:     { fontSize: 26, fontWeight: 700, color: "#1a3a5c", marginBottom: 4, fontFamily: "'Segoe UI', sans-serif" },
  homeDesc:      { fontSize: 14, color: "#94a3b8", marginBottom: 20, fontFamily: "'Segoe UI', sans-serif" },
  tableGrid:     { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))", gap: 12 },
  tableCard:     { background: "#fff", border: "1px solid #e2e8f0", borderRadius: 8, padding: "16px 20px", cursor: "pointer", textAlign: "left", fontFamily: "'Segoe UI', sans-serif", boxShadow: "0 1px 3px rgba(0,0,0,0.05)", transition: "box-shadow 0.15s", display: "flex", flexDirection: "column", gap: 6 },
  tableCardRow1: { display: "flex", alignItems: "center", gap: 12 },
  tableCardIcon: { fontSize: 28, lineHeight: 1, flexShrink: 0 },
  tableCardName: { fontSize: 18, fontWeight: 700, color: "#1a3a5c" },
  tableCardDesc: { fontSize: 12, color: "#94a3b8", lineHeight: 1.5 },
};
