'use client'
import type { ComponentType } from 'react'
import type { App, AppSSO } from '@/types/app'
import { cn } from '@langgenius/dify-ui/cn'
import { useMemo } from 'react'
import { useLocale } from '@/context/i18n'
import useTheme from '@/hooks/use-theme'
import { getDocLanguage } from '@/i18n-config/language'
import { AppModeEnum, Theme } from '@/types/app'
import { useDocToc } from './hooks/use-doc-toc'
import TemplateEn from './template/template.en.mdx'
import TemplateJa from './template/template.ja.mdx'
import TemplateZh from './template/template.zh.mdx'
import TemplateAdvancedChatEn from './template/template_advanced_chat.en.mdx'
import TemplateAdvancedChatJa from './template/template_advanced_chat.ja.mdx'
import TemplateAdvancedChatZh from './template/template_advanced_chat.zh.mdx'
import TemplateChatEn from './template/template_chat.en.mdx'
import TemplateChatJa from './template/template_chat.ja.mdx'
import TemplateChatZh from './template/template_chat.zh.mdx'
import TemplateWorkflowEn from './template/template_workflow.en.mdx'
import TemplateWorkflowJa from './template/template_workflow.ja.mdx'
import TemplateWorkflowZh from './template/template_workflow.zh.mdx'
import TocPanel from './toc-panel'

type AppDetail = App & Partial<AppSSO>
type PromptVariable = { key: string; name: string }

type IDocProps = {
  appDetail: AppDetail
}

// Shared props shape for all MDX template components
type TemplateProps = {
  appDetail: AppDetail
  variables: PromptVariable[]
  inputs: Record<string, string>
}

// Lookup table: [appMode][docLanguage] → template component
// MDX components accept arbitrary props at runtime but expose a narrow static type,
// so we assert the map type to allow passing TemplateProps when rendering.
const TEMPLATE_MAP = {
  [AppModeEnum.CHAT]: { zh: TemplateChatZh, ja: TemplateChatJa, en: TemplateChatEn },
  [AppModeEnum.AGENT_CHAT]: { zh: TemplateChatZh, ja: TemplateChatJa, en: TemplateChatEn },
  [AppModeEnum.ADVANCED_CHAT]: {
    zh: TemplateAdvancedChatZh,
    ja: TemplateAdvancedChatJa,
    en: TemplateAdvancedChatEn,
  },
  [AppModeEnum.WORKFLOW]: {
    zh: TemplateWorkflowZh,
    ja: TemplateWorkflowJa,
    en: TemplateWorkflowEn,
  },
  [AppModeEnum.COMPLETION]: { zh: TemplateZh, ja: TemplateJa, en: TemplateEn },
} as Record<string, Record<string, ComponentType<TemplateProps>>>

const resolveTemplate = (
  mode: string | undefined,
  locale: string,
): ComponentType<TemplateProps> | null => {
  if (!mode) return null
  const langTemplates = TEMPLATE_MAP[mode]
  if (!langTemplates) return null
  const docLang = getDocLanguage(locale)
  return langTemplates[docLang] ?? langTemplates.en ?? null
}

const Doc = ({ appDetail }: IDocProps) => {
  const locale = useLocale()
  const { theme } = useTheme()
  const { toc, isTocExpanded, setIsTocExpanded, activeSection, handleTocClick } = useDocToc({
    appDetail,
    locale,
  })

  // model_config.configs.prompt_variables exists in the raw API response but is not modeled in ModelConfig type
  const variables: PromptVariable[] =
    (
      appDetail?.model_config as unknown as
        | Record<string, Record<string, PromptVariable[]>>
        | undefined
    )?.configs?.prompt_variables ?? []
  const inputs = variables.reduce<Record<string, string>>((res, variable) => {
    res[variable.key] = variable.name || ''
    return res
  }, {})

  const TemplateComponent = useMemo(
    () => resolveTemplate(appDetail?.mode, locale),
    [appDetail?.mode, locale],
  )

  return (
    <div className="flex">
      <div
        className={`fixed top-32 right-20 z-10 transition-all duration-150 ease-out ${isTocExpanded ? 'w-70' : 'w-11'}`}
      >
        <TocPanel
          toc={toc}
          activeSection={activeSection}
          isTocExpanded={isTocExpanded}
          onToggle={setIsTocExpanded}
          onItemClick={handleTocClick}
        />
      </div>
      <article className={cn('prose-xl prose', theme === Theme.dark && 'prose-invert')}>
        {TemplateComponent && (
          <TemplateComponent appDetail={appDetail} variables={variables} inputs={inputs} />
        )}
      </article>
    </div>
  )
}

export default Doc
