import { useMemo, useRef, useState } from 'react'
import { Navigate } from 'react-router-dom'
import { CheckCircle2, GitBranch, Loader2, Sparkles, Trash2, Upload, Workflow } from 'lucide-react'
import { useAuth } from '../contexts/AuthContext.jsx'
import { generateAiFlowchart } from '../services/api.js'

const SUPER_ADMIN_EMAIL = '494161546@qq.com'
const SUPER_ADMIN_PHONE = '13136092523'

const sampleNodes = [
  { id: 'start', label: '流程文件 / 自然语言', type: 'start', actor: '输入', context: '等待生成', x: 6, y: 34 },
  { id: 'extract', label: '抽取活动与角色', type: 'activity', actor: 'AI 理解', context: '等待生成', x: 28, y: 16 },
  { id: 'map', label: '生成依赖关系', type: 'activity', actor: '结构化', context: '等待生成', x: 52, y: 34 },
  { id: 'canvas', label: '平台内画布', type: 'activity', actor: '可编辑', context: '等待生成', x: 74, y: 16 },
  { id: 'save', label: '保存流程资产', type: 'end', actor: '沉淀', context: '等待生成', x: 74, y: 58 },
]

const sampleGraph = {
  title: 'AI 绘图链路',
  summary: '提交后由当前 AI 执行内核生成业务流程图。',
  lanes: [],
  nodes: sampleNodes,
  edges: [
    { id: 'e1', source: 'start', target: 'extract', label: '' },
    { id: 'e2', source: 'extract', target: 'map', label: '' },
    { id: 'e3', source: 'map', target: 'canvas', label: '' },
    { id: 'e4', source: 'canvas', target: 'save', label: '' },
  ],
  notes: [],
}

const techRoute = [
  ['输入层', '自然语言 + 流程文件', '先让 AI 读懂活动、执行者、上下游依赖和上下文。'],
  ['中间层', '结构化 JSON / Mermaid', 'AI 先写可校验的图谱，再进入画布，避免自由画乱。'],
  ['画布层', 'React Flow', '嵌入平台内容器，节点、连线、拖拽和后续属性编辑都好接。'],
  ['标准层', 'BPMN 作为二期', '等要靠近生产级流程定义时，再引入更严格的 BPMN。'],
]

export default function AiFlowDrawing() {
  const { user } = useAuth()
  const fileInputRef = useRef(null)
  const canvasRef = useRef(null)
  const [prompt, setPrompt] = useState('把采购申请到付款的端到端流程画出来，标清申请人、部门负责人、采购、财务和供应商。')
  const [file, setFile] = useState(null)
  const [mode, setMode] = useState('react-flow')
  const [graph, setGraph] = useState(sampleGraph)
  const [selectedNodeId, setSelectedNodeId] = useState('')
  const [drag, setDrag] = useState(null)
  const [isGenerating, setIsGenerating] = useState(false)
  const [error, setError] = useState('')
  const [resultMeta, setResultMeta] = useState(null)

  const isSuperAdmin = user?.email === SUPER_ADMIN_EMAIL || user?.phone === SUPER_ADMIN_PHONE

  const nodesById = useMemo(() => {
    const map = new Map()
    for (const node of graph.nodes || []) map.set(node.id, node)
    return map
  }, [graph.nodes])

  const selectedNode = selectedNodeId ? nodesById.get(selectedNodeId) : null
  const engineLabel = useMemo(() => {
    const engine = resultMeta?.engine
    if (!engine) return ''
    if (engine.kind === 'agentrun') {
      const runtime = engine.agentRun?.runtimeName || engine.agentRun?.name || 'AgentRun'
      const endpoint = engine.agentRun?.endpointName || engine.agentRun?.defaultModel || ''
      return `AgentRun：${runtime}${endpoint ? ` · ${endpoint}` : ''}`
    }
    const provider = engine.provider
    if (provider?.name || provider?.code) {
      return `AI 内核：${provider.name || provider.code}${provider.model ? ` · ${provider.model}` : ''}`
    }
    return 'AI 执行内核已连接'
  }, [resultMeta])

  if (!isSuperAdmin) return <Navigate to="/all-skills" replace />

  async function handleGenerate() {
    if (!prompt.trim() && !file) return
    setIsGenerating(true)
    setError('')
    setResultMeta(null)
    try {
      const res = await generateAiFlowchart({ prompt, file, mode })
      setGraph(res.data || sampleGraph)
      setSelectedNodeId('')
      setResultMeta(res)
    } catch (e) {
      setError(e?.message || String(e))
    } finally {
      setIsGenerating(false)
    }
  }

  function patchNode(id, patch) {
    setGraph(prev => ({
      ...prev,
      nodes: (prev.nodes || []).map(node => node.id === id ? { ...node, ...patch } : node),
    }))
  }

  function deleteNode(id) {
    setGraph(prev => ({
      ...prev,
      nodes: (prev.nodes || []).filter(node => node.id !== id),
      edges: (prev.edges || []).filter(edge => edge.source !== id && edge.target !== id),
    }))
    if (selectedNodeId === id) setSelectedNodeId('')
  }

  function handlePointerDown(e, node) {
    if (e.target.closest('button')) return
    const rect = canvasRef.current?.getBoundingClientRect()
    if (!rect) return
    setSelectedNodeId(node.id)
    setDrag({ id: node.id, startX: e.clientX, startY: e.clientY, x: node.x, y: node.y, width: rect.width, height: rect.height })
  }

  function handlePointerMove(e) {
    if (!drag) return
    const nextX = Math.max(2, Math.min(86, drag.x + ((e.clientX - drag.startX) / drag.width) * 100))
    const nextY = Math.max(8, Math.min(82, drag.y + ((e.clientY - drag.startY) / drag.height) * 100))
    patchNode(drag.id, { x: nextX, y: nextY })
  }

  function handlePointerUp() {
    setDrag(null)
  }

  return (
    <div className="flex h-full min-h-0 flex-col bg-gray-50">
      <header className="border-b border-gray-200 bg-white px-6 py-4">
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <div className="flex items-center gap-2 text-[12px] text-gray-500">
              <Workflow size={14} className="text-brand-600" />
              <span>实用功能</span>
            </div>
            <h1 className="mt-1 text-[20px] font-semibold text-gray-950">AI绘图</h1>
          </div>
          <span className="rounded-full bg-gray-100 px-2.5 py-1 text-[11px] font-medium text-gray-600">
            超级管理员
          </span>
        </div>
      </header>

      <div className="grid min-h-0 flex-1 grid-cols-[360px_minmax(0,1fr)] max-lg:grid-cols-1">
        <aside className="min-h-0 overflow-y-auto border-r border-gray-200 bg-white p-4">
          <div className="space-y-4">
            <section>
              <label className="text-[12px] font-medium text-gray-600">流程描述</label>
              <textarea
                value={prompt}
                onChange={e => setPrompt(e.target.value)}
                rows={8}
                className="mt-2 w-full resize-none rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-[13px] leading-6 text-gray-800 outline-none transition focus:border-brand-400 focus:ring-2 focus:ring-brand-100"
              />
            </section>

            <section>
              <label className="text-[12px] font-medium text-gray-600">流程文件</label>
              <input
                ref={fileInputRef}
                type="file"
                className="hidden"
                accept=".pdf,.doc,.docx,.txt,.md,.csv,.xlsx"
                onChange={e => setFile(e.target.files?.[0] || null)}
              />
              <button
                type="button"
                onClick={() => fileInputRef.current?.click()}
                className="mt-2 flex w-full items-center justify-between gap-3 rounded-lg border border-dashed border-gray-300 bg-gray-50 px-3 py-3 text-left transition hover:border-brand-300 hover:bg-brand-50"
              >
                <span className="flex min-w-0 items-center gap-2">
                  <Upload size={16} className="flex-shrink-0 text-gray-500" />
                  <span className="truncate text-[13px] text-gray-700">{file?.name || '选择流程文件'}</span>
                </span>
                {file && <CheckCircle2 size={16} className="flex-shrink-0 text-emerald-600" />}
              </button>
            </section>

            <section>
              <div className="text-[12px] font-medium text-gray-600">输出底座</div>
              <div className="mt-2 grid grid-cols-3 gap-1 rounded-lg bg-gray-100 p-1">
                {[
                  ['react-flow', '画布'],
                  ['mermaid', '文本'],
                  ['bpmn', 'BPMN'],
                ].map(([value, label]) => (
                  <button
                    key={value}
                    type="button"
                    onClick={() => setMode(value)}
                    className={[
                      'rounded-md px-2 py-1.5 text-[12px] transition',
                      mode === value ? 'bg-white font-medium text-gray-950 shadow-sm' : 'text-gray-500 hover:text-gray-800'
                    ].join(' ')}
                  >
                    {label}
                  </button>
                ))}
              </div>
            </section>

            <button
              type="button"
              onClick={handleGenerate}
              className="flex w-full items-center justify-center gap-2 rounded-lg bg-gray-950 px-4 py-2.5 text-[13px] font-medium text-white transition hover:bg-gray-800 disabled:cursor-not-allowed disabled:bg-gray-300"
              disabled={isGenerating || (!prompt.trim() && !file)}
            >
              {isGenerating ? <Loader2 size={16} className="animate-spin" /> : <Sparkles size={16} />}
              {isGenerating ? 'AI 生成中' : '生成草图'}
            </button>

            {error && (
              <div className="rounded-lg border border-rose-200 bg-rose-50 px-3 py-2 text-[12px] leading-5 text-rose-700">
                {error}
              </div>
            )}

            {resultMeta?.engine && (
              <div className="rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-2 text-[12px] leading-5 text-emerald-700">
                {engineLabel}
              </div>
            )}

            {selectedNode && (
              <section className="rounded-lg border border-gray-200 bg-gray-50 p-3">
                <div className="mb-2 text-[12px] font-medium text-gray-600">节点编辑</div>
                <label className="block text-[11px] text-gray-500">活动</label>
                <input
                  value={selectedNode.label || ''}
                  onChange={e => patchNode(selectedNode.id, { label: e.target.value })}
                  className="mt-1 w-full rounded-md border border-gray-200 bg-white px-2 py-1.5 text-[12px] outline-none focus:border-brand-400"
                />
                <label className="mt-2 block text-[11px] text-gray-500">执行者</label>
                <input
                  value={selectedNode.actor || ''}
                  onChange={e => patchNode(selectedNode.id, { actor: e.target.value })}
                  className="mt-1 w-full rounded-md border border-gray-200 bg-white px-2 py-1.5 text-[12px] outline-none focus:border-brand-400"
                />
                <label className="mt-2 block text-[11px] text-gray-500">上下文</label>
                <textarea
                  value={selectedNode.context || ''}
                  onChange={e => patchNode(selectedNode.id, { context: e.target.value })}
                  rows={3}
                  className="mt-1 w-full resize-none rounded-md border border-gray-200 bg-white px-2 py-1.5 text-[12px] leading-5 outline-none focus:border-brand-400"
                />
              </section>
            )}
          </div>
        </aside>

        <main className="min-h-0 overflow-y-auto">
          <section className="border-b border-gray-200 bg-white px-5 py-3">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div className="flex items-center gap-2 text-[13px] font-medium text-gray-800">
                <GitBranch size={16} className="text-brand-600" />
                {graph.title || '平台内流程画布'}
              </div>
              <div className="flex items-center gap-2 text-[11px] text-gray-500">
                <span className="rounded-full bg-brand-50 px-2 py-0.5 text-brand-700">React Flow 优先</span>
                <span className="rounded-full bg-gray-100 px-2 py-0.5">Mermaid 兜底</span>
              </div>
            </div>
          </section>

          <section className="p-5">
            <div className="overflow-x-auto rounded-lg border border-gray-200 bg-white">
              <div
                ref={canvasRef}
                className="relative h-[430px] min-w-[980px] overflow-hidden"
                onPointerMove={handlePointerMove}
                onPointerUp={handlePointerUp}
                onPointerLeave={handlePointerUp}
              >
                <div className="absolute inset-0 bg-[linear-gradient(#eef2f7_1px,transparent_1px),linear-gradient(90deg,#eef2f7_1px,transparent_1px)] bg-[size:28px_28px]" />
                <svg className="absolute inset-0 h-full w-full" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
                  {(graph.edges || []).map(edge => {
                    const source = nodesById.get(edge.source)
                    const target = nodesById.get(edge.target)
                    if (!source || !target) return null
                    const sx = Number(source.x || 0) + 8
                    const sy = Number(source.y || 0) + 6
                    const tx = Number(target.x || 0) + 2
                    const ty = Number(target.y || 0) + 6
                    return (
                      <g key={edge.id || `${edge.source}-${edge.target}`}>
                        <path
                          d={`M ${sx} ${sy} C ${(sx + tx) / 2} ${sy}, ${(sx + tx) / 2} ${ty}, ${tx} ${ty}`}
                          stroke="#94A3B8"
                          strokeWidth="0.35"
                          fill="none"
                        />
                      </g>
                    )
                  })}
                </svg>
                {(graph.nodes || []).map(node => (
                  <div
                    key={node.id}
                    onPointerDown={e => handlePointerDown(e, node)}
                    className={[
                      'absolute w-44 cursor-grab rounded-lg border bg-white px-3 py-2.5 shadow-sm shadow-slate-200/60 transition active:cursor-grabbing',
                      selectedNodeId === node.id ? 'border-brand-400 ring-2 ring-brand-100' : 'border-gray-200'
                    ].join(' ')}
                    style={{ left: `${node.x}%`, top: `${node.y}%` }}
                  >
                    <div className="flex items-start justify-between gap-2">
                      <div className="min-w-0">
                        <div className="truncate text-[11px] font-medium text-brand-600">{node.actor || node.type || '活动'}</div>
                        <div className="mt-1 line-clamp-2 text-[13px] font-semibold leading-5 text-gray-950">{node.label}</div>
                      </div>
                      <button
                        type="button"
                        onClick={() => deleteNode(node.id)}
                        className="grid h-6 w-6 flex-shrink-0 place-items-center rounded text-gray-400 transition hover:bg-rose-50 hover:text-rose-600"
                        title="删除节点"
                      >
                        <Trash2 size={13} />
                      </button>
                    </div>
                    {node.context && <div className="mt-2 line-clamp-2 text-[11px] leading-4 text-gray-500">{node.context}</div>}
                  </div>
                ))}
              </div>
            </div>

            <div className="mt-5 overflow-hidden rounded-lg border border-gray-200 bg-white">
              <div className="grid grid-cols-[112px_minmax(0,180px)_minmax(0,1fr)] gap-3 border-b border-gray-100 bg-gray-50 px-4 py-2 text-[12px] font-medium text-gray-500">
                <div>模块</div>
                <div>推荐</div>
                <div>判断</div>
              </div>
              <div className="divide-y divide-gray-100">
                {techRoute.map(row => (
                  <div key={row[0]} className="grid grid-cols-[112px_minmax(0,180px)_minmax(0,1fr)] gap-3 px-4 py-3 text-[13px]">
                    <div className="font-medium text-gray-700">{row[0]}</div>
                    <div className="text-gray-950">{row[1]}</div>
                    <div className="text-gray-500">{row[2]}</div>
                  </div>
                ))}
              </div>
            </div>
          </section>
        </main>
      </div>
    </div>
  )
}
