import { useEffect, useState } from 'react'
import { ExportDialog } from './components/Export/ExportDialog'
import type { ExportOptions } from './components/Export/ExportDialog'
import { FileTree } from './components/FileTree/FileTree'
import { currentEditorView } from './components/Editor/MarkdownEditor'
import { MarkdownEditor } from './components/Editor/MarkdownEditor'
import { DocumentOutline } from './components/Editor/DocumentOutline'
import { ChatPanel } from './components/AIChat/ChatPanel'
import { AnalysisToolbar } from './components/Toolbar/AnalysisToolbar'
import { RevisionPanel } from './components/Revisions/RevisionPanel'
import { ProjectSearchModal } from './components/Search/ProjectSearchModal'
import { SettingsDialog } from './components/Settings/SettingsDialog'
import { HomeScreen } from './components/Home/HomeScreen'
import { SubmissionsScreen } from './components/Submissions/SubmissionsScreen'
import { useEditorStore } from './store/editorStore'
import './styles/app.css'

export default function App(): JSX.Element {
  const {
    setFileTree, activeFilePath, isDirty, markSaved, activeFileContent, theme, toggleTheme,
    loadSession, revisionPanelOpen, toggleRevisionPanel, fontSize, setFontSize,
    openProjectSearch, clearActiveFile, initPrefs, focusMode, toggleFocusMode,
    showHome, goHome, setActiveFile, showSubmissions, goSubmissions
  } = useEditorStore()

  const handleOpenStoryBible = async (): Promise<void> => {
    try {
      const { path, content } = await window.api.openStoryBible()
      setActiveFile(path, content)
      if (path === activeFilePath) {
        const view = currentEditorView
        if (view) {
          view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: content } })
          markSaved()
        }
      }
    } catch (err) {
      console.error('[App] openStoryBible failed:', err)
    }
  }

  const handleOpenPublisherPack = async (): Promise<void> => {
    try {
      const { path, content } = await window.api.openPublisherPack()
      setActiveFile(path, content)
    } catch (err) {
      console.error('[App] openPublisherPack failed:', err)
    }
  }
  const [sidebarOpen, setSidebarOpen] = useState(
    () => localStorage.getItem('sidebarOpen') !== 'false'
  )
  const [chatOpen, setChatOpen] = useState(
    () => localStorage.getItem('chatOpen') !== 'false'
  )
  const [settingsOpen, setSettingsOpen] = useState(false)
  const [exportOpen, setExportOpen] = useState(false)
  const [isFirstRun, setIsFirstRun] = useState(false)
  const [focusPeek, setFocusPeek] = useState(false)
  const [projectTitle, setProjectTitle] = useState('')

  useEffect(() => {
    if (!focusMode) {
      setFocusPeek(false)
      return
    }
    const onMove = (e: MouseEvent): void => setFocusPeek(e.clientY < 85)
    window.addEventListener('mousemove', onMove)
    return () => window.removeEventListener('mousemove', onMove)
  }, [focusMode])

  const switchProject = async (newPath: string): Promise<void> => {
    await window.api.writeConfig({ projectPath: newPath })
    setProjectTitle(newPath.split('/').filter(Boolean).pop() ?? '')
    clearActiveFile()
    const files = await window.api.listFiles()
    setFileTree(files)
    await loadSession()
  }

  // Load file tree, restore prefs + session, and detect first run.
  // Draft-directory calls are sequenced so macOS only prompts for folder access once.
  useEffect(() => {
    async function init(): Promise<void> {
      initPrefs()
      const files = await window.api.listFiles()
      setFileTree(files)
      await loadSession()
      const cfg = await window.api.readConfig()
      if (!cfg.apiKey || !cfg.projectPath) {
        setIsFirstRun(true)
        setSettingsOpen(true)
      }
      if (cfg.projectPath) {
        setProjectTitle(cfg.projectPath.split('/').filter(Boolean).pop() ?? '')
      }
    }
    init()
  }, [])

  // Handle menu actions sent from the main process
  useEffect(() => {
    return window.api.onMenuAction(async (action) => {
      if (action === 'save') {
        if (activeFilePath && isDirty) {
          await window.api.writeFile(activeFilePath, activeFileContent)
          await window.api.saveRevision(activeFilePath, activeFileContent)
          markSaved()
        }
      } else if (action === 'toggleSidebar') {
        setSidebarOpen((v) => { const n = !v; localStorage.setItem('sidebarOpen', String(n)); return n })
      } else if (action === 'toggleChat') {
        setChatOpen((v) => { const n = !v; localStorage.setItem('chatOpen', String(n)); return n })
      } else if (action === 'toggleRevisions') {
        toggleRevisionPanel()
      } else if (action === 'toggleTheme') {
        toggleTheme()
      } else if (action === 'fontIncrease') {
        setFontSize(fontSize + 1)
      } else if (action === 'fontDecrease') {
        setFontSize(fontSize - 1)
      } else if (action === 'fontReset') {
        setFontSize(15)
      } else if (action === 'projectSearch') {
        openProjectSearch()
      } else if (action === 'openSettings') {
        setSettingsOpen(true)
      } else if (action === 'toggleFocusMode') {
        toggleFocusMode()
      } else if (action === 'openProject') {
        const picked = await window.api.pickProjectFolder()
        if (picked) await switchProject(picked)
      } else if (action.startsWith('openRecent:')) {
        await switchProject(action.slice('openRecent:'.length))
      } else if (action === 'exportPDF') {
        if (activeFilePath && activeFileContent) {
          const fileName = activeFilePath.split('/').pop()?.replace(/\.md$/, '') ?? 'document'
          await window.api.exportPDF(activeFileContent, fileName)
        }
      } else if (action === 'exportProjectPDF') {
        setExportOpen(true)
      }
    })
  }, [activeFilePath, isDirty, activeFileContent, fontSize])

  // Handle Cmd+S / Ctrl+S and Cmd+Shift+F / Ctrl+Shift+F
  useEffect(() => {
    const handler = async (e: KeyboardEvent): Promise<void> => {
      if ((e.metaKey || e.ctrlKey) && e.key === 's') {
        e.preventDefault()
        if (activeFilePath && isDirty) {
          await window.api.writeFile(activeFilePath, activeFileContent)
          await window.api.saveRevision(activeFilePath, activeFileContent)
          markSaved()
        }
      } else if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === 'f') {
        e.preventDefault()
        openProjectSearch()
      } else if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === 'g') {
        e.preventDefault()
        toggleFocusMode()
      } else if (e.key === 'Escape' && focusMode) {
        toggleFocusMode()
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [activeFilePath, isDirty, activeFileContent, focusMode])

  return (
    <div
      className="app-layout"
      data-sidebar={sidebarOpen ? 'open' : 'closed'}
      data-chat={chatOpen ? 'open' : 'closed'}
      data-focus={focusMode ? 'on' : 'off'}
      data-peek={focusPeek ? 'on' : 'off'}
    >
      <div className="app-titlebar">
        <span className="app-titlebar-title">{projectTitle || 'Hohoff Editor'}</span>
        <div className="app-titlebar-right">
          <div className="app-layout-toggle">
            <button
              className={`app-layout-toggle-seg${sidebarOpen ? ' active' : ''}`}
              onClick={() => setSidebarOpen((v) => { const next = !v; localStorage.setItem('sidebarOpen', String(next)); return next })}
              title={sidebarOpen ? 'Hide file tree' : 'Show file tree'}
              disabled={focusMode}
            />
            <div className="app-layout-toggle-seg app-layout-toggle-seg--mid" />
            <button
              className={`app-layout-toggle-seg${chatOpen ? ' active' : ''}`}
              onClick={() => setChatOpen((v) => { const next = !v; localStorage.setItem('chatOpen', String(next)); return next })}
              title={chatOpen ? 'Hide AI chat' : 'Show AI chat'}
              disabled={focusMode}
            />
          </div>
          <div className="app-titlebar-icon-group">
            <button
              className={`app-titlebar-theme-btn${focusMode ? ' active' : ''}`}
              onClick={toggleFocusMode}
              title="Focus mode (⌘⇧G)"
            >⊡</button>
            <button
              className="app-titlebar-theme-btn"
              onClick={toggleTheme}
              title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
            >
              {theme === 'dark' ? '☀' : '☾'}
            </button>
          </div>
        </div>
      </div>
      <aside className="sidebar">
        <div className="sidebar-nav">
          <button
            className={`sidebar-nav-btn${showHome ? ' active' : ''}`}
            onClick={goHome}
            title="Home"
          >
            <span className="sidebar-nav-icon">⌂</span>
          </button>
          <button
            className="sidebar-nav-btn"
            onClick={handleOpenStoryBible}
            title="Story Bible"
          >
            <span className="sidebar-nav-icon">📖</span>
          </button>
          <button
            className="sidebar-nav-btn"
            onClick={handleOpenPublisherPack}
            title="Publisher Pack"
          >
            <span className="sidebar-nav-label">Pack</span>
          </button>
          <button
            className={`sidebar-nav-btn${showSubmissions ? ' active' : ''}`}
            onClick={goSubmissions}
            title="Submissions"
          >
            <span className="sidebar-nav-label">Sub</span>
          </button>
        </div>
        <FileTree />
      </aside>
      <main className="editor-area" style={{ position: 'relative' }}>
        {showHome ? (
          <HomeScreen />
        ) : showSubmissions ? (
          <SubmissionsScreen />
        ) : (
          <>
            <AnalysisToolbar />
            <div className="editor-body">
              <div className="page-backdrop" />
              <DocumentOutline />
              <MarkdownEditor />
            </div>
            {revisionPanelOpen && <RevisionPanel />}
          </>
        )}
      </main>
      <aside className="chat-area">
        <ChatPanel />
      </aside>

      <ProjectSearchModal />
      {settingsOpen && (
        <SettingsDialog
          onClose={() => { setSettingsOpen(false); setIsFirstRun(false) }}
          isSetup={isFirstRun}
          onProjectChanged={async () => {
            clearActiveFile()
            const files = await window.api.listFiles()
            setFileTree(files)
            await loadSession()
          }}
        />
      )}
      {exportOpen && (
        <ExportDialog
          onClose={() => setExportOpen(false)}
          onExport={async (opts: ExportOptions) => {
            setExportOpen(false)
            await window.api.exportProjectPDF(opts)
          }}
        />
      )}
    </div>
  )
}
