import {
  ArrowRight,
  BookOpenCheck,
  ClipboardList,
  Columns3,
  FileCode2,
  FileSearch,
  FileText,
  FlaskConical,
  Library,
  LibraryBig,
  ListTree,
  NotebookPen,
  PenTool,
  Plus,
  Settings2,
  type LucideIcon,
} from 'lucide-react';
import { useCoreServices } from '@learnitive/context';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@learnitive/ui-components';
import React from 'react';
import { AI_SETTINGS_CLOSED_EVENT, AI_SETTINGS_SAVED_EVENT, openAiSettingsDialog } from '../ai-settings-events';
import {
  clearPendingHomeAiIntent,
  readPendingHomeAiIntent,
  requestHomeAiBuild,
  requestHomeProjectDialog,
  savePendingHomeAiIntent,
  type HomeAiOutputFormat,
  type PendingHomeAiIntent,
} from '../../saas/home-ai-build-intent';

type PromptAction = {
  id: string;
  label: string;
  prompt: string;
  Icon: LucideIcon;
};

const PROMPT_ACTIONS: readonly PromptAction[] = [
  { id: 'research-abstract', label: 'Research abstract', Icon: FileSearch, prompt: 'Draft an abstract for a research paper about renewable energy storage.' },
  { id: 'literature-review', label: 'Literature review', Icon: LibraryBig, prompt: 'Create a literature review outline for my research topic and organise the major themes, debates and research gaps.' },
  { id: 'thesis-outline', label: 'Thesis outline', Icon: ListTree, prompt: 'Create a structured thesis outline with chapters, sections and key research questions.' },
  { id: 'academic-rewrite', label: 'Academic rewrite', Icon: PenTool, prompt: 'Rewrite my text in clear, concise academic language while preserving its meaning and citations.' },
  { id: 'methodology', label: 'Methodology', Icon: FlaskConical, prompt: 'Help me structure a methodology section for this research project, including research design, data collection and analysis.' },
  { id: 'study-notes', label: 'Study notes', Icon: NotebookPen, prompt: 'Turn this material into structured study notes with key concepts, definitions and review questions.' },
  { id: 'compare-sources', label: 'Compare sources', Icon: Columns3, prompt: 'Compare these research sources by argument, methodology, evidence, findings and limitations.' },
  { id: 'research-questions', label: 'Research questions', Icon: ClipboardList, prompt: 'Develop focused research questions and possible hypotheses for my topic.' },
  { id: 'annotated-bibliography', label: 'Annotated bibliography', Icon: BookOpenCheck, prompt: 'Create an annotated bibliography structure for these sources and summarise the relevance of each one.' },
  { id: 'summarise-paper', label: 'Summarise a paper', Icon: FileText, prompt: 'Summarise this research paper and extract its research question, method, findings, limitations and conclusions.' },
  { id: 'research-table', label: 'Research table', Icon: Columns3, prompt: 'Turn these sources into a research comparison table showing author, year, method, findings and research gap.' },
  { id: 'citation-help', label: 'Citation help', Icon: Library, prompt: 'Help me integrate these sources naturally into my writing and identify where citations are required.' },
] as const;

function loginReturnPath(mode: 'build' | 'settings'): string {
  const flag = mode === 'build' ? 'homeAiBuild=1' : 'homeAiSettings=1';
  return `/?${flag}`;
}

export function HomeAiBuilder({ authenticated, authLoading, proAccess, settings }: { authenticated: boolean; authLoading: boolean; proAccess: boolean; settings?: { enabled: boolean; anonymousVisible: boolean; maxPromptLength: number; quickStarts: string[] } }) {
  const core = useCoreServices();
  const [prompt, setPrompt] = React.useState('');
  const [outputFormat, setOutputFormat] = React.useState<HomeAiOutputFormat>('markdown');
  const [starterPrompt, setStarterPrompt] = React.useState<string>();
  const [contextMenuOpen, setContextMenuOpen] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [upgradeOpen, setUpgradeOpen] = React.useState(false);
  const [aiSetupOpen, setAiSetupOpen] = React.useState(false);
  const [aiSetupReason, setAiSetupReason] = React.useState<string>();
  const textareaRef = React.useRef<HTMLTextAreaElement>(null);
  const submittingRef = React.useRef(false);
  const pendingAiResumeRef = React.useRef<PendingHomeAiIntent>();

  const selectPromptAction = React.useCallback((item: PromptAction) => {
    const canReplace = !prompt.trim() || (starterPrompt !== undefined && prompt === starterPrompt);
    if (canReplace) {
      setPrompt(item.prompt);
      setStarterPrompt(item.prompt);
    }
    window.setTimeout(() => textareaRef.current?.focus(), 0);
  }, [prompt, starterPrompt]);

  const persistAndLogin = React.useCallback((intent: PendingHomeAiIntent, mode: 'build' | 'settings') => {
    savePendingHomeAiIntent(intent);
    window.location.assign(`/login?returnTo=${encodeURIComponent(loginReturnPath(mode))}`);
  }, []);

  const finishSubmission = React.useCallback(() => {
    submittingRef.current = false;
    setSubmitting(false);
  }, []);

  const authorizeAndDispatchBuild = React.useCallback((intent: PendingHomeAiIntent) => {
    if (!proAccess) {
      pendingAiResumeRef.current = undefined;
      setUpgradeOpen(true);
      finishSubmission();
      return;
    }
    const readiness = core.projectAi.agentReadiness();
    if (!readiness.ready) {
      pendingAiResumeRef.current = intent;
      setAiSetupReason(readiness.reason);
      setAiSetupOpen(true);
      finishSubmission();
      return;
    }
    pendingAiResumeRef.current = undefined;
    requestHomeAiBuild(intent);
    window.setTimeout(finishSubmission, 350);
  }, [core.projectAi, finishSubmission, proAccess]);

  const startBuild = React.useCallback(() => {
    const text = prompt.trim();
    if (!text || submittingRef.current || authLoading) return;
    const intent: PendingHomeAiIntent = {
      action: 'build',
      prompt: text,
      outputFormat,
      requestedAt: Date.now(),
      source: 'home-ai-builder',
    };
    submittingRef.current = true;
    setSubmitting(true);
    savePendingHomeAiIntent(intent);
    if (!authenticated) {
      persistAndLogin(intent, 'build');
      return;
    }
    authorizeAndDispatchBuild(intent);
  }, [authLoading, authenticated, authorizeAndDispatchBuild, outputFormat, persistAndLogin, prompt]);

  const openSettings = React.useCallback(() => {
    const intent: PendingHomeAiIntent = {
      action: 'settings',
      prompt: prompt.trim(),
      outputFormat,
      requestedAt: Date.now(),
      source: 'home-ai-builder',
    };
    if (!authenticated) {
      persistAndLogin(intent, 'settings');
      return;
    }
    openAiSettingsDialog();
  }, [authenticated, outputFormat, persistAndLogin, prompt]);

  React.useEffect(() => {
    const handleSaved = () => {
      const pending = pendingAiResumeRef.current;
      if (!pending || !proAccess || !core.projectAi.agentReadiness().ready) return;
      pendingAiResumeRef.current = undefined;
      if (submittingRef.current) return;
      submittingRef.current = true;
      setSubmitting(true);
      requestHomeAiBuild(pending);
      window.setTimeout(finishSubmission, 350);
    };
    const handleClosed = () => {
      if (core.projectAi.agentReadiness().ready) return;
      pendingAiResumeRef.current = undefined;
      clearPendingHomeAiIntent();
      finishSubmission();
    };
    window.addEventListener(AI_SETTINGS_SAVED_EVENT, handleSaved);
    window.addEventListener(AI_SETTINGS_CLOSED_EVENT, handleClosed);
    return () => {
      window.removeEventListener(AI_SETTINGS_SAVED_EVENT, handleSaved);
      window.removeEventListener(AI_SETTINGS_CLOSED_EVENT, handleClosed);
    };
  }, [core.projectAi, finishSubmission, proAccess]);

  React.useEffect(() => {
    if (authLoading || !authenticated) return;
    const params = new URLSearchParams(window.location.search);
    const buildReturn = params.get('homeAiBuild') === '1';
    const settingsReturn = params.get('homeAiSettings') === '1';
    if (!buildReturn && !settingsReturn) return;
    const pending = readPendingHomeAiIntent();
    if (!pending) return;
    setPrompt(pending.prompt);
    setOutputFormat(pending.outputFormat ?? (pending.projectIntent === 'latex' ? 'latex' : 'markdown'));
    const url = new URL(window.location.href);
    url.searchParams.delete('homeAiBuild');
    url.searchParams.delete('homeAiSettings');
    window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}${url.hash}`);
    window.setTimeout(() => {
      if (settingsReturn || pending.action === 'settings') {
        clearPendingHomeAiIntent();
        openAiSettingsDialog();
        return;
      }
      if (submittingRef.current) return;
      submittingRef.current = true;
      setSubmitting(true);
      authorizeAndDispatchBuild(pending);
    }, 0);
  }, [authenticated, authLoading, authorizeAndDispatchBuild]);

  if (settings?.enabled === false || (!authenticated && settings?.anonymousVisible === false)) return null;

  return (
    <>
      <section className="interactive-page-container interactive-home-ai-builder" aria-labelledby="interactive-home-ai-builder-title" data-home-section="ai-writer" data-testid="home-ai-builder">
        <div className="interactive-why-heading interactive-home-ai-builder-heading">
          <span className="interactive-eyebrow">Create with AI</span>
          <h2 id="interactive-home-ai-builder-title">What will you write today?</h2>
          <p>Describe your goal, paste notes or choose a research task. Learnitive will turn it into an editable Markdown or LaTeX project.</p>
        </div>

        <div className="interactive-home-ai-composer">
          <label className="interactive-home-ai-composer-label" htmlFor="interactive-home-ai-build-prompt">Describe your project</label>
          <textarea
            ref={textareaRef}
            id="interactive-home-ai-build-prompt"
            data-testid="home-ai-build-prompt"
            className="interactive-home-ai-composer-input"
            value={prompt}
            maxLength={settings?.maxPromptLength ?? 8000}
            rows={4}
            placeholder="e.g. Compare these sources and draft a literature review on renewable energy storage…"
            onChange={(event) => {
              const value = event.currentTarget.value;
              setPrompt(value);
              if (starterPrompt !== undefined && value !== starterPrompt) setStarterPrompt(undefined);
            }}
            onKeyDown={(event) => {
              if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {
                event.preventDefault();
                startBuild();
              }
            }}
          />

          <div className="interactive-home-ai-composer-footer">
            <div className="interactive-home-ai-composer-context">
              <div className="interactive-home-ai-plus-wrap">
                <button type="button" className="interactive-home-ai-context-button" aria-label="Add writing context" aria-expanded={contextMenuOpen} onClick={() => setContextMenuOpen((value) => !value)}>
                  <Plus className="size-4" aria-hidden="true" />
                  <span>Add context</span>
                </button>
                {contextMenuOpen ? (
                  <div className="interactive-home-ai-context-menu" role="menu">
                    <a role="menuitem" href="/templates" onClick={() => setContextMenuOpen(false)}>Choose template</a>
                    <button type="button" role="menuitem" onClick={() => { setContextMenuOpen(false); requestHomeProjectDialog(); }}>Import or open project</button>
                  </div>
                ) : null}
              </div>

              <span className="interactive-home-ai-shortcut" aria-hidden="true">Ctrl/⌘ + Enter</span>
            </div>

            <div className="interactive-home-ai-composer-actions">
              <button type="button" className="interactive-home-ai-settings" aria-label="AI Settings" title="AI Settings" onClick={openSettings}>
                <Settings2 className="size-5" aria-hidden="true" />
              </button>
              <button type="button" className="interactive-button interactive-button-primary interactive-home-ai-build" disabled={!prompt.trim() || submitting || authLoading} onClick={startBuild} data-testid="home-ai-build-submit">
                {submitting ? 'Preparing…' : 'Create project'} <ArrowRight className="size-4" aria-hidden="true" />
              </button>
            </div>
          </div>
        </div>

        <div className="interactive-home-ai-prompt-actions" aria-labelledby="interactive-home-ai-prompt-actions-title">
          <div className="interactive-home-ai-section-label" id="interactive-home-ai-prompt-actions-title">Popular writing tasks</div>
          <div className="interactive-home-ai-prompt-actions-scroll">
            {PROMPT_ACTIONS.map((item) => {
              const Icon = item.Icon;
              const active = starterPrompt === item.prompt && prompt === item.prompt;
              return (
                <button key={item.id} type="button" className={`interactive-home-ai-prompt-action${active ? ' is-selected' : ''}`} aria-pressed={active} onClick={() => selectPromptAction(item)} data-testid={`home-ai-prompt-${item.id}`}>
                  <Icon className="size-4" aria-hidden="true" />
                  <span>{item.label}</span>
                </button>
              );
            })}
          </div>
        </div>

        <div className="interactive-home-ai-format" aria-labelledby="interactive-home-ai-format-title">
          <div className="interactive-home-ai-section-label" id="interactive-home-ai-format-title">Output format</div>
          <div className="interactive-home-ai-format-options" role="group" aria-label="Writing output format">
            <button type="button" className={`interactive-home-ai-format-option${outputFormat === 'markdown' ? ' is-selected' : ''}`} aria-pressed={outputFormat === 'markdown'} onClick={() => setOutputFormat('markdown')} data-testid="home-ai-format-markdown">
              <FileText className="size-4" aria-hidden="true" />
              <span>Markdown</span>
            </button>
            <button type="button" className={`interactive-home-ai-format-option${outputFormat === 'latex' ? ' is-selected' : ''}`} aria-pressed={outputFormat === 'latex'} onClick={() => setOutputFormat('latex')} data-testid="home-ai-format-latex">
              <FileCode2 className="size-4" aria-hidden="true" />
              <span>LaTeX</span>
            </button>
          </div>
          <p className="interactive-home-ai-format-help">Choose how the generated project should be authored. You can switch formats later in the editor.</p>
        </div>

      </section>
      <Dialog open={upgradeOpen} onOpenChange={setUpgradeOpen}>
        <DialogContent className="sm:max-w-md" data-testid="home-ai-pro-upgrade-dialog">
          <DialogHeader>
            <DialogTitle>AI writing requires Pro</DialogTitle>
            <DialogDescription>AI writing with BYOK or supported AI providers is not enabled for your current Free plan.</DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <button type="button" className="interactive-button interactive-button-secondary" onClick={() => setUpgradeOpen(false)}>Not now</button>
            <a className="interactive-button interactive-button-primary" href="/pricing">Buy Pro</a>
          </DialogFooter>
        </DialogContent>
      </Dialog>
      <Dialog open={aiSetupOpen} onOpenChange={(nextOpen) => {
        setAiSetupOpen(nextOpen);
        if (!nextOpen) {
          pendingAiResumeRef.current = undefined;
          clearPendingHomeAiIntent();
          finishSubmission();
        }
      }}>
        <DialogContent className="sm:max-w-md" data-testid="home-ai-setup-dialog">
          <DialogHeader>
            <DialogTitle>Set up AI to continue</DialogTitle>
            <DialogDescription>
              Learnitive needs an AI provider to create this project. Choose Local AI, Ollama or configure your BYOK provider.
              {aiSetupReason ? <span className="interactive-home-ai-setup-reason"> {aiSetupReason}</span> : null}
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <button type="button" className="interactive-button interactive-button-secondary" onClick={() => {
              pendingAiResumeRef.current = undefined;
              clearPendingHomeAiIntent();
              finishSubmission();
              setAiSetupOpen(false);
            }}>Not now</button>
            <button type="button" className="interactive-button interactive-button-primary" onClick={() => {
              setAiSetupOpen(false);
              openAiSettingsDialog();
            }}>Set up AI</button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
