import { useEffect, useMemo, useState } from 'react'

import { useNavigate } from 'react-router-dom'
import { GitBranch, Keyboard, LayoutGrid, Plus, Search, Sparkles, Upload } from 'lucide-react'
import CategoryTree from '../components/CategoryTree.jsx'
import SkillCard from '../components/SkillCard.jsx'
import SkillKeyboardView from '../components/SkillKeyboardView.jsx'
import StatusBadge from '../components/StatusBadge.jsx'
import { getSkills, API_BASE, trackSkillDownload, voteSkill, getMyVote } from '../services/api.js'
import { useCategories } from '../contexts/CategoryContext.jsx'
import { useAuth } from '../contexts/AuthContext.jsx'
import { useChatOverlay } from '../contexts/ChatOverlayContext.jsx'
import { FEATURES } from '../featureFlags.js'
import { formatSkillDate, formatSkillDateTime } from '../services/skillTimestamp.js'

const TABS = [
  { key: 'all',       label: '全部' },
  { key: 'draft',     label: '草稿' },
  { key: 'published', label: '已上线' },
  { key: 'archived',  label: '已归档' },
]

const PAGE_SIZE = 12

export default function AllSkills() {
  const navigate = useNavigate()
  const { openOverlay } = useChatOverlay()
  const { flat: categories } = useCategories()
  const { user } = useAuth()
  const [selectedNode, setSelectedNode] = useState(null)
  const [tab, setTab] = useState('all')
  const [keyword, setKeyword] = useState('')
  const [keywordInput, setKeywordInput] = useState('')
  const [page, setPage] = useState(1)
  const [data, setData] = useState({ items: [], total: 0 })
  const [loading, setLoading] = useState(false)
  const [previewSkill, setPreviewSkill] = useState(null)
  const [viewMode, setViewMode] = useState(() => localStorage.getItem('allskills_view_mode') || 'grid')
  const [allSkills, setAllSkills] = useState([])

  // 视图切换持久化
  const switchView = (mode) => {
    setViewMode(mode)
    localStorage.setItem('allskills_view_mode', mode)
  }

  // 键盘模式下加载全量技能
  useEffect(() => {
    if (viewMode !== 'keyboard') return
    let cancelled = false
    getSkills({ status: 'all', page: 1, pageSize: 9999 })
      .then(res => { if (!cancelled) setAllSkills(res.items || []) })
    return () => { cancelled = true }
  }, [viewMode])

  const nodeId = selectedNode?.id || null

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    getSkills({ status: tab, page, pageSize: PAGE_SIZE, keyword, nodeId })
      .then(res => { if (!cancelled) setData(res) })
      .finally(() => { if (!cancelled) setLoading(false) })
    return () => { cancelled = true }
  }, [tab, page, keyword, nodeId])

  // 切换 tab/搜索/类目时回到第一页
  useEffect(() => { setPage(1) }, [tab, keyword, nodeId])

  const totalPages = Math.max(1, Math.ceil((data.total || 0) / PAGE_SIZE))
  const hasFilters = tab !== 'all' || !!keyword || !!nodeId

  const handleSearch = (e) => {
    e.preventDefault()
    setKeyword(keywordInput.trim())
  }

  const handleEvaluatePreviewSkill = () => {
    const skillId = previewSkill?.id
    if (!skillId) return
    setPreviewSkill(null)
    openOverlay('eval', { skillId })
  }

  const clearFilters = () => {
    setTab('all')
    setKeyword('')
    setKeywordInput('')
    setSelectedNode(null)
  }

  const breadcrumb = useMemo(() => {
    if (!selectedNode) return null
    return selectedNode.label
  }, [selectedNode])

  return (
    <div className="flex h-full overflow-hidden">
      {viewMode === 'grid' && (
        <div className="hidden lg:block h-full min-h-0">
          <CategoryTree selectedId={nodeId} onSelect={setSelectedNode} />
        </div>
      )}

      <div className="flex-1 min-w-0 flex flex-col bg-gray-50 overflow-hidden">
        <div className="border-b border-gray-200 bg-white px-6 py-4">
          <div className="flex flex-wrap items-start justify-between gap-4">
            <div className="min-w-0">
              <div className="flex items-center gap-2 text-[12px] text-gray-500">
                <Sparkles size={14} className="text-brand-600" />
                <span>Skill 管理</span>
                {breadcrumb && (
                  <span className="inline-flex min-w-0 items-center gap-1 truncate text-gray-400">
                    <GitBranch size={13} />
                    {breadcrumb}
                  </span>
                )}
              </div>
              <h1 className="mt-1 text-[20px] font-semibold text-gray-950">全部 Skill</h1>
              <div className="mt-1 text-[13px] text-gray-500">共 {data.total} 条</div>
            </div>
            <div className="flex flex-wrap items-center gap-2">
              <div className="flex h-9 overflow-hidden rounded-md border border-gray-200 bg-white">
                <button
                  onClick={() => switchView('grid')}
                  title="网格视图"
                  className={`grid w-9 place-items-center transition ${
                    viewMode === 'grid'
                      ? 'bg-gray-950 text-white'
                      : 'text-gray-500 hover:bg-gray-50'
                  }`}
                >
                  <LayoutGrid size={16} />
                </button>
                <button
                  onClick={() => switchView('keyboard')}
                  title="键盘视图"
                  className={`grid w-9 place-items-center border-l border-gray-200 transition ${
                    viewMode === 'keyboard'
                      ? 'bg-gray-950 text-white'
                      : 'text-gray-500 hover:bg-gray-50'
                  }`}
                >
                  <Keyboard size={16} />
                </button>
              </div>
              <button
                onClick={() => navigate('/upload')}
                title="上传 Skill"
                className="inline-flex h-9 items-center gap-1.5 rounded-md border border-gray-200 bg-white px-3 text-[13px] text-gray-700 transition hover:bg-gray-50 max-sm:w-9 max-sm:justify-center max-sm:px-0"
              >
                <Upload size={15} />
                <span className="whitespace-nowrap max-sm:hidden">上传</span>
              </button>
              {FEATURES.createSkill && (
                <button
                  onClick={() => openOverlay('create')}
                  title="创建 Skill"
                  className="inline-flex h-9 items-center gap-1.5 rounded-md bg-gray-950 px-3 text-[13px] text-white transition hover:bg-gray-800 max-sm:w-9 max-sm:justify-center max-sm:px-0"
                >
                  <Plus size={15} />
                  <span className="whitespace-nowrap max-sm:hidden">创建</span>
                </button>
              )}
            </div>
          </div>

          <div className="mt-4 flex flex-wrap items-center justify-between gap-3">
            <div className="flex items-center gap-1">
              {TABS.map(t => (
                <button
                  key={t.key}
                  onClick={() => setTab(t.key)}
                  className={[
                    'h-8 rounded-md px-3 text-[13px] transition',
                    tab === t.key ? 'bg-gray-950 text-white' : 'text-gray-600 hover:bg-gray-50'
                  ].join(' ')}
                >
                  {t.label}
                </button>
              ))}
            </div>
            <form onSubmit={handleSearch} className="flex min-w-[280px] flex-1 items-center justify-end gap-2">
              <div className="flex max-w-sm flex-1 items-center gap-2 rounded-md border border-gray-200 bg-white px-3 ring-1 ring-transparent transition focus-within:border-brand-300 focus-within:ring-brand-100">
                <Search size={15} className="text-gray-400" />
                <input
                  value={keywordInput}
                  onChange={e => setKeywordInput(e.target.value)}
                  placeholder="搜索 Skill 名称"
                  className="h-9 min-w-0 flex-1 border-0 text-[13px] outline-none"
                />
              </div>
              <button type="submit" className="h-9 rounded-md border border-gray-200 bg-white px-3 text-[13px] text-gray-700 transition hover:bg-gray-50">
                搜索
              </button>
            </form>
          </div>
        </div>

        {/* 卡片网格 / 键盘视图 */}
        <div className="flex-1 overflow-y-auto p-6">
          {viewMode === 'keyboard' ? (
            <SkillKeyboardView
              skills={allSkills}
              categories={categories}
              onSkillClick={(skill) => setPreviewSkill(skill)}
            />
          ) : loading ? (
            <div className="text-center text-[13px] text-gray-400 py-12">加载中...</div>
          ) : data.items.length === 0 ? (
            <EmptySkillState
              hasFilters={hasFilters}
              canCreate={FEATURES.createSkill}
              onUpload={() => navigate('/upload')}
              onCreate={() => openOverlay('create')}
              onClear={clearFilters}
            />
          ) : (
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
              {data.items.map((s, idx) => (
                <SkillCard
                  key={s.id}
                  skill={s}
                  isHot={idx < 5}
                  onClick={() => setPreviewSkill(s)}
                  onVote={(skillId, counts) => {
                    setData(d => ({
                      ...d,
                      items: d.items.map(item => item.id === skillId ? { ...item, ...counts } : item)
                    }))
                  }}
                />
              ))}
            </div>
          )}

          {/* 分页（仅网格视图） */}
          {viewMode === 'grid' && data.total > PAGE_SIZE && (
            <div className="mt-6 flex items-center justify-center gap-1 text-[13px]">
              <button
                disabled={page <= 1}
                onClick={() => setPage(p => Math.max(1, p - 1))}
                className="px-3 py-1 border border-gray-200 rounded text-gray-600 disabled:opacity-40 hover:bg-gray-50"
              >上一页</button>
              <span className="px-3 py-1 text-gray-500">第 {page} / {totalPages} 页</span>
              <button
                disabled={page >= totalPages}
                onClick={() => setPage(p => Math.min(totalPages, p + 1))}
                className="px-3 py-1 border border-gray-200 rounded text-gray-600 disabled:opacity-40 hover:bg-gray-50"
              >下一页</button>
            </div>
          )}
        </div>
      </div>

      {previewSkill && (
        <SkillDetailModal
          skill={previewSkill}
          currentUser={user}
          onClose={() => setPreviewSkill(null)}
          onEdit={() => { setPreviewSkill(null); navigate(`/skills/${previewSkill.id}/edit`) }}
          onRun={() => previewSkill?.id && openOverlay('sandbox', { skillId: previewSkill.id })}
          onEvaluate={handleEvaluatePreviewSkill}
          onVote={(skillId, counts) => {
            setData(d => ({
              ...d,
              items: d.items.map(s => s.id === skillId ? { ...s, ...counts } : s)
            }))
            setPreviewSkill(ps => ps?.id === skillId ? { ...ps, ...counts } : ps)
          }}
        />
      )}
    </div>
  )
}

function EmptySkillState({ hasFilters, canCreate, onUpload, onCreate, onClear }) {
  return (
    <div className="mx-auto mt-10 max-w-md rounded-lg border border-dashed border-gray-300 bg-white px-6 py-8 text-center">
      <div className="mx-auto grid h-10 w-10 place-items-center rounded-md bg-brand-50 text-brand-700">
        <Sparkles size={18} />
      </div>
      <h2 className="mt-4 text-[15px] font-semibold text-gray-950">
        {hasFilters ? '没有匹配的 Skill' : '还没有 Skill'}
      </h2>
      <p className="mt-1 text-[13px] leading-6 text-gray-500">
        {hasFilters
          ? '可以换个关键词、切回全部状态，或清除流程节点筛选。'
          : '发布前先上传一个 Skill 包，把能力归位到左侧流程节点。'}
      </p>
      <div className="mt-5 flex flex-wrap justify-center gap-2">
        {hasFilters && (
          <button
            type="button"
            onClick={onClear}
            className="inline-flex h-9 items-center rounded-md border border-gray-200 bg-white px-3 text-[13px] text-gray-700 transition hover:bg-gray-50"
          >
            清除筛选
          </button>
        )}
        <button
          type="button"
          onClick={onUpload}
          className="inline-flex h-9 items-center gap-1.5 rounded-md bg-gray-950 px-3 text-[13px] text-white transition hover:bg-gray-800"
        >
          <Upload size={15} />
          上传 Skill
        </button>
        {canCreate && (
          <button
            type="button"
            onClick={onCreate}
            className="inline-flex h-9 items-center gap-1.5 rounded-md border border-brand-200 bg-brand-50 px-3 text-[13px] text-brand-700 transition hover:bg-brand-100"
          >
            <Plus size={15} />
            创建 Skill
          </button>
        )}
      </div>
    </div>
  )
}

function SkillDetailModal({ skill, currentUser, onClose, onEdit, onRun, onEvaluate, onVote }) {
  const node = skill.category_nodes?.[0]
  const [copied, setCopied] = useState(false)
  const [myVote, setMyVote] = useState(null)           // 'like' | 'dislike' | null
  const [likeCount, setLikeCount] = useState(skill.like_count ?? 0)
  const [dislikeCount, setDislikeCount] = useState(skill.dislike_count ?? 0)
  const [voting, setVoting] = useState(false)

  // 打开弹窗时读取当前用户的投票状态
  useEffect(() => {
    getMyVote(skill.id).then(r => setMyVote(r.vote))
  }, [skill.id])

  const handleVote = async (vote) => {
    if (voting) return
    setVoting(true)
    try {
      const res = await voteSkill(skill.id, vote)
      setMyVote(res.vote)
      setLikeCount(res.like_count ?? 0)
      setDislikeCount(res.dislike_count ?? 0)
      onVote?.(skill.id, { like_count: res.like_count ?? 0, dislike_count: res.dislike_count ?? 0 })
    } catch {} finally {
      setVoting(false)
    }
  }

  const handleDownloadZip = () => {
    if (!skill.package_key) return
    const url = `${API_BASE}/uploads/download?key=${encodeURIComponent(skill.package_key)}`
    const a = document.createElement('a')
    a.href = url
    a.target = '_blank'
    a.rel = 'noopener noreferrer'
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    trackSkillDownload(skill.id)  // fire-and-forget
  }

  // 判断是否是创建人
  const isOwner = (
    (currentUser?.phone && skill.creator_phone && currentUser.phone === skill.creator_phone) ||
    (currentUser?.email && skill.creator_email && currentUser.email === skill.creator_email)
  )

  const handleCopyCurl = () => {
    if (!skill.package_key) return
    const fullUrl = `${window.location.origin}/api/uploads/download?key=${encodeURIComponent(skill.package_key)}`
    const filename = skill.package_name || 'skill.zip'
    const cmd = `curl -L "${fullUrl}" -o "${filename}"`

    const doSuccess = () => { setCopied(true); setTimeout(() => setCopied(false), 2000); trackSkillDownload(skill.id) }

    // HTTP 环境下 navigator.clipboard 不可用，降级用 execCommand
    const fallback = () => {
      try {
        const ta = document.createElement('textarea')
        ta.value = cmd
        ta.style.cssText = 'position:fixed;opacity:0;pointer-events:none'
        document.body.appendChild(ta)
        ta.select()
        document.execCommand('copy')
        document.body.removeChild(ta)
        doSuccess()
      } catch {}
    }

    if (navigator.clipboard && window.isSecureContext) {
      navigator.clipboard.writeText(cmd).then(doSuccess).catch(fallback)
    } else {
      fallback()
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40" onClick={onClose}>
      <div
        className="bg-white rounded-xl shadow-2xl w-[640px] max-w-[92vw] max-h-[88vh] flex flex-col overflow-hidden"
        onClick={e => e.stopPropagation()}
      >
        {/* 头部 */}
        <div className="px-6 py-4 border-b border-gray-100 flex items-start justify-between gap-4">
          <div className="min-w-0">
            <div className="flex items-center gap-2 flex-wrap">
              <h2 className="text-[17px] font-semibold text-gray-900 truncate">{skill.title || skill.name}</h2>
              <StatusBadge status={skill.status} />
              {isOwner && (
                <span className="text-[11px] px-1.5 py-0.5 rounded bg-brand-50 text-brand-600">👤 我创建</span>
              )}
            </div>
            <div className="mt-1 text-[12px] text-gray-500 flex items-center gap-3 flex-wrap">
              <span>👤 {skill.author || skill.creator_name}</span>
              <span>🕒 {formatSkillDate(skill.updated_at)}</span>
              {node && <span>📁 {node.parent_label ? `${node.parent_label} / ` : ''}{node.label}</span>}
            </div>
          </div>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-lg leading-none">✕</button>
        </div>

        {/* 内容 */}
        <div className="flex-1 overflow-y-auto px-6 py-5 space-y-4">
          {/* 描述 */}
          <div>
            <div className="text-[12px] font-medium text-gray-500 mb-1">简介</div>
            <p className="text-[13px] text-gray-700 leading-relaxed">
              {skill.description || skill.desc || <span className="text-gray-400">暂无描述</span>}
            </p>
          </div>

          {/* 文件信息 */}
          {skill.package_key && (
            <div className="bg-gray-50 border border-gray-100 rounded-lg px-4 py-3 space-y-2">
              <div className="flex items-center justify-between gap-3">
                <div className="min-w-0">
                  <div className="text-[11px] text-gray-400 mb-0.5">原始包</div>
                  <div className="text-[13px] text-gray-700 truncate">
                    {skill.package_name || '未命名'}
                    {skill.package_size ? <span className="ml-2 text-[11px] text-gray-400">{(skill.package_size / 1024).toFixed(1)} KB</span> : null}
                  </div>
                </div>
                <button
                  onClick={handleDownloadZip}
                  className="flex-shrink-0 px-3.5 py-1.5 text-[13px] rounded-md text-white bg-brand-600 hover:bg-brand-700 flex items-center gap-1"
                >
                  ↓ 下载原始包
                </button>
              </div>
              {/* curl 命令行 */}
              <div className="flex items-center gap-2">
                <code className="flex-1 text-[11px] bg-gray-900 text-gray-300 rounded px-3 py-1.5 truncate font-mono select-all">
                  curl -L &quot;{window.location.origin}/api/uploads/download?key={encodeURIComponent(skill.package_key)}&quot; -o &quot;{skill.package_name || 'skill.zip'}&quot;
                </code>
                <button
                  onClick={handleCopyCurl}
                  className={`flex-shrink-0 px-3 py-1.5 text-[12px] rounded-md border transition ${
                    copied
                      ? 'bg-emerald-50 border-emerald-300 text-emerald-700'
                      : 'bg-white border-gray-200 text-gray-600 hover:bg-gray-50'
                  }`}
                >
                  {copied ? '✓ 已复制' : '复制命令'}
                </button>
              </div>
            </div>
          )}

          {/* 元信息 */}
          <div className="grid grid-cols-2 gap-x-6 gap-y-3 text-[12px]">
            <div>
              <span className="text-[11px] text-gray-400">来源</span>
              <div className="text-gray-700">{skill.source === 'upload' ? '上传' : skill.source === 'create' ? '表单创建' : (skill.source || '—')}</div>
            </div>
            <div>
              <span className="text-[11px] text-gray-400">创建时间</span>
              <div className="text-gray-700">{formatSkillDateTime(skill.created_at)}</div>
            </div>
          </div>
        </div>

        {/* 底部按钮 */}
        <div className="px-6 py-3 border-t border-gray-100 flex items-center justify-between gap-2 bg-gray-50">
          {/* 点赞点踩 */}
          <div className="flex items-center gap-2">
            <button
              onClick={() => handleVote('like')}
              disabled={voting}
              title="点赞"
              className={[
                'flex items-center gap-1.5 px-3 py-1.5 text-[13px] rounded-md border transition',
                myVote === 'like'
                  ? 'bg-emerald-50 border-emerald-300 text-emerald-700 font-medium'
                  : 'bg-white border-gray-200 text-gray-600 hover:bg-gray-50'
              ].join(' ')}
            >
              <svg className="w-3.5 h-3.5" fill={myVote === 'like' ? 'currentColor' : 'none'} stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14 10h4.764a2 2 0 011.789 2.894l-3.5 7A2 2 0 0115.263 21h-4.017c-.163 0-.326-.02-.485-.06L7 20m7-10V5a2 2 0 00-2-2h-.095c-.5 0-.905.405-.905.905 0 .714-.211 1.412-.608 2.006L7 11v9m7-10h-2M7 20H5a2 2 0 01-2-2v-6a2 2 0 012-2h2.5" />
              </svg>
              {likeCount}
            </button>
            <button
              onClick={() => handleVote('dislike')}
              disabled={voting}
              title="点踩"
              className={[
                'flex items-center gap-1.5 px-3 py-1.5 text-[13px] rounded-md border transition',
                myVote === 'dislike'
                  ? 'bg-rose-50 border-rose-300 text-rose-700 font-medium'
                  : 'bg-white border-gray-200 text-gray-600 hover:bg-gray-50'
              ].join(' ')}
            >
              <svg className="w-3.5 h-3.5" fill={myVote === 'dislike' ? 'currentColor' : 'none'} stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.736 3h4.018c.163 0 .326.02.485.06L17 4m-7 10v2a2 2 0 002 2h.095c.5 0 .905-.405.905-.905 0-.714.211-1.412.608-2.006L17 13V4m-7 10h2m5-10h2a2 2 0 012 2v6a2 2 0 01-2 2h-2.5" />
              </svg>
              {dislikeCount}
            </button>
          </div>
          {/* 下载 / curl / 关闭 / 编辑 */}
          <div className="flex items-center gap-2">
            {skill.package_key && (
              <button
                onClick={onRun}
                className="px-3.5 py-1.5 text-[13px] rounded-md text-white bg-gray-950 hover:bg-gray-800 flex items-center gap-1"
              >
                ▶ 运行
              </button>
            )}
            {skill.package_key && (
              <button
                onClick={onEvaluate}
                className="px-3.5 py-1.5 text-[13px] rounded-md text-brand-700 border border-brand-200 bg-white hover:bg-brand-50 flex items-center gap-1"
              >
                ✓ 评测
              </button>
            )}
            {skill.package_key && (
              <button
                onClick={handleDownloadZip}
                className="px-3.5 py-1.5 text-[13px] rounded-md text-white bg-blue-600 hover:bg-blue-700 flex items-center gap-1"
              >
                ⬇ 下载
              </button>
            )}
            {skill.package_key && (
              <button
                onClick={handleCopyCurl}
                className={`px-3.5 py-1.5 text-[13px] rounded-md border transition flex items-center gap-1 ${
                  copied
                    ? 'bg-emerald-50 border-emerald-300 text-emerald-700'
                    : 'bg-white border-gray-200 text-gray-600 hover:bg-gray-50'
                }`}
              >
                {copied ? '✓ 已复制' : '📋 curl'}
              </button>
            )}
            <button
              onClick={onClose}
              className="px-3.5 py-1.5 text-[13px] rounded-md text-gray-600 bg-white border border-gray-200 hover:bg-gray-50"
            >
              关闭
            </button>
            {isOwner && (
              <button
                onClick={onEdit}
                className="px-3.5 py-1.5 text-[13px] rounded-md text-white bg-brand-600 hover:bg-brand-700"
              >
                ✏️ 编辑
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  )
}
