import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import * as eventTracking from '../../../../infrastructure/event-tracking'
import { useProjectContext } from '@/shared/context/project-context'
import { postJSON } from '@/infrastructure/fetch-json'
import type { ProjectCompiler } from '@ol-types/project-settings'

import {
  DropdownDivider,
  DropdownItem,
} from '@/shared/components/dropdown/dropdown-menu'
import { useFileTreeActionable } from '../../contexts/file-tree-actionable'
import { useFileTreeSelectable } from '../../contexts/file-tree-selectable'
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
import { useFileTreeMainContext } from '../../contexts/file-tree-main'
import { findInTree } from '../../util/find-in-tree'
import useConvertDoc from '@/features/ide-react/hooks/use-convert-doc'
import getMeta from '@/utils/meta'
import { isValidTeXFile } from '@/main/is-valid-tex-file'

const COMPILER_BY_EXT: Record<string, ProjectCompiler> = {
  tex: 'pdflatex',
  rtex: 'pdflatex',
  ltx: 'pdflatex',
  rnw: 'pdflatex',
  typ: 'typst',
  qmd: 'quarto',
  rmd: 'quarto',
}

function FileTreeItemMenuItems() {
  const { t } = useTranslation()

  const {
    canRename,
    canDelete,
    canCreate,
    startRenaming,
    startDeleting,
    startCreatingFolder,
    startCreatingDocOrFile,
    startUploadingDocOrFile,
    downloadPath,
    selectedFileName,
  } = useFileTreeActionable()

  const { project, projectId, updateProject } = useProjectContext()
  const projectOwner = project?.owner?._id
  const rootDocId = project?.rootDocId

  const { fileTreeData, fileTreeReadOnly } = useFileTreeData()
  const { selectedEntityIds } = useFileTreeSelectable()
  const { contextMenuEntityId } = useFileTreeMainContext()
  const selectedEntityId =
    selectedEntityIds.size === 1 ? Array.from(selectedEntityIds)[0] : null

  // Use context-menu-target entity for convert/set-as-main; falls back to selection
  const convertEntityId = contextMenuEntityId ?? selectedEntityId
  const convertEntity = convertEntityId
    ? findInTree(fileTreeData, convertEntityId)
    : null
  const isConvertableDoc = convertEntity?.type === 'doc'
  const convertEntityName = convertEntity?.entity.name ?? null

  const enablePandocConversions =
    getMeta('ol-ExposedSettings')?.enablePandocConversions

  const canConvertToTypst =
    enablePandocConversions &&
    !fileTreeReadOnly &&
    isConvertableDoc &&
    convertEntityName?.endsWith('.tex')
  const canConvertToLatex =
    enablePandocConversions &&
    !fileTreeReadOnly &&
    isConvertableDoc &&
    convertEntityName?.endsWith('.typ')

  const canShowSetAsMain =
    !fileTreeReadOnly &&
    isConvertableDoc &&
    !!convertEntityId &&
    convertEntityId !== rootDocId &&
    !!convertEntityName &&
    isValidTeXFile(convertEntityName)

  const handleSetAsMain = useCallback(async () => {
    if (!convertEntityId || !convertEntityName) return
    const ext = convertEntityName.split('.').pop()?.toLowerCase() ?? ''
    const newCompiler = COMPILER_BY_EXT[ext]
    const body: Record<string, string> = { rootDocId: convertEntityId }
    if (newCompiler && newCompiler !== project?.compiler) body.compiler = newCompiler
    await postJSON(`/project/${projectId}/settings`, { body })
    const update: Record<string, string> = { rootDocId: convertEntityId }
    if (newCompiler) update.compiler = newCompiler
    updateProject(update)
  }, [convertEntityId, convertEntityName, project, projectId, updateProject])

  const { convert: convertToTypst } = useConvertDoc('typst', convertEntityId)
  const { convert: convertToLatex } = useConvertDoc('latex', convertEntityId)

  const downloadWithAnalytics = useCallback(() => {
    // we are only interested in downloads of bib files WRT analytics, for the purposes of promoting the tpr integrations
    if (selectedFileName?.endsWith('.bib')) {
      eventTracking.sendMB('download-bib-file', { projectOwner })
    }
  }, [selectedFileName, projectOwner])

  const createWithAnalytics = useCallback(() => {
    eventTracking.sendMB('new-file-click', { location: 'file-menu' })
    startCreatingDocOrFile()
  }, [startCreatingDocOrFile])

  const uploadWithAnalytics = useCallback(() => {
    eventTracking.sendMB('upload-click', { location: 'file-menu' })
    startUploadingDocOrFile()
  }, [startUploadingDocOrFile])

  return (
    <>
      {canRename ? (
        <li role="none">
          <DropdownItem onClick={startRenaming}>{t('rename')}</DropdownItem>
        </li>
      ) : null}
      {downloadPath ? (
        <li role="none">
          <DropdownItem
            href={downloadPath}
            onClick={downloadWithAnalytics}
            download={selectedFileName ?? undefined}
          >
            {t('download')}
          </DropdownItem>
        </li>
      ) : null}
      {canShowSetAsMain ? (
        <>
          <DropdownDivider />
          <li role="none">
            <DropdownItem onClick={handleSetAsMain}>
              {t('set_as_main_document')}
            </DropdownItem>
          </li>
        </>
      ) : null}
      {(canConvertToTypst || canConvertToLatex) ? (
        <>
          <DropdownDivider />
          {canConvertToTypst && (
            <li role="none">
              <DropdownItem onClick={convertToTypst}>
                {t('convert_to_typst')}
              </DropdownItem>
            </li>
          )}
          {canConvertToLatex && (
            <li role="none">
              <DropdownItem onClick={convertToLatex}>
                {t('convert_to_latex')}
              </DropdownItem>
            </li>
          )}
        </>
      ) : null}
      {canDelete ? (
        <>
          <DropdownDivider />
          <li role="none">
            <DropdownItem onClick={startDeleting}>{t('delete')}</DropdownItem>
          </li>
        </>
      ) : null}
      {canCreate ? (
        <>
          <DropdownDivider />
          <li role="none">
            <DropdownItem onClick={createWithAnalytics}>
              {t('new_file')}
            </DropdownItem>
          </li>
          <li role="none">
            <DropdownItem onClick={startCreatingFolder}>
              {t('new_folder')}
            </DropdownItem>
          </li>
          <li role="none">
            <DropdownItem onClick={uploadWithAnalytics}>
              {t('upload')}
            </DropdownItem>
          </li>
        </>
      ) : null}
    </>
  )
}

export default FileTreeItemMenuItems
