import { useEffect, useState } from 'react';
import type { BonsaiShellProps } from '../../lib/contracts';
import { normalizeThemeMode, resolveThemeMode, THEME_STORAGE_KEY, type ThemeMode } from '../theme';
import { ChatSurface } from './ChatSurface';
import { ConversationList } from './ConversationList';
import { Header, type ChatWidth } from './Header';
import { InspectorPanel } from './InspectorPanel';
import { ModelRail } from './ModelRail';
import { SettingsSheet } from './SettingsSheet';

const BROWSER_THEME_COLORS = {
  light: '#f3f6f2',
  dark: '#111511',
} as const;

export function BonsaiShell(props: BonsaiShellProps) {
  const [leftSidebarOpen, setLeftSidebarOpen] = useState(true);
  const [rightSidebarOpen, setRightSidebarOpen] = useState(true);
  const [chatWidth, setChatWidth] = useState<ChatWidth>('centered');
  const [themeMode, setThemeMode] = useState<ThemeMode>(() => {
    try {
      return normalizeThemeMode(globalThis.localStorage?.getItem(THEME_STORAGE_KEY));
    } catch {
      return 'system';
    }
  });
  const [systemDark, setSystemDark] = useState(() => globalThis.matchMedia?.('(prefers-color-scheme: dark)').matches ?? false);
  const activeModel = props.models.find((model) => model.id === props.activeModelId);
  const busy = props.streamState === 'loading' || props.streamState === 'streaming';
  const resolvedTheme = resolveThemeMode(themeMode, systemDark);

  useEffect(() => {
    const media = globalThis.matchMedia?.('(prefers-color-scheme: dark)');
    if (!media) return;
    const handleChange = (event: MediaQueryListEvent) => setSystemDark(event.matches);
    setSystemDark(media.matches);
    media.addEventListener('change', handleChange);
    return () => media.removeEventListener('change', handleChange);
  }, []);

  useEffect(() => {
    try {
      globalThis.localStorage?.setItem(THEME_STORAGE_KEY, themeMode);
    } catch {
      // Theme still works for the current tab when storage is unavailable.
    }
  }, [themeMode]);

  useEffect(() => {
    const themeColor = BROWSER_THEME_COLORS[resolvedTheme];
    const meta = document.querySelector<HTMLMetaElement>('meta[name="theme-color"]');
    const previousMetaColor = meta?.content;
    const previousRootBackground = document.documentElement.style.backgroundColor;
    const previousBodyBackground = document.body.style.backgroundColor;
    const previousColorScheme = document.documentElement.style.colorScheme;
    if (meta) meta.content = themeColor;
    document.documentElement.style.backgroundColor = themeColor;
    document.documentElement.style.colorScheme = resolvedTheme;
    document.body.style.backgroundColor = themeColor;
    return () => {
      if (meta && previousMetaColor !== undefined) meta.content = previousMetaColor;
      document.documentElement.style.backgroundColor = previousRootBackground;
      document.documentElement.style.colorScheme = previousColorScheme;
      document.body.style.backgroundColor = previousBodyBackground;
    };
  }, [resolvedTheme]);

  if (!activeModel) {
    throw new Error(`Active model ${props.activeModelId} is missing from the model catalog`);
  }

  return (
    <div className="station-frame" data-theme={resolvedTheme} data-theme-mode={themeMode}>
      <Header
        onOpenSettings={props.onOpenSettings}
        disabled={busy}
        leftSidebarOpen={leftSidebarOpen}
        rightSidebarOpen={rightSidebarOpen}
        chatWidth={chatWidth}
        onToggleLeftSidebar={() => setLeftSidebarOpen((open) => !open)}
        onToggleRightSidebar={() => setRightSidebarOpen((open) => !open)}
        onToggleChatWidth={() => setChatWidth((width) => width === 'centered' ? 'wide' : 'centered')}
      />
      <div className={`workspace-grid layout-${chatWidth}${leftSidebarOpen ? '' : ' is-models-collapsed'}${rightSidebarOpen ? '' : ' is-inspector-collapsed'}`}>
        <ModelRail
          hidden={!leftSidebarOpen}
          models={props.models}
          activeModelId={props.activeModelId}
          busy={busy}
          onModelSelect={props.onModelSelect}
        />
        {props.conversationListOpen ? <ConversationList
          conversations={props.conversations}
          activeConversationId={props.activeConversationId}
          onNewConversation={props.onNewConversation}
          onOpenConversation={props.onOpenConversation}
          onOpenConversationSettings={props.onOpenConversationSettings}
          onDeleteConversation={props.onDeleteConversation}
        /> : <ChatSurface
          activeModel={activeModel}
          loadedModelId={props.loadedModelId}
          messages={props.messages}
          streamState={props.streamState}
          modelLoadProgress={props.modelLoadProgress}
          toolsEnabled={props.toolsEnabled}
          runtimeStatus={props.runtimeStatus}
          error={props.error}
          shardRetry={props.shardRetry}
          theme={resolvedTheme}
          onLoadModel={props.onLoadModel}
          onDismissError={props.onDismissError}
          onRetryShard={props.onRetryShard}
          onSend={props.onSend}
          onRegenerate={props.onRegenerate}
          onCancel={props.onCancel}
          onToolsEnabledChange={props.onToolsEnabledChange}
          onOpenConversationList={props.onOpenConversationList}
          onOpenSettings={props.onOpenSettings}
        />}
        <InspectorPanel
          hidden={!rightSidebarOpen}
          telemetry={props.telemetry}
          toolEvents={props.toolEvents}
          artifact={props.artifact}
          onCloseArtifact={props.onCloseArtifact}
        />
      </div>
      <SettingsSheet
        open={props.settingsOpen}
        themeMode={themeMode}
        onThemeModeChange={setThemeMode}
        activeModel={activeModel}
        telemetry={props.telemetry}
        settings={props.settings}
        onSettingsChange={props.onSettingsChange}
        onPersistStorage={props.onPersistStorage}
        onClearStorage={props.onClearStorage}
        onClearConversation={props.onClearConversation}
        onClose={props.onCloseSettings}
      />
    </div>
  );
}
