import { useMemo, useState } from 'react'
import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
import DropdownSetting from '../dropdown-setting'
import type { Option } from '../dropdown-setting'
import { useTranslation } from 'react-i18next'
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
import { ProjectCompiler } from '@ol-types/project-settings'
import { useSetCompilationSettingWithEvent } from '@/features/editor-left-menu/hooks/use-set-compilation-setting'
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
import { findInTree } from '@/features/file-tree/util/find-in-tree'

// Which compiler engines make sense for a given root-file extension. CLSI
// dispatches the real engine from this extension (.qmd → Quarto, .typ → Typst,
// .tex → latexmk), so offering, say, XeLaTeX for a .qmd root is meaningless.
const ENGINES_BY_EXTENSION: Record<string, ProjectCompiler[]> = {
  tex: ['pdflatex', 'latex', 'xelatex', 'lualatex'],
  qmd: ['quarto'],
  rmd: ['quarto'],
  typ: ['typst'],
}

function getCompilerOptions(): Option<ProjectCompiler>[] {
  return [
    { value: 'quarto', label: 'Quarto' },
    { value: 'typst', label: 'Typst' },
    { value: 'pdflatex', label: 'pdfLaTeX' },
    { value: 'latex', label: 'LaTeX' },
    { value: 'xelatex', label: 'XeLaTeX' },
    { value: 'lualatex', label: 'LuaLaTeX' },
  ]
}

export default function CompilerSetting() {
  const { compiler, setCompiler, rootDocId } = useProjectSettingsContext()
  const [compilerOptions] = useState(() => getCompilerOptions())
  const { t } = useTranslation()
  const { write } = usePermissionsContext()
  const { docs, fileTreeData } = useFileTreeData()
  const changeCompiler = useSetCompilationSettingWithEvent(
    'compiler',
    setCompiler
  )

  // Disable the engines that don't apply to the current root file's extension.
  // The currently-selected engine is always left enabled so it keeps showing.
  const options = useMemo(() => {
    let rootDocName: string | undefined
    if (rootDocId) {
      const fromDocs = docs?.find(doc => doc.doc.id === rootDocId)
      if (fromDocs) {
        rootDocName = fromDocs.doc.name
      } else if (fileTreeData) {
        // Fallback: look up directly in tree in case of ID format mismatch
        const found = findInTree(fileTreeData, rootDocId)
        if (found?.type === 'doc') rootDocName = found.entity.name
      }
    }
    const extension = rootDocName?.split('.').pop()?.toLowerCase()
    const allowed = extension ? ENGINES_BY_EXTENSION[extension] : undefined

    if (!allowed) {
      return compilerOptions
    }

    return compilerOptions.map(option => ({
      ...option,
      disabled: !allowed.includes(option.value) && option.value !== compiler,
    }))
  }, [compilerOptions, docs, rootDocId, compiler])

  return (
    <DropdownSetting
      id="compiler"
      label={t('compiler')}
      description={t('the_latex_engine_used_for_compiling')}
      disabled={!write}
      options={options}
      onChange={changeCompiler}
      value={compiler}
      translateOptions="no"
    />
  )
}
