import { useState, useEffect, useCallback } from 'react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import rehypeRaw from 'rehype-raw'
import { FileText, X, Copy, Check, Loader2, Clock } from 'lucide-react'
import { useStore } from '../store'
import type { TodoItem, Message } from '../types'

const API = '/api'

/** 从任务描述中解析出子任务列表 */
function parseSubTasks(task: string): string[] {
  // 匹配 "1. xxx" "2、xxx" "① xxx" 等编号格式，或 "- xxx" 列表
  const lines = task.split('\n')
  const items: string[] = []
  const pattern = /^[\s]*(?:\d+[.、)）]|[-•·]|[①②③④⑤⑥⑦⑧⑨⑩])\s*(.+)/
  for (const line of lines) {
    const m = line.match(pattern)
    if (m) items.push(m[1].trim())
  }
  return items
}

function StatusBadge({ status }: { status: TodoItem['status'] }) {
  if (status === 'done') {
    return (
      <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-green-500/15 text-green-600 dark:text-green-400">
        <svg className="w-3 h-3" viewBox="0 0 16 16" fill="none"><path d="M13.25 4.75L6 12 2.75 8.75" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
        完成
      </span>
    )
  }
  if (status === 'working') {
    return (
      <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--accent)]/15 text-[var(--accent)]">
        <Loader2 className="w-3 h-3 animate-spin" />
        执行中
      </span>
    )
  }
  return (
    <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--bg-tertiary)] text-[var(--text-muted)]">
      <span className="w-1.5 h-1.5 rounded-full bg-current opacity-50" />
      等待中
    </span>
  )
}

function TodoCard({ todo, onClick }: { todo: TodoItem; onClick?: () => void }) {
  const subTasks = parseSubTasks(todo.task)
  const isDone = todo.status === 'done'

  return (
    <div className={`mx-3 mb-2 rounded-lg border transition-all cursor-pointer hover:shadow-md ${
      isDone
        ? 'border-green-500/20 bg-green-500/5'
        : todo.status === 'working'
          ? 'border-[var(--accent)]/30 bg-[var(--accent)]/5 shadow-sm shadow-[var(--accent)]/10'
          : 'border-[var(--border)] bg-[var(--bg-primary)]'
    }`}
      onClick={onClick}
    >
      {/* 卡片头部：agent + 状态 */}
      <div className="flex items-center justify-between px-3 py-2">
        <div className="flex items-center gap-2 min-w-0">
          <div className={`w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-bold text-white flex-shrink-0 ${
            isDone ? 'bg-green-500' : todo.status === 'working' ? 'bg-[var(--accent)]' : 'bg-[var(--text-muted)]'
          }`}>
            {todo.agent.charAt(0)}
          </div>
          <span className={`text-xs font-semibold truncate ${isDone ? 'text-[var(--text-muted)]' : 'text-[var(--text-primary)]'}`}>
            {todo.agent}
          </span>
        </div>
        <StatusBadge status={todo.status} />
      </div>

      {/* 子任务列表 */}
      {subTasks.length > 0 ? (
        <div className="px-3 pb-2.5 space-y-1">
          {subTasks.map((item, i) => (
            <div key={i} className="flex items-start gap-1.5">
              <div className={`w-3.5 h-3.5 mt-px rounded-sm border flex items-center justify-center flex-shrink-0 ${
                isDone
                  ? 'border-green-500/40 bg-green-500/20'
                  : 'border-[var(--border)] bg-[var(--bg-secondary)]'
              }`}>
                {isDone && (
                  <svg className="w-2.5 h-2.5 text-green-600 dark:text-green-400" viewBox="0 0 16 16" fill="none">
                    <path d="M13.25 4.75L6 12 2.75 8.75" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                )}
              </div>
              <span
                className={`text-[11px] leading-snug ${
                  isDone ? 'text-[var(--text-muted)] line-through' : 'text-[var(--text-secondary)]'
                }`}
                dangerouslySetInnerHTML={{ __html: item.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>') }}
              />
            </div>
          ))}
        </div>
      ) : (
        <div className="px-3 pb-2.5">
          <p
            className={`text-[11px] leading-snug ${isDone ? 'text-[var(--text-muted)]' : 'text-[var(--text-secondary)]'}`}
            dangerouslySetInnerHTML={{
              __html: (todo.task.length > 80 ? todo.task.slice(0, 80) + '…' : todo.task)
                .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
            }}
          />
        </div>
      )}
    </div>
  )
}

function TodoDetailPopup({
  todo,
  onClose,
  messages: msgs,
  roomId: _roomId,
}: {
  todo: TodoItem
  onClose: () => void
  messages: Message[]
  roomId: string
}) {
  // ESC to close
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [onClose])

  // Find member result from messages
  const memberMsgs = msgs.filter(m => m.agent === todo.agent && (m.role === 'member' || m.role === 'artifact'))
  const latestResult = memberMsgs.length > 0 ? memberMsgs[memberMsgs.length - 1] : null

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"
      onClick={e => { if (e.target === e.currentTarget) onClose() }}
    >
      <div
        className="bg-[var(--bg-primary)] rounded-xl shadow-2xl flex flex-col overflow-hidden border border-[var(--border)]"
        style={{ width: '90vw', maxWidth: '700px', maxHeight: '80vh' }}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-3 border-b border-[var(--border)] bg-[var(--bg-secondary)] flex-shrink-0">
          <div className="flex items-center gap-2.5">
            <div className={`w-7 h-7 rounded-full flex items-center justify-center text-xs font-bold text-white flex-shrink-0 ${
              todo.status === 'done' ? 'bg-green-500' : todo.status === 'working' ? 'bg-[var(--accent)]' : 'bg-[var(--text-muted)]'
            }`}>
              {todo.agent.charAt(0)}
            </div>
            <span className="font-semibold text-sm">{todo.agent}</span>
            <StatusBadge status={todo.status} />
          </div>
          <button
            onClick={onClose}
            className="p-1.5 rounded-md text-[var(--text-muted)] hover:bg-[var(--bg-hover)] transition-colors"
          >
            <X className="w-4 h-4" />
          </button>
        </div>

        {/* Content */}
        <div className="flex-1 overflow-y-auto p-5 space-y-4">
          {/* Task description */}
          <div>
            <h4 className="text-xs font-semibold text-[var(--text-muted)] uppercase mb-2">任务</h4>
            <div className="prose prose-sm dark:prose-invert max-w-none bg-[var(--bg-secondary)] rounded-lg p-3 border border-[var(--border)]">
              <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>{todo.task}</ReactMarkdown>
            </div>
          </div>

          {/* Action status */}
          {todo.status === 'working' && todo.action && (
            <div className="flex items-center gap-2 text-sm text-[var(--accent)]">
              <Loader2 className="w-4 h-4 animate-spin" />
              <span>{todo.action}</span>
            </div>
          )}

          {/* Result */}
          {latestResult && (
            <div>
              <h4 className="text-xs font-semibold text-[var(--text-muted)] uppercase mb-2">结果</h4>
              <div className="prose prose-sm dark:prose-invert max-w-none bg-[var(--bg-secondary)] rounded-lg p-3 border border-[var(--border)]">
                <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>{latestResult.content}</ReactMarkdown>
              </div>
            </div>
          )}

          {todo.status !== 'done' && !latestResult && todo.status === 'assigned' && (
            <div className="text-center py-6 text-[var(--text-muted)]">
              <p className="text-xs">等待执行</p>
            </div>
          )}
        </div>
      </div>
    </div>
  )
}

export function RightSidebar() {
  const { activeRoomId, workspace, todoItems, messages, rooms } = useStore()
  const [previewFile, setPreviewFile] = useState<{ name: string; content: string; loading?: boolean } | null>(null)
  const [selectedTodo, setSelectedTodo] = useState<TodoItem | null>(null)
  const [copied, setCopied] = useState(false)
  const [versions, setVersions] = useState<{version: number, agent: string, created_at: string}[]>([])
  const [showVersions, setShowVersions] = useState(false)
  const [versionContent, setVersionContent] = useState<string | null>(null)
  const [selectedVersion, setSelectedVersion] = useState<number | null>(null)

  const files = activeRoomId ? (workspace[activeRoomId] || []) : []
  const todos = activeRoomId ? (todoItems[activeRoomId] || []) : []
  const room = rooms.find(r => r.id === activeRoomId)

  const openPreview = useCallback(async (filename: string) => {
    if (!activeRoomId) return
    // 先弹出 loading 状态，不阻塞 UI
    setPreviewFile({ name: filename, content: '', loading: true })
    try {
      const d = await fetch(`${API}/rooms/${activeRoomId}/workspace/${filename}`).then(r => r.json())
      setPreviewFile({ name: filename, content: d.content || '' })
    } catch {
      setPreviewFile({ name: filename, content: '加载失败' })
    }
  }, [activeRoomId])

  useEffect(() => {
    const handler = (e: Event) => {
      const detail = (e as CustomEvent).detail
      if (detail.roomId === activeRoomId && detail.filename) {
        openPreview(detail.filename)
      }
    }
    window.addEventListener('open-artifact', handler)
    return () => window.removeEventListener('open-artifact', handler)
  }, [activeRoomId, openPreview])

  useEffect(() => {
    if (!previewFile) return
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setPreviewFile(null)
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [previewFile])

  const copyContent = () => {
    if (!previewFile) return
    navigator.clipboard.writeText(previewFile.content)
    setCopied(true)
    setTimeout(() => setCopied(false), 2000)
  }

  if (!activeRoomId) {
    return (
      <div className="w-[260px] bg-[var(--bg-secondary)] border-l border-[var(--border)] flex flex-col">
        <div className="h-12 px-4 border-b border-[var(--border)] flex items-center">
          <span className="text-sm font-semibold text-[var(--text-muted)]">工作台</span>
        </div>
        <div className="flex-1 flex items-center justify-center text-[var(--text-muted)] text-xs">
          选择项目查看工作台
        </div>
      </div>
    )
  }

  const doneCount = todos.filter(t => t.status === 'done').length
  const progress = todos.length > 0 ? (doneCount / todos.length) * 100 : 0

  return (
    <>
      <div className="w-[260px] bg-[var(--bg-secondary)] border-l border-[var(--border)] flex flex-col overflow-hidden">
        {/* 任务区域 */}
        <div className="flex flex-col min-h-0" style={{ flex: todos.length > 0 ? '1 1 auto' : '0 0 auto' }}>
          <div className="h-12 px-4 border-b border-[var(--border)] flex items-center gap-2 flex-shrink-0">
            <span className="text-sm font-semibold text-[var(--text-primary)]">任务进度</span>
            {todos.length > 0 && (
              <span className="ml-auto text-[11px] font-mono text-[var(--text-muted)]">
                {doneCount}/{todos.length}
              </span>
            )}
          </div>

          {todos.length > 0 && (
            <>
              {/* 进度条 */}
              <div className="px-4 py-2.5 flex-shrink-0">
                <div className="h-1.5 rounded-full bg-[var(--bg-tertiary)] overflow-hidden">
                  <div
                    className="h-full rounded-full transition-all duration-500 ease-out"
                    style={{
                      width: `${progress}%`,
                      background: progress === 100
                        ? '#23A55A'
                        : 'var(--accent)',
                    }}
                  />
                </div>
              </div>

              {/* 任务卡片列表 */}
              <div className="flex-1 overflow-y-auto scrollbar-thin pb-2">
                {todos.map(todo => (
                  <TodoCard key={todo.id} todo={todo} onClick={() => setSelectedTodo(todo)} />
                ))}
              </div>
            </>
          )}

          {todos.length === 0 && (
            <div className="flex items-center justify-center py-8 text-[var(--text-muted)]">
              <div className="text-center">
                <div className="w-8 h-8 mx-auto mb-2 rounded-full bg-[var(--bg-tertiary)] flex items-center justify-center">
                  <svg className="w-4 h-4 opacity-40" viewBox="0 0 16 16" fill="none">
                    <path d="M2 4h12M2 8h12M2 12h8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
                  </svg>
                </div>
                <p className="text-xs opacity-60">等待任务分配</p>
              </div>
            </div>
          )}
        </div>

        {/* 产出物区域 */}
        <div className="flex-1 flex flex-col min-h-[120px] border-t border-[var(--border)]">
          <div className="h-10 px-4 border-b border-[var(--border)] flex items-center gap-2 flex-shrink-0">
            <FileText className="w-3.5 h-3.5 text-[var(--text-muted)]" />
            <span className="text-xs font-semibold text-[var(--text-muted)]">产出物</span>
            {files.length > 0 && (
              <span className="text-[10px] px-1.5 py-0.5 bg-[var(--bg-tertiary)] text-[var(--text-muted)] rounded-full">
                {files.length}
              </span>
            )}
          </div>

          {files.length > 0 ? (
            <div className="flex-1 overflow-y-auto scrollbar-thin">
              {files.map(f => (
                <button
                  key={f}
                  onClick={() => openPreview(f)}
                  className="w-full flex items-center gap-2 px-4 py-2 text-sm text-left hover:bg-[var(--bg-hover)] transition-colors"
                >
                  <FileText className="w-3.5 h-3.5 flex-shrink-0 text-[var(--accent)]" />
                  <span className="truncate text-xs text-[var(--text-secondary)]">{f}</span>
                </button>
              ))}
            </div>
          ) : (
            <div className="flex-1 flex items-center justify-center text-[var(--text-muted)]">
              <p className="text-xs opacity-60">暂无产出物</p>
            </div>
          )}
        </div>
      </div>

      {/* 预览弹窗 */}
      {previewFile && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"
          onClick={e => { if (e.target === e.currentTarget) setPreviewFile(null) }}
        >
          <div
            className="bg-[var(--bg-primary)] rounded-xl shadow-2xl flex flex-col overflow-hidden border border-[var(--border)]"
            style={{ width: '90vw', maxWidth: '900px', maxHeight: '85vh' }}
          >
            <div className="flex items-center justify-between px-6 py-3 border-b border-[var(--border)] bg-[var(--bg-secondary)] flex-shrink-0">
              <div className="flex items-center gap-2 min-w-0">
                <FileText className="w-4 h-4 text-[var(--accent)] flex-shrink-0" />
                <span className="font-medium text-sm truncate">{previewFile.name}</span>
              </div>
              <div className="flex items-center gap-2 flex-shrink-0">
                <button
                  onClick={copyContent}
                  className="flex items-center gap-1 px-2.5 py-1 rounded-md text-xs text-[var(--text-muted)] hover:bg-[var(--bg-hover)] transition-colors"
                >
                  {copied ? <Check className="w-3.5 h-3.5" /> : <Copy className="w-3.5 h-3.5" />}
                  {copied ? '已复制' : '复制'}
                </button>
                <button
                  onClick={async () => {
                    if (!activeRoomId || !previewFile) return
                    const res = await fetch(`${API}/rooms/${activeRoomId}/workspace/${encodeURIComponent(previewFile.name)}/versions`)
                    const data = await res.json()
                    setVersions(data || [])
                    setShowVersions(!showVersions)
                    setVersionContent(null)
                    setSelectedVersion(null)
                  }}
                  className="flex items-center gap-1 px-2.5 py-1 rounded-md text-xs text-[var(--text-muted)] hover:bg-[var(--bg-hover)] transition-colors"
                >
                  <Clock className="w-3.5 h-3.5" />
                  历史版本
                </button>
                <button
                  onClick={() => setPreviewFile(null)}
                  className="p-1.5 rounded-md text-[var(--text-muted)] hover:bg-[var(--bg-hover)] transition-colors"
                >
                  <X className="w-4 h-4" />
                </button>
              </div>
            </div>
            <div className="flex-1 overflow-y-auto flex min-h-0">
              {showVersions && versions.length > 0 && (
                <div className="w-48 border-r border-[var(--border)] overflow-y-auto flex-shrink-0">
                  <div className="p-2 space-y-1">
                    <button
                      onClick={() => { setVersionContent(null); setSelectedVersion(null) }}
                      className={`w-full text-left px-2 py-1.5 rounded text-xs transition-colors ${
                        selectedVersion === null ? 'bg-[var(--accent)]/15 text-[var(--accent)]' : 'hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]'
                      }`}
                    >
                      当前版本
                    </button>
                    {versions.map(v => (
                      <button
                        key={v.version}
                        onClick={async () => {
                          if (!activeRoomId || !previewFile) return
                          const res = await fetch(`${API}/rooms/${activeRoomId}/workspace/${encodeURIComponent(previewFile.name)}/versions/${v.version}`)
                          const data = await res.json()
                          setVersionContent(data.content || '')
                          setSelectedVersion(v.version)
                        }}
                        className={`w-full text-left px-2 py-1.5 rounded text-xs transition-colors ${
                          selectedVersion === v.version ? 'bg-[var(--accent)]/15 text-[var(--accent)]' : 'hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]'
                        }`}
                      >
                        <div className="font-medium">v{v.version}</div>
                        <div className="text-[10px] text-[var(--text-muted)]">{v.created_at}</div>
                        {v.agent && <div className="text-[10px] text-[var(--text-muted)]">{v.agent}</div>}
                      </button>
                    ))}
                  </div>
                </div>
              )}
              <div className="flex-1 mx-auto px-[20mm] py-[15mm] max-w-none" style={{ minHeight: '100%' }}>
                {previewFile.loading ? (
                  <div className="flex items-center justify-center py-20">
                    <Loader2 className="w-6 h-6 text-[var(--accent)] animate-spin" />
                  </div>
                ) : (
                  <div className="prose prose-sm dark:prose-invert max-w-none prose-headings:font-bold prose-h1:text-2xl prose-h1:border-b prose-h1:pb-2 prose-h1:mb-6 prose-h2:text-lg prose-h2:mt-6 prose-table:text-sm">
                    <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
                      {versionContent !== null ? versionContent : previewFile.content}
                    </ReactMarkdown>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
      )}

      {/* 任务详情弹窗 */}
      {selectedTodo && activeRoomId && (
        <TodoDetailPopup
          todo={todos.find(t => t.id === selectedTodo.id) || selectedTodo}
          onClose={() => setSelectedTodo(null)}
          messages={activeRoomId ? (messages[activeRoomId] || []) : []}
          roomId={activeRoomId}
        />
      )}
    </>
  )
}
