import { type Component, createSignal, onMount, onCleanup, createMemo, createEffect, lazy, Suspense, Show, untrack } from 'solid-js';
import { Layout } from './components/Layout';
import { EmbedLayout } from './components/EmbedLayout';
import { EmbedAuthWrapper } from './components/EmbedAuthWrapper';
import { CriticalView } from './views/CriticalView';
import { AuthCallback } from './components/Auth';
import { pb } from './lib/pocketbase';
import { initStore, setStore, store, advanceAIHelpTipSectionIndex } from './store';
import { generateAIHelpTip, hasFireworksApiKey } from './lib/ai-help';

// const CriticalView = lazy(() => import('./views/CriticalView').then(m => ({ default: m.CriticalView })));
const UrgencyView = lazy(() => import('./views/UrgencyView').then(m => ({ default: m.UrgencyView })));
const PriorityView = lazy(() => import('./views/PriorityView').then(m => ({ default: m.PriorityView })));
const MatrixView = lazy(() => import('./views/MatrixView').then(m => ({ default: m.MatrixView })));
const SettingsView = lazy(() => import('./views/SettingsView').then(m => ({ default: m.SettingsView })));
const SnowballView = lazy(() => import('./views/SnowballView').then(m => ({ default: m.SnowballView })));
const DigInView = lazy(() => import('./views/DigInView').then(m => ({ default: m.DigInView })));
const ProgressView = lazy(() => import('./views/ProgressView').then(m => ({ default: m.ProgressView })));
const HelpView = lazy(() => import('./views/HelpView').then(m => ({ default: m.HelpView })));
const AIHelpView = lazy(() => import('./views/AIHelpView').then(m => ({ default: m.AIHelpView })));
const NotepadView = lazy(() => import('./views/NotepadView').then(m => ({ default: m.NotepadView })));
const QuickEntryForm = lazy(() => import('./components/QuickEntryForm').then(m => ({ default: m.QuickEntryForm })));

const App: Component = () => {
  // Basic routing state
  const [currentView, setCurrentView] = createSignal("critical");
  const [lastNonAIView, setLastNonAIView] = createSignal("critical");
  const [isAuthenticated, setIsAuthenticated] = createSignal(pb.authStore.isValid);
  const [authUserId, setAuthUserId] = createSignal<string | null>(pb.authStore.model?.id || null);
  const [location, setLocation] = createSignal(window.location.href);
  const [isDesktop, setIsDesktop] = createSignal(window.matchMedia("(min-width: 768px)").matches);
  const [aiHelpTip, setAiHelpTip] = createSignal<string | null>(null);
  const [tipGeneratedForUserId, setTipGeneratedForUserId] = createSignal<string | null>(null);

  createEffect(() => {
    const view = currentView();
    if (view !== "help_ai") {
      setLastNonAIView(view);
    }
  });

  const effectiveView = createMemo(() =>
    currentView() === "help_ai" && isDesktop() ? lastNonAIView() : currentView()
  );

  createEffect(() => {
    const userId = authUserId();
    const authenticated = isAuthenticated();
    const desktop = isDesktop();
    const initializing = store.isInitializing;
    const hasApiKey = hasFireworksApiKey();
    const alreadyGeneratedForUser = tipGeneratedForUserId() === userId;
    const prefsLoadedForUser = !!userId && store.prefId === userId;

    if (!authenticated || !userId || !desktop || initializing || !prefsLoadedForUser || !hasApiKey || alreadyGeneratedForUser) return;

    setTipGeneratedForUserId(userId);
    const sectionIndex = untrack(() => store.aiHelpTipSectionIndex);
    void (async () => {
      try {
        const nextTip = await generateAIHelpTip(sectionIndex);
        if (!nextTip) return;
        setAiHelpTip(nextTip);
        await advanceAIHelpTipSectionIndex();
      } catch (err) {
        console.warn("Tip generation skipped", err);
      }
    })();
  });

  onMount(() => {
    const mediaQuery = window.matchMedia("(min-width: 768px)");
    const openHelpGuide = (sectionId?: string) => {
      const nextHash = sectionId ? `#help/${sectionId}` : "#help";
      if (window.location.hash !== nextHash) {
      window.location.hash = nextHash;
      }
      setStore('isNotepadMode', false);
      setCurrentView("help");
      window.dispatchEvent(new CustomEvent("taskgrid:help-target", { detail: { sectionId } }));
    };

    const openAIHelp = () => {
      setStore('isNotepadMode', false);
      setCurrentView("help_ai");
    };

    const handleMediaChange = (event: MediaQueryListEvent) => {
      setIsDesktop(event.matches);
    };

    const handleLocChange = () => {
      setLocation(window.location.href);

      const hash = window.location.hash;
      if (hash === "#help" || hash.startsWith("#help/")) {
        setCurrentView("help");
      }
    };

    (window as any).setCurrentView = setCurrentView;
    (window as any).openTasGridHelp = openHelpGuide;
    (window as any).openTasGridAIHelp = openAIHelp;

    window.addEventListener('popstate', handleLocChange);
    window.addEventListener('hashchange', handleLocChange);
    mediaQuery.addEventListener('change', handleMediaChange);

    let isFirstRun = true;
    const removeListener = pb.authStore.onChange((token) => {
      const wasAuthenticated = isAuthenticated();
      const previousUserId = authUserId();
      const nextUserId = token ? (pb.authStore.model?.id || null) : null;
      setIsAuthenticated(!!token);
      setAuthUserId(nextUserId);

      if (!token || nextUserId !== previousUserId) {
        setTipGeneratedForUserId(null);
        setAiHelpTip(null);
      }

      if (token && (isFirstRun || !wasAuthenticated)) {
        initStore();
      }
      isFirstRun = false;
    }, true);

    onCleanup(() => {
      removeListener();
      delete (window as any).setCurrentView;
      delete (window as any).openTasGridHelp;
      delete (window as any).openTasGridAIHelp;
      window.removeEventListener('popstate', handleLocChange);
      window.removeEventListener('hashchange', handleLocChange);
      mediaQuery.removeEventListener('change', handleMediaChange);
    });

    // Background preload of other views when idle
    const idleCallback = (window as any).requestIdleCallback || ((cb: any) => setTimeout(cb, 1000));
    idleCallback(() => {
      // CriticalView is now static
      import('./views/UrgencyView');
      import('./views/PriorityView');
      import('./views/MatrixView');
      import('./views/SettingsView');
      import('./views/SnowballView');
      import('./views/DigInView');
      import('./views/ProgressView');
      import('./views/HelpView');
      import('./views/AIHelpView');

      // Remove splash screen after high priority work is done
      const splash = document.getElementById('splash');
      if (splash) {
        splash.style.opacity = '0';
        setTimeout(() => splash.remove(), 500);
      }
    });

    handleLocChange();
  });

  // Determine if we are in an embed route (check both path and hash for compatibility)
  const isEmbed = () => {
    const loc = location(); // Reactive dependency
    const url = new URL(loc);
    const path = url.pathname;
    const hash = url.hash;
    return path.startsWith('/embed/') || hash.startsWith('#/embed/');
  };

  const getEmbedView = () => {
    const loc = location(); // Reactive dependency
    const url = new URL(loc);
    const fullPath = url.pathname + url.hash;
    let view = null;
    if (fullPath.includes('/notes')) view = 'embed_notes';
    else if (fullPath.includes('/quick-add')) view = 'embed_quick_add';
    return view;
  };

    return (
        <Show
            when={isEmbed()}
            fallback={
                <Show when={isAuthenticated()} fallback={<AuthCallback onSuccess={() => { }} />}>
                    <Layout
                        currentView={effectiveView()}
                        setView={setCurrentView}
                        isAIHelpOpen={currentView() === "help_ai" && isDesktop()}
                        onToggleAIHelp={() => setCurrentView(currentView() === "help_ai" ? lastNonAIView() : "help_ai")}
                        aiHelpTip={aiHelpTip()}
                        hideQuickEntry={currentView() === "help_ai" && !isDesktop()}
                    >
                        <Suspense fallback={<div class="flex items-center justify-center h-full"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div></div>}>
                            <Show when={effectiveView() === "critical"}><CriticalView /></Show>
                            <Show when={effectiveView() === "urgency"}><UrgencyView /></Show>
                            <Show when={effectiveView() === "priority"}><PriorityView /></Show>
                            <Show when={effectiveView() === "matrix"}><MatrixView /></Show>
                            <Show when={effectiveView() === "snowball"}><SnowballView /></Show>
                            <Show when={effectiveView() === "dig_in"}><DigInView /></Show>
                            <Show when={effectiveView() === "progress"}><ProgressView /></Show>
                            <Show when={effectiveView() === "settings"}><SettingsView setView={setCurrentView} /></Show>
                            <Show when={effectiveView() === "help_ai"}><AIHelpView /></Show>
                            <Show when={effectiveView() === "help"}><HelpView onBack={() => setCurrentView("settings")} /></Show>
                        </Suspense>
                    </Layout>
                </Show>
            }
        >
            {(() => {
                const isPublicNote = () => {
                    const view = getEmbedView();
                    const urlObj = new URL(location());
                    const noteId = new URLSearchParams(urlObj.search).get('noteId') || 
                                 (urlObj.hash.includes('?') ? new URLSearchParams(urlObj.hash.substring(urlObj.hash.indexOf('?'))).get('noteId') : null);
                    return view === 'embed_notes' && !!noteId;
                };

                return (
                    <EmbedAuthWrapper skipAuth={isPublicNote()}>
                        <EmbedLayout>
                            <Suspense fallback={<div class="flex items-center justify-center h-full"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div></div>}>
                                <Show when={getEmbedView() === 'embed_notes'}>
                                    {(() => {
                                        const noteIdFromUrl = createMemo(() => {
                                            const urlObj = new URL(location());
                                            let noteId = new URLSearchParams(urlObj.search).get('noteId');
                                            if (!noteId && urlObj.hash.includes('?')) {
                                                const hashQueryString = urlObj.hash.substring(urlObj.hash.indexOf('?'));
                                                noteId = new URLSearchParams(hashQueryString).get('noteId');
                                            }
                                            return noteId;
                                        });
                                        return <NotepadView selectedNoteId={noteIdFromUrl()} setSelectedNoteId={() => { }} hideNavigation={!!noteIdFromUrl()} />;
                                    })()}
                                </Show>
                                <Show when={getEmbedView() === 'embed_quick_add'}>
                                    <QuickEntryForm autoFocus={true} />
                                </Show>
                            </Suspense>
                        </EmbedLayout>
                    </EmbedAuthWrapper>
                );
            })()}
        </Show>
  );
};

export default App;
