import { useState } from 'react'
import { Brain, User, Library, History, Cpu, Globe, Star, Package, RefreshCw, X, ChevronDown, ChevronRight, Plus, Pencil, Trash2, Check } from 'lucide-react'
import type { MemorySummary, Command } from '../../types/protocol'

/* ── types ────────────────────────────────────────────── */

interface MemoryPanelProps {
  memories: MemorySummary[]
  onRefresh: () => void
  onClose?: () => void
  onCreateMemory: (ns: string, key: string, content: string) => Command
  onUpdateMemory: (id: string, content: string) => Command
  onDeleteMemory: (id: string) => Command
  sendCommand: (cmd: Command) => void
}

interface NamespaceConfig { label: string; icon: typeof Brain; accent: string; accentBorder: string }

const NS: Record<string, NamespaceConfig> = {
  user:        { label: '用户记忆', icon: User,    accent: 'text-cyan-400',   accentBorder: 'border-cyan-400/40' },
  semantic:    { label: '语义记忆', icon: Library,  accent: 'text-amber-400',  accentBorder: 'border-amber-400/40' },
  episodic:    { label: '情景记忆', icon: History,  accent: 'text-purple-400', accentBorder: 'border-purple-400/40' },
  skill:       { label: '技能记忆', icon: Cpu,      accent: 'text-green-400',  accentBorder: 'border-green-400/40' },
  environment: { label: '环境记忆', icon: Globe,    accent: 'text-sky-400',    accentBorder: 'border-sky-400/40' },
  reflection:  { label: '反思记忆', icon: Star,     accent: 'text-rose-400',   accentBorder: 'border-rose-400/40' },
  other:       { label: '其他',     icon: Package,  accent: 'text-stone-400',  accentBorder: 'border-stone-400/40' },
}

function cfg(ns: string): NamespaceConfig {
  return NS[ns] ?? { label: ns, icon: Package, accent: 'text-[var(--text-secondary)]', accentBorder: 'border-[var(--border-color)]' }
}

function fmtKey(k: string) { return k.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()) }

const NS_OPTIONS = Object.entries(NS)

/* ── Memory card with edit/delete ──────────────────────── */

function MemoryCard({ memory, config, onUpdate, onDelete }:
  { memory: MemorySummary; config: NamespaceConfig; onUpdate: (id: string, content: string) => void; onDelete: (id: string) => void }) {

  const [editing, setEditing] = useState(false)
  const [editContent, setEditContent] = useState(memory.content)
  const [confirmDelete, setConfirmDelete] = useState(false)

  const handleSave = () => {
    if (editContent.trim() && editContent !== memory.content) {
      onUpdate(memory.id, editContent.trim())
    }
    setEditing(false)
  }

  const handleDelete = () => {
    if (confirmDelete) {
      onDelete(memory.id)
    } else {
      setConfirmDelete(true)
      setTimeout(() => setConfirmDelete(false), 3000)
    }
  }

  return (
    <div className={`group rounded-lg bg-[var(--overlay-hover)] border-l-2 ${config.accentBorder} border border-[var(--border-color)] overflow-hidden transition-all duration-200 hover:border-[var(--border-accent)]`}>
      <div className="px-3 py-2.5">
        {/* header row */}
        <div className="flex items-center justify-between mb-0.5">
          <span className={`text-[10px] font-mono uppercase tracking-wider ${config.accent} opacity-60`}>
            {fmtKey(memory.memory_key)}
          </span>
          {/* action buttons — visible on hover */}
          <div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
            <button onClick={() => { setEditing(!editing); setEditContent(memory.content) }}
              className={`p-1 rounded hover:bg-[var(--overlay-subtle)] ${editing ? 'text-[var(--accent-cyan)]' : 'text-[var(--text-muted)]'} hover:text-[var(--accent-cyan)] transition-colors`} title="编辑">
              <Pencil className="h-3 w-3" />
            </button>
            <button onClick={handleDelete}
              className={`p-1 rounded hover:bg-red-500/10 ${confirmDelete ? 'text-red-400' : 'text-[var(--text-muted)]'} hover:text-red-400 transition-colors`} title={confirmDelete ? '再次点击确认删除' : '删除'}>
              <Trash2 className="h-3 w-3" />
            </button>
          </div>
        </div>

        {/* content */}
        {editing ? (
          <div className="flex gap-1.5 mt-1">
            <textarea value={editContent} onChange={e => setEditContent(e.target.value)}
              className="flex-1 text-sm bg-[var(--bg-tertiary)] border border-[var(--border-color)] rounded-lg px-2 py-1.5 text-[var(--text-primary)] resize-none focus:outline-none focus:border-[var(--accent-cyan)] min-h-[120px]"
              autoFocus onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSave() } }} />
            <button onClick={handleSave}
              className="shrink-0 p-1.5 rounded-lg bg-[var(--accent-cyan)]/10 text-[var(--accent-cyan)] hover:bg-[var(--accent-cyan)]/20 transition-colors" title="保存">
              <Check className="h-3.5 w-3.5" />
            </button>
          </div>
        ) : (
          <p className="text-sm text-[var(--text-secondary)] leading-relaxed">{memory.content}</p>
        )}
      </div>
    </div>
  )
}

/* ── Add memory form ───────────────────────────────────── */

function AddMemoryForm({ onAdd, onCancel }: { onAdd: (ns: string, key: string, content: string) => void; onCancel: () => void }) {
  const [ns, setNs] = useState('user')
  const [key, setKey] = useState('')
  const [content, setContent] = useState('')

  const handleSubmit = () => {
    if (!key.trim() || !content.trim()) return
    onAdd(ns, key.trim(), content.trim())
  }

  return (
    <div className="rounded-xl border border-[var(--border-accent)] bg-[var(--bg-tertiary)]/80 p-3 space-y-2.5 animate-fade-in">
      <div className="flex gap-2">
        <select value={ns} onChange={e => setNs(e.target.value)}
          className="text-xs bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg px-2 py-1.5 text-[var(--text-primary)]">
          {NS_OPTIONS.map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
        </select>
        <input value={key} onChange={e => setKey(e.target.value)} placeholder="键名 (如 work_preference)"
          className="flex-1 text-xs bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg px-2 py-1.5 text-[var(--text-primary)] placeholder:text-[var(--text-muted)]" />
      </div>
      <textarea value={content} onChange={e => setContent(e.target.value)} placeholder="内容..."
        className="w-full text-sm bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg px-2.5 py-2 text-[var(--text-primary)] placeholder:text-[var(--text-muted)] resize-none min-h-[120px]"
        autoFocus onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSubmit() } }} />
      <div className="flex justify-end gap-1.5">
        <button onClick={onCancel} className="px-3 py-1 rounded-lg text-xs text-[var(--text-muted)] hover:bg-[var(--overlay-hover)] transition-colors">取消</button>
        <button onClick={handleSubmit} disabled={!key.trim() || !content.trim()}
          className="px-3 py-1 rounded-lg text-xs bg-[var(--accent-cyan)]/10 text-[var(--accent-cyan)] hover:bg-[var(--accent-cyan)]/20 transition-colors disabled:opacity-40 disabled:cursor-not-allowed">创建</button>
      </div>
    </div>
  )
}

/* ── Section header ────────────────────────────────────── */

function SectionHeader({ config, count, isCollapsed, onClick }:
  { config: NamespaceConfig; count: number; isCollapsed: boolean; onClick: () => void }) {
  const Icon = config.icon
  return (
    <button onClick={onClick} className="sticky top-0 z-10 group flex items-center gap-2 w-full py-1.5 rounded-lg transition-colors hover:bg-[var(--overlay-hover)] bg-[var(--bg-secondary)]/90 backdrop-blur-sm -mx-3 px-3">
      {isCollapsed ? <ChevronRight className="h-3 w-3 text-[var(--text-muted)]" /> : <ChevronDown className="h-3 w-3 text-[var(--text-muted)]" />}
      <div className={`flex items-center justify-center w-5 h-5 rounded-md bg-[var(--overlay-hover)] ${config.accent}`}>
        <Icon className="h-3 w-3" />
      </div>
      <span className="text-xs font-semibold text-[var(--text-primary)] tracking-tight">{config.label}</span>
      <span className="text-[10px] text-[var(--text-muted)] font-mono tabular-nums ml-auto">{count}</span>
    </button>
  )
}

/* ── main component ────────────────────────────────────── */

export function MemoryPanel({ memories, onRefresh, onClose, onCreateMemory, onUpdateMemory, onDeleteMemory, sendCommand }: MemoryPanelProps) {
  const [collapsed, setCollapsed] = useState<Set<string>>(() => {
    try { const s = localStorage.getItem('picobot-memory-collapsed'); return s ? new Set(JSON.parse(s)) : new Set() }
    catch (_) { return new Set() }
  })
  const [showAddForm, setShowAddForm] = useState(false)

  const toggle = (ns: string) => {
    setCollapsed(prev => {
      const next = new Set(prev)
      if (next.has(ns)) { next.delete(ns) } else { next.add(ns) }
      localStorage.setItem('picobot-memory-collapsed', JSON.stringify([...next]))
      return next
    })
  }

  const grouped = new Map<string, MemorySummary[]>()
  for (const m of memories) { const l = grouped.get(m.namespace) || []; l.push(m); grouped.set(m.namespace, l) }

  const order = ['user', 'semantic', 'episodic', 'skill', 'environment', 'reflection', 'other']
  const sorted = Array.from(grouped.keys()).sort((a, b) => {
    const ai = order.indexOf(a); const bi = order.indexOf(b)
    if (ai !== -1 && bi !== -1) return ai - bi
    if (ai !== -1) return -1; if (bi !== -1) return 1
    return a.localeCompare(b)
  })

  const handleCreate = (ns: string, key: string, content: string) => {
    sendCommand(onCreateMemory(ns, key, content))
    setShowAddForm(false)
  }
  const handleUpdate = (id: string, content: string) => { sendCommand(onUpdateMemory(id, content)) }
  const handleDelete = (id: string) => { sendCommand(onDeleteMemory(id)) }

  return (
    <div className="flex h-full flex-col">
      {/* title bar */}
      <div className="shrink-0 border-b border-[var(--border-color)] px-4 py-3 flex items-center gap-2.5">
        <div className="flex items-center justify-center w-6 h-6 rounded-lg bg-[var(--accent-cyan)]/10">
          <Brain className="h-3.5 w-3.5 text-[var(--accent-cyan)]" />
        </div>
        <span className="text-sm font-bold text-[var(--text-primary)] tracking-tight">记忆</span>
        {memories.length > 0 && <span className="text-[11px] font-mono text-[var(--text-muted)] tabular-nums ml-0.5">{memories.length}</span>}
        <div className="ml-auto flex items-center gap-0.5">
          <button onClick={() => setShowAddForm(!showAddForm)} className={`p-1.5 rounded-lg transition-colors ${showAddForm ? 'bg-[var(--accent-cyan)]/10 text-[var(--accent-cyan)]' : 'text-[var(--text-muted)] hover:bg-[var(--overlay-hover)] hover:text-[var(--accent-cyan)]'}`} title="新增记忆">
            <Plus className="h-3.5 w-3.5" />
          </button>
          <button onClick={onRefresh} className="p-1.5 rounded-lg hover:bg-[var(--overlay-hover)] text-[var(--text-muted)] hover:text-[var(--accent-cyan)] transition-colors" title="刷新">
            <RefreshCw className="h-3.5 w-3.5" />
          </button>
          {onClose && <button onClick={onClose} className="p-1.5 rounded-lg hover:bg-[var(--overlay-hover)] text-[var(--text-muted)] hover:text-[var(--text-secondary)] transition-colors" title="收起"><X className="h-3.5 w-3.5" /></button>}
        </div>
      </div>

      {/* add form */}
      {showAddForm && <div className="px-3 pt-2"><AddMemoryForm onAdd={handleCreate} onCancel={() => setShowAddForm(false)} /></div>}

      {/* empty */}
      {memories.length === 0 && !showAddForm && (
        <div className="flex flex-1 items-center justify-center p-8">
          <div className="text-center select-none">
            <div className="relative inline-block mb-5">
              <div className="absolute inset-0 rounded-full bg-[var(--accent-cyan)]/10 blur-xl animate-pulse" />
              <Brain className="relative h-12 w-12 text-[var(--accent-cyan)]/25" />
            </div>
            <p className="text-sm text-[var(--text-muted)] leading-relaxed">PicoBot 会在对话中<br />自动学习并记录关于你的信息</p>
          </div>
        </div>
      )}

      {/* list */}
      {memories.length > 0 && (
        <div className="flex-1 overflow-y-auto px-3 pt-0 pb-2 space-y-3">
          {sorted.map(ns => {
            const c = cfg(ns)
            const items = grouped.get(ns)!
            const closed = collapsed.has(ns)
            return (
              <div key={ns}>
                <SectionHeader config={c} count={items.length} isCollapsed={closed} onClick={() => toggle(ns)} />
                {!closed && (
                  <div className="mt-1.5 space-y-1.5">
                    {items.map(m => <MemoryCard key={m.id} memory={m} config={c} onUpdate={handleUpdate} onDelete={handleDelete} />)}
                  </div>
                )}
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}
