import { useMemo, useState } from 'react'
import { motion } from 'framer-motion'
import { CheckCircle2, Copy, Play, Server, TerminalSquare } from 'lucide-react'

type ApiEndpoint = {
  id: string
  name: string
  method: 'GET'
  path: string
  samplePath: string
  description: string
  fields: string[]
}

const endpoints: ApiEndpoint[] = [
  {
    id: 'process-groups',
    name: '过程组列表',
    method: 'GET',
    path: '/api/process-groups.json',
    samplePath: '/api/process-groups.json',
    description: '返回五大过程组基础信息。',
    fields: ['id：过程组 ID', 'name：过程组名称'],
  },
  {
    id: 'knowledge-areas',
    name: '知识领域列表',
    method: 'GET',
    path: '/api/knowledge-areas.json',
    samplePath: '/api/knowledge-areas.json',
    description: '返回十大知识领域及其裁剪因素。',
    fields: ['id：知识领域 ID', 'name：知识领域名称', 'tailoringFactors：裁剪因素数组', 'title：裁剪因素标题', 'description：裁剪因素说明'],
  },
  {
    id: 'knowledge-area-tailoring',
    name: '知识领域裁剪因素',
    method: 'GET',
    path: '/api/knowledge-areas/{id}/tailoring-factors.json',
    samplePath: '/api/knowledge-areas/KA01/tailoring-factors.json',
    description: '返回指定知识领域的裁剪因素。',
    fields: ['title：裁剪因素标题', 'description：裁剪因素说明'],
  },
  {
    id: 'knowledge-area-processes',
    name: '知识领域过程',
    method: 'GET',
    path: '/api/knowledge-areas/{id}/processes.json',
    samplePath: '/api/knowledge-areas/KA01/processes.json',
    description: '返回指定知识领域下的过程。',
    fields: ['id：过程 ID', 'name：过程名称', 'processGroupId：过程组 ID', 'processGroupName：过程组名称', 'purpose：主要作用'],
  },
  {
    id: 'process-group-processes',
    name: '过程组过程',
    method: 'GET',
    path: '/api/process-groups/{id}/processes.json',
    samplePath: '/api/process-groups/PG02/processes.json',
    description: '返回指定过程组下的过程。',
    fields: ['id：过程 ID', 'name：过程名称', 'knowledgeAreaId：知识领域 ID', 'knowledgeAreaName：知识领域名称', 'purpose：主要作用'],
  },
  {
    id: 'processes',
    name: '过程列表',
    method: 'GET',
    path: '/api/processes.json',
    samplePath: '/api/processes.json',
    description: '返回 49 个项目管理过程。',
    fields: ['id：过程 ID', 'name：过程名称', 'knowledgeAreaId：知识领域 ID', 'knowledgeAreaName：知识领域名称', 'processGroupId：过程组 ID', 'processGroupName：过程组名称', 'purpose：主要作用'],
  },
  {
    id: 'process-detail',
    name: '过程详情',
    method: 'GET',
    path: '/api/processes/{id}.json',
    samplePath: '/api/processes/P1.1.json',
    description: '返回指定过程基础信息。',
    fields: ['id：过程 ID', 'name：过程名称', 'knowledgeAreaId：知识领域 ID', 'knowledgeAreaName：知识领域名称', 'processGroupId：过程组 ID', 'processGroupName：过程组名称', 'purpose：主要作用'],
  },
  {
    id: 'process-itto',
    name: '过程 ITTO',
    method: 'GET',
    path: '/api/processes/{id}/itto.json',
    samplePath: '/api/processes/P1.1/itto.json',
    description: '返回指定过程的输入、工具与技术、输出。',
    fields: ['id：过程 ID', 'name：过程名称', 'inputs：输入数组', 'tools：工具数组', 'outputs：输出数组', 'details：明细项数组', 'note：过程语境备注'],
  },
  {
    id: 'performance-domains',
    name: '绩效域列表',
    method: 'GET',
    path: '/api/performance-domains.json',
    samplePath: '/api/performance-domains.json',
    description: '返回八大项目绩效域。',
    fields: ['id：绩效域 ID', 'name：绩效域名称'],
  },
  {
    id: 'performance-domain-detail',
    name: '绩效域详情',
    method: 'GET',
    path: '/api/performance-domains/{id}.json',
    samplePath: '/api/performance-domains/PD01.json',
    description: '返回指定绩效域的目标、要点、交互与检查项。',
    fields: ['id：绩效域 ID', 'name：绩效域名称', 'expectedGoals：预期目标', 'keyPoints：绩效要点', 'interactions：相互作用', 'checks：检查方法', 'goal：检查目标', 'indicators：检查指标'],
  },
  {
    id: 'artifact-usage',
    name: '工件使用情况',
    method: 'GET',
    path: '/api/artifacts/{id}/usage.json',
    samplePath: '/api/artifacts/A001/usage.json',
    description: '返回指定工件作为输入或输出的过程。',
    fields: ['id：工件 ID', 'name：工件名称', 'asInput：作为输入被哪些过程使用', 'asOutput：由哪些过程输出'],
  },
  {
    id: 'tool-usage',
    name: '工具与技术使用情况',
    method: 'GET',
    path: '/api/tools/{id}/usage.json',
    samplePath: '/api/tools/TT001/usage.json',
    description: '返回指定工具与技术出现的过程。',
    fields: ['id：工具 ID', 'name：工具名称', 'usedIn：使用该工具的过程数组'],
  },
  {
    id: 'api-doc-markdown',
    name: 'Markdown 接口文档',
    method: 'GET',
    path: '/apidoc',
    samplePath: '/apidoc',
    description: '返回接口说明 Markdown 文本字符串。',
    fields: ['响应体：Markdown 文本字符串', '用途：供知识库或外部系统直接读取接口说明'],
  },
]

const fieldGroups = [
  {
    title: '通用字段',
    items: ['id：稳定编号', 'name：中文名称', 'purpose：主要作用'],
  },
  {
    title: '过程字段',
    items: ['knowledgeAreaId：所属知识领域 ID', 'knowledgeAreaName：所属知识领域名称', 'processGroupId：所属过程组 ID', 'processGroupName：所属过程组名称'],
  },
  {
    title: '引用字段',
    items: ['inputs：输入数组', 'tools：工具数组', 'outputs：输出数组', 'details：明细项数组', 'note：补充说明'],
  },
]

function formatJson(value: unknown) {
  return JSON.stringify(value, null, 2)
}

export function ApiDocPage() {
  const [selectedId, setSelectedId] = useState(endpoints[0].id)
  const selectedEndpoint = useMemo(
    () => endpoints.find((endpoint) => endpoint.id === selectedId) ?? endpoints[0],
    [selectedId]
  )
  const [requestPath, setRequestPath] = useState(selectedEndpoint.samplePath)
  const [loading, setLoading] = useState(false)
  const [result, setResult] = useState<string>('')
  const [status, setStatus] = useState<string>('')

  function handleEndpointChange(endpointId: string) {
    const endpoint = endpoints.find((item) => item.id === endpointId) ?? endpoints[0]
    setSelectedId(endpoint.id)
    setRequestPath(endpoint.samplePath)
    setStatus('')
    setResult('')
  }

  async function handleFetchTest() {
    setLoading(true)
    setStatus('请求中')
    setResult('')

    try {
      const response = await fetch(requestPath, { headers: { Accept: 'application/json, text/markdown, text/plain, */*' } })
      const contentType = response.headers.get('content-type') ?? ''
      const body = contentType.includes('application/json') ? await response.json() : await response.text()

      setStatus(`${response.status} ${response.statusText || 'OK'}`)
      setResult(typeof body === 'string' ? body : formatJson(body))
    } catch (error) {
      setStatus('请求失败')
      setResult(error instanceof Error ? error.message : '无法完成请求')
    } finally {
      setLoading(false)
    }
  }

  async function copyPath() {
    await navigator.clipboard?.writeText(requestPath)
  }

  return (
    <div className="mx-auto max-w-7xl space-y-6">
      <motion.div
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        className="rounded-2xl bg-white p-6 shadow-sm ring-1 ring-gray-100 dark:bg-gray-800 dark:ring-gray-700"
      >
        <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
          <div>
            <div className="mb-3 inline-flex items-center gap-2 rounded-full bg-indigo-50 px-3 py-1 text-xs font-medium text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300">
              <Server size={14} />
              知识库接口
            </div>
            <h1 className="text-2xl font-bold text-gray-900 dark:text-white">API 调用说明</h1>
            <p className="mt-2 max-w-2xl text-sm leading-6 text-gray-500 dark:text-gray-400">
              静态接口采用 GET 请求，/api 返回 JSON，/apidoc 返回 Markdown 文本；面向知识库读取，不包含搜索、展示样式和五问一法。
            </p>
            <div className="mt-4 flex flex-wrap gap-2">
              <a
                href="/apidoc"
                target="_blank"
                rel="noreferrer"
                className="inline-flex items-center rounded-lg bg-gray-900 px-3 py-2 text-sm font-medium text-white transition hover:bg-gray-700 dark:bg-white dark:text-gray-900 dark:hover:bg-gray-200"
              >
                查看 Markdown 文档 /apidoc
              </a>
            </div>
          </div>
          <div className="grid grid-cols-3 gap-3 text-center">
            <div className="rounded-xl bg-gray-50 px-4 py-3 dark:bg-gray-900/50">
              <div className="text-lg font-bold text-gray-900 dark:text-white">{endpoints.length}</div>
              <div className="text-xs text-gray-500 dark:text-gray-400">个接口</div>
            </div>
            <div className="rounded-xl bg-gray-50 px-4 py-3 dark:bg-gray-900/50">
              <div className="text-lg font-bold text-gray-900 dark:text-white">GET</div>
              <div className="text-xs text-gray-500 dark:text-gray-400">请求方法</div>
            </div>
            <div className="rounded-xl bg-gray-50 px-4 py-3 dark:bg-gray-900/50">
              <div className="text-lg font-bold text-gray-900 dark:text-white">JSON/MD</div>
              <div className="text-xs text-gray-500 dark:text-gray-400">响应格式</div>
            </div>
          </div>
        </div>
      </motion.div>

      <div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_420px]">
        <motion.section
          initial={{ opacity: 0, y: 12 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.04 }}
          className="rounded-2xl bg-white shadow-sm ring-1 ring-gray-100 dark:bg-gray-800 dark:ring-gray-700"
        >
          <div className="border-b border-gray-100 px-5 py-4 dark:border-gray-700">
            <h2 className="font-semibold text-gray-900 dark:text-white">接口列表</h2>
          </div>
          <div className="divide-y divide-gray-100 dark:divide-gray-700">
            {endpoints.map((endpoint) => (
              <button
                key={endpoint.id}
                type="button"
                onClick={() => handleEndpointChange(endpoint.id)}
                className={`w-full px-5 py-4 text-left transition-colors hover:bg-gray-50 dark:hover:bg-gray-700/40 ${
                  selectedEndpoint.id === endpoint.id ? 'bg-indigo-50/70 dark:bg-indigo-900/20' : ''
                }`}
              >
                <div className="flex flex-col gap-2 lg:flex-row lg:items-start lg:justify-between">
                  <div className="min-w-0">
                    <div className="flex items-center gap-2">
                      <span className="rounded-md bg-emerald-50 px-2 py-0.5 text-xs font-bold text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300">
                        {endpoint.method}
                      </span>
                      <h3 className="font-medium text-gray-900 dark:text-white">{endpoint.name}</h3>
                    </div>
                    <p className="mt-1 font-mono text-xs text-indigo-600 dark:text-indigo-300">{endpoint.path}</p>
                    <p className="mt-2 text-sm text-gray-500 dark:text-gray-400">{endpoint.description}</p>
                  </div>
                  {selectedEndpoint.id === endpoint.id && <CheckCircle2 className="h-5 w-5 text-indigo-500" />}
                </div>
              </button>
            ))}
          </div>
        </motion.section>

        <motion.aside
          initial={{ opacity: 0, y: 12 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.08 }}
          className="space-y-6"
        >
          <section className="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-gray-100 dark:bg-gray-800 dark:ring-gray-700">
            <div className="mb-4 flex items-center gap-2">
              <TerminalSquare className="h-5 w-5 text-indigo-500" />
              <h2 className="font-semibold text-gray-900 dark:text-white">调用测试</h2>
            </div>

            <label className="text-sm font-medium text-gray-700 dark:text-gray-300" htmlFor="api-endpoint">
              选择接口
            </label>
            <select
              id="api-endpoint"
              value={selectedId}
              onChange={(event) => handleEndpointChange(event.target.value)}
              className="mt-2 w-full rounded-lg border border-gray-200 bg-white px-3 py-2 text-sm text-gray-900 outline-none transition focus:border-indigo-500 focus:ring-2 focus:ring-indigo-100 dark:border-gray-600 dark:bg-gray-900 dark:text-white dark:focus:ring-indigo-900/40"
            >
              {endpoints.map((endpoint) => (
                <option key={endpoint.id} value={endpoint.id}>{endpoint.name}</option>
              ))}
            </select>

            <label className="mt-4 block text-sm font-medium text-gray-700 dark:text-gray-300" htmlFor="api-path">
              请求路径
            </label>
            <div className="mt-2 flex gap-2">
              <input
                id="api-path"
                value={requestPath}
                onChange={(event) => setRequestPath(event.target.value)}
                className="min-w-0 flex-1 rounded-lg border border-gray-200 bg-white px-3 py-2 font-mono text-sm text-gray-900 outline-none transition focus:border-indigo-500 focus:ring-2 focus:ring-indigo-100 dark:border-gray-600 dark:bg-gray-900 dark:text-white dark:focus:ring-indigo-900/40"
              />
              <button
                type="button"
                onClick={copyPath}
                className="rounded-lg border border-gray-200 px-3 text-gray-600 transition hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700"
                aria-label="复制请求路径"
              >
                <Copy size={17} />
              </button>
            </div>

            <button
              type="button"
              onClick={handleFetchTest}
              disabled={loading || !requestPath.trim()}
              className="mt-4 inline-flex w-full items-center justify-center gap-2 rounded-lg bg-indigo-600 px-4 py-2.5 text-sm font-medium text-white transition hover:bg-indigo-700 disabled:cursor-not-allowed disabled:opacity-60"
            >
              <Play size={16} />
              {loading ? '请求中' : '发送请求'}
            </button>

            {status && (
              <div className="mt-4 rounded-lg bg-gray-50 p-3 dark:bg-gray-900/60">
                <div className="mb-2 text-xs font-medium text-gray-500 dark:text-gray-400">响应</div>
                <div className="mb-3 text-sm font-semibold text-gray-900 dark:text-white">{status}</div>
                <pre className="max-h-96 overflow-auto whitespace-pre-wrap break-words rounded-lg bg-gray-950 p-3 text-xs leading-5 text-gray-100">
                  {result}
                </pre>
              </div>
            )}
          </section>

          <section className="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-gray-100 dark:bg-gray-800 dark:ring-gray-700">
            <h2 className="font-semibold text-gray-900 dark:text-white">字段说明</h2>
            <div className="mt-4 space-y-4">
              {fieldGroups.map((group) => (
                <div key={group.title}>
                  <h3 className="text-sm font-medium text-gray-800 dark:text-gray-200">{group.title}</h3>
                  <ul className="mt-2 space-y-1 text-sm leading-6 text-gray-500 dark:text-gray-400">
                    {group.items.map((item) => <li key={item}>• {item}</li>)}
                  </ul>
                </div>
              ))}
            </div>
          </section>
        </motion.aside>
      </div>

      <motion.section
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ delay: 0.12 }}
        className="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-gray-100 dark:bg-gray-800 dark:ring-gray-700"
      >
        <h2 className="font-semibold text-gray-900 dark:text-white">{selectedEndpoint.name}字段</h2>
        <div className="mt-3 grid gap-2 md:grid-cols-2 xl:grid-cols-3">
          {selectedEndpoint.fields.map((field) => (
            <div key={field} className="rounded-lg bg-gray-50 px-3 py-2 text-sm text-gray-600 dark:bg-gray-900/50 dark:text-gray-300">
              {field}
            </div>
          ))}
        </div>
      </motion.section>
    </div>
  )
}
