import { loadDevicePrivateKey } from '@chat-app/shared/auth';
import { useEffect } from 'react';
import { Outlet } from 'react-router-dom';

import { useAuth } from '../context/AuthContext';
import { startConversationKeySync } from '../lib/conversationKeySync';
import { startDeviceApprovalListener } from '../lib/deviceApproval';
import { ensureNotificationPermission } from '../lib/osNotify';
import { devLocalSecretStore } from '../lib/secretStore';
import { BackupPromptBanner } from './BackupPromptBanner';
import { CallUI } from './CallUI';
import { DeviceApprovalBanner } from './DeviceApprovalBanner';
import { Sidebar } from './Sidebar';

export function AppShell() {
  const { session, device } = useAuth();
  useEffect(() => {
    // Prompt once per authenticated shell mount. Module-level guard prevents
    // re-asking if the user already responded this session.
    void ensureNotificationPermission();
  }, []);

  useEffect(() => {
    if (!session?.user.id || !device?.id) return;
    const userId = session.user.id;
    const deviceId = device.id;
    const stopKeySync = startConversationKeySync(userId, deviceId);
    const stopApproval = startDeviceApprovalListener({
      ownUserId: userId,
      ownDeviceId: deviceId,
      getPriv: () => loadDevicePrivateKey(devLocalSecretStore, userId, deviceId),
    });
    return () => {
      stopKeySync();
      stopApproval();
    };
  }, [session?.user.id, device?.id]);

  return (
    <div className="relative flex min-h-screen overflow-hidden bg-surface text-fg">
      <ShellBackground />
      <div className="relative z-10 flex min-h-screen w-full">
        <Sidebar />
        <main className="relative flex-1 overflow-hidden">
          <div className="h-screen overflow-y-auto">
            <Outlet />
          </div>
        </main>
      </div>
      <CallUI />
      <BackupPromptBanner />
      <DeviceApprovalBanner />
    </div>
  );
}

// Subtle desktop texture for dark mode. The panels carry the depth; the
// background stays quiet so chat content remains the focus.
function ShellBackground() {
  return (
    <div aria-hidden="true" className="pointer-events-none absolute inset-0 hidden dark:block">
      <div className="bg-grid absolute inset-0 opacity-[0.08]" />
      <div className="absolute inset-0 bg-[linear-gradient(180deg,rgba(30,31,34,0.94),rgba(17,18,20,0.98))]" />
    </div>
  );
}
