// app_shell.jsx — トップレベル。ナビ + ルーティング

// iOS PWA で起動されているか
function isStandalonePWA() {
  return window.matchMedia('(display-mode: standalone)').matches ||
         window.navigator.standalone === true;
}

// iOS かどうか
function isIOS() {
  return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
}

function AppShell() {
  const t = useT();
  const [view, setView] = React.useState(() => {
    // URLパラメータ優先（PWAショートカット用）
    try {
      const params = new URLSearchParams(window.location.search);
      const urlView = params.get('view');
      if (urlView && ['inbox', 'timeline', 'ripen', 'settings'].includes(urlView)) {
        return urlView;
      }
      return localStorage.getItem('echo.view') || 'inbox';
    } catch (e) { return 'inbox'; }
  });
  const [notes, setNotes] = React.useState([]);
  const [events, setEvents] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [showInstallBanner, setShowInstallBanner] = React.useState(false);
  const [quickOpen, setQuickOpen] = React.useState(false);
  const install = (window.useInstallPrompt || (() => ({ open: () => {}, close: () => {}, node: null, available: false, installed: false, platform: 'desktop' })))();

  // Settings から install を開けるように露出（グローバル）
  React.useEffect(() => {
    window.__echoOpenInstall = install.open;
    return () => { if (window.__echoOpenInstall === install.open) delete window.__echoOpenInstall; };
  }, [install.open]);

  React.useEffect(() => {
    try { localStorage.setItem('echo.view', view); } catch (e) {}
  }, [view]);

  // 初回訪問でまだインストール未完なら、小バナーで誘導
  React.useEffect(() => {
    if (isStandalonePWA()) return;
    if (install.installed) return;
    // iOS以外 かつ beforeinstallprompt もまだ来ていなければバナー出さない
    if (!isIOS() && !install.available) return;
    let dismissed = false;
    try { dismissed = localStorage.getItem('echo.installHintDismissed') === '1'; } catch (e) {}
    if (dismissed) return;
    const timer = setTimeout(() => setShowInstallBanner(true), 2500);
    return () => clearTimeout(timer);
  }, [install.available, install.installed]);

  const reload = React.useCallback(async () => {
    const all = await DB.all();
    setNotes(all);
  }, []);

  const reloadEvents = React.useCallback(async () => {
    const all = await DB.allEvents();
    setEvents(all);
  }, []);

  React.useEffect(() => {
    (async () => {
      await ensureSeeded();
      await ensureSeededCalendar();
      await reload();
      await reloadEvents();
      setLoading(false);

      // Google Calendar: 前回同期から2時間以上経過している場合のみ背景で静かに同期
      try {
        if (typeof shouldAutoSync === 'function' && await shouldAutoSync(2 * 3600 * 1000)) {
          syncGoogleCalendars()
            .then(() => reloadEvents())
            .catch((e) => console.warn('[echo] Google sync failed:', e.message));
        }
      } catch (e) { /* noop */ }
    })();
  }, [reload, reloadEvents]);

  // 手動同期完了時にイベント再読み込み
  React.useEffect(() => {
    const handler = () => reloadEvents();
    window.addEventListener('echo:gcal-synced', handler);
    return () => window.removeEventListener('echo:gcal-synced', handler);
  }, [reloadEvents]);

  const handlePosted = React.useCallback(async () => {
    await reload();
  }, [reload]);

  const handleUpdate = async (note) => {
    await DB.put(note);
    await reload();
  };
  const handleDelete = async (id) => {
    await DB.remove(id);
    await reload();
  };
  const handleReset = async () => {
    if (!confirm('全メモを削除してシードに戻しますか？')) return;
    await resetDemo();
    await reload();
  };

  const dismissInstallBanner = () => {
    setShowInstallBanner(false);
    try { localStorage.setItem('echo.installHintDismissed', '1'); } catch (e) {}
  };
  const openInstallDetails = () => {
    setShowInstallBanner(false);
    install.open();
  };

  const navItems = [
    { k: 'inbox',    label: 'Inbox',    icon: Icons.inbox },
    { k: 'timeline', label: 'Timeline', icon: Icons.timeline },
    { k: 'ripen',    label: 'Ripen',    icon: Icons.sprout },
    { k: 'settings', label: 'Settings', icon: Icons.settings },
  ];

  const standalone = isStandalonePWA();

  return (
    <div style={{
      minHeight: '100vh',
      minHeight: '100dvh',
      background: t.bg, color: t.ink,
      fontFamily: APP_FONT,
      paddingBottom: 80,
    }}>
      {/* 上部ヘッダ (常に最前面に固定) */}
      <header style={{
        position: 'fixed',
        top: 0, left: 0, right: 0, zIndex: 30,
        background: t.bgCard + 'ee', backdropFilter: 'blur(16px)',
        WebkitBackdropFilter: 'blur(16px)',
        borderBottom: `1px solid ${t.line}`,
        paddingTop: standalone ? 'env(safe-area-inset-top)' : 0,
      }}>
        <div style={{
          maxWidth: 880, margin: '0 auto',
          padding: '14px 20px',
          display: 'flex', alignItems: 'center', gap: 20,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ color: t.primary, display: 'flex' }}>{Icons.sprout(22)}</span>
            <span style={{
              fontSize: 17, fontWeight: 800, letterSpacing: '-0.03em', color: t.ink,
            }}>Echo</span>
            <span style={{ fontSize: 10, color: t.ink4, fontWeight: 500 }}>(仮)</span>
          </div>
          <nav className="desktop-nav" style={{
            marginLeft: 12, display: 'flex', gap: 4, flex: 1,
          }}>
            {navItems.map(n => (
              <button key={n.k} onClick={() => setView(n.k)} style={{
                display: 'inline-flex', alignItems: 'center', gap: 6,
                padding: '7px 12px', borderRadius: 8, border: 'none',
                background: view === n.k ? t.bgSoft : 'transparent',
                color: view === n.k ? t.ink : t.ink3,
                fontFamily: APP_FONT, fontSize: 13, fontWeight: view === n.k ? 700 : 500,
                cursor: 'pointer', letterSpacing: '-0.01em',
                minHeight: 36,
              }}>
                {n.icon(14)} {n.label}
              </button>
            ))}
          </nav>
          {/* カウンターバッジは「完了圧」を生むため廃止。
              必要な数字はInbox/Ripenの各セクション内に自然に出す。 */}
        </div>
      </header>

      <main style={{
        maxWidth: 680, margin: '0 auto',
        // ヘッダー(fixed)の高さ分を確保
        padding: 'calc(64px + 24px) 20px 24px',
        paddingLeft: 'max(20px, env(safe-area-inset-left))',
        paddingRight: 'max(20px, env(safe-area-inset-right))',
        display: 'flex', flexDirection: 'column', gap: 24,
      }}>
        {loading ? (
          <div style={{ padding: 40, textAlign: 'center', color: t.ink4, fontSize: 13 }}>
            読み込み中…
          </div>
        ) : (
          <>
            {view === 'inbox'    && <InboxView    notes={notes} onUpdate={handleUpdate} onDelete={handleDelete} onGoRipen={() => setView('ripen')}/>}
            {view === 'timeline' && <TimelineView notes={notes} events={events} onUpdate={handleUpdate} onDelete={handleDelete}/>}
            {view === 'ripen'    && <RipenView    notes={notes} onUpdate={handleUpdate} onDelete={handleDelete}/>}
            {view === 'settings' && <SettingsView notes={notes} onReset={handleReset} onCalendarChange={reloadEvents}/>}
          </>
        )}
      </main>

      {/* 下部タブナビ (mobile) */}
      <nav className="mobile-nav" style={{
        position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: 40,
        background: t.bgCard + 'f0', backdropFilter: 'blur(16px)',
        WebkitBackdropFilter: 'blur(16px)',
        borderTop: `1px solid ${t.line}`,
        paddingBottom: 'env(safe-area-inset-bottom)',
      }}>
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)',
          maxWidth: 560, margin: '0 auto', padding: '8px 0',
        }}>
          {navItems.map(n => (
            <button key={n.k} onClick={() => setView(n.k)} style={{
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
              padding: '10px 4px', border: 'none', background: 'transparent',
              color: view === n.k ? t.primary : t.ink4, cursor: 'pointer',
              fontFamily: APP_FONT,
              minHeight: 44,
              WebkitTapHighlightColor: 'transparent',
            }}>
              {n.icon(20)}
              <span style={{
                fontSize: 10, fontWeight: view === n.k ? 700 : 500,
                letterSpacing: '-0.01em',
              }}>{n.label}</span>
            </button>
          ))}
        </div>
      </nav>

      {/* クイック投下 FAB (Settings以外で表示) */}
      <QuickFAB
        visible={view !== 'settings' && !quickOpen && !loading}
        onOpen={() => setQuickOpen(true)}
      />
      <QuickComposerOverlay
        open={quickOpen}
        onClose={() => setQuickOpen(false)}
        onPosted={handlePosted}
        pastNotes={notes}
      />

      {/* インストール誘導バナー（小） */}
      {showInstallBanner && (
        <InstallBanner
          onDetails={openInstallDetails}
          onDismiss={dismissInstallBanner}
        />
      )}
      {/* モーダル（iOS図解 or ネイティブ prompt） */}
      {install.node}

      <style>{`
        @media (max-width: 640px) {
          .desktop-nav { display: none !important; }
          .counter-bar { display: none !important; }
        }
        @media (min-width: 641px) {
          .mobile-nav { display: none !important; }
        }
      `}</style>
    </div>
  );
}

function App() {
  return (
    <ThemeProvider>
      <AppShell/>
    </ThemeProvider>
  );
}

Object.assign(window, { AppShell, App, isStandalonePWA, isIOS });
