import { useMemo, useState, useRef, useEffect, type MouseEvent as ReactMouseEvent } from 'react'
import { saveCommand } from '../ipc'
import type { CommandItem, Config } from '../types'
import { writeToTerminal } from './TerminalView'
import { IconClose, IconInsert, IconPlus, IconSend, IconStar } from './Icons'

interface Props {
  config: Config
  projectPath: string
  tabId: string
  onConfigChange: (c: Config) => void
  /** 当前聚焦标签的提示队列（回合结束时自动逐条发送） */
  queue: string[]
  onQueueChange: (next: string[]) => void
}

/** 终端右侧的常用指令面板：已加星置顶分组，其余按分类分组；底部为提示队列 */
export function CommandDrawer({ config, projectPath, tabId, onConfigChange, queue, onQueueChange }: Props) {
  const [filter, setFilter] = useState('')
  const [categoryId, setCategoryId] = useState('')
  const [draft, setDraft] = useState('')
  const [queueOpen, setQueueOpen] = useState(true)
  const rootRef = useRef<HTMLDivElement>(null)
  // 指令侧栏宽度可拖拽，跨重启保留（localStorage）
  const [width, setWidth] = useState<number>(() => {
    const v = Number(localStorage.getItem('ccgui.drawerWidth'))
    return v >= 220 && v <= 560 ? v : 270
  })
  useEffect(() => {
    localStorage.setItem('ccgui.drawerWidth', String(width))
  }, [width])

  // 拖动左缘调整宽度：侧栏右缘固定贴窗口右侧，新宽度即右缘到指针的距离
  const startResize = (e: ReactMouseEvent) => {
    e.preventDefault()
    const onMove = (ev: MouseEvent) => {
      const right = rootRef.current?.getBoundingClientRect().right
      if (right === undefined) return
      setWidth(Math.min(560, Math.max(220, right - ev.clientX)))
    }
    const onUp = () => {
      window.removeEventListener('mousemove', onMove)
      window.removeEventListener('mouseup', onUp)
    }
    window.addEventListener('mousemove', onMove)
    window.addEventListener('mouseup', onUp)
  }

  const enqueue = () => {
    const text = draft.trim()
    if (!text) return
    onQueueChange([...queue, text])
    setDraft('')
  }

  const visible = useMemo(
    () =>
      config.commands.filter((c) => {
        if (c.projects && !c.projects.includes(projectPath)) return false
        if (categoryId && (c.categoryId ?? '') !== categoryId) return false
        if (filter) {
          const f = filter.toLowerCase()
          return c.name.toLowerCase().includes(f) || c.content.toLowerCase().includes(f)
        }
        return true
      }),
    [config.commands, projectPath, categoryId, filter]
  )

  const groups = useMemo(() => {
    const ordered: { name: string; items: CommandItem[] }[] = []
    // 已加星的归入置顶分组，不在原分类中重复出现
    const starred = visible.filter((c) => c.starred)
    if (starred.length > 0) ordered.push({ name: '已加星', items: starred })
    const rest = visible.filter((c) => !c.starred)
    const byCat = new Map<string, CommandItem[]>()
    for (const cmd of rest) {
      const key = cmd.categoryId ?? ''
      if (!byCat.has(key)) byCat.set(key, [])
      byCat.get(key)!.push(cmd)
    }
    for (const cat of config.commandCategories) {
      const items = byCat.get(cat.id)
      if (items?.length) ordered.push({ name: cat.name, items })
      byCat.delete(cat.id)
    }
    const uncategorized = byCat.get('')
    if (uncategorized?.length) ordered.push({ name: '未分类', items: uncategorized })
    return ordered
  }, [visible, config.commandCategories])

  const toggleStar = async (cmd: CommandItem) => {
    onConfigChange(await saveCommand({ ...cmd, starred: !cmd.starred }))
  }

  return (
    <div className="cmd-drawer" ref={rootRef} style={{ width }}>
      <div className="side-resizer left" onMouseDown={startResize} title="拖动调整指令侧栏宽度" />
      <div className="cmd-drawer-header">
        <select
          className="select"
          style={{ width: 92 }}
          value={categoryId}
          onChange={(e) => setCategoryId(e.target.value)}
        >
          <option value="">全部分类</option>
          {config.commandCategories.map((c) => (
            <option key={c.id} value={c.id}>
              {c.name}
            </option>
          ))}
        </select>
        <input
          className="input"
          style={{ flex: 1, minWidth: 0 }}
          placeholder="搜索指令"
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
        />
      </div>
      <div className="cmd-list">
        {groups.length === 0 && <div className="empty-hint">没有可用指令</div>}
        {groups.map((g) => (
          <div key={g.name}>
            <div className="cmd-group-title">{g.name}</div>
            {g.items.map((cmd) => (
              <div key={cmd.id} className="cmd-item" title={`${cmd.name}\n${cmd.content}`}>
                <span className="cmd-name">
                  {cmd.name.length > 14 ? `${cmd.name.slice(0, 14)}…` : cmd.name}
                </span>
                <button
                  className={`star-btn ghost ${cmd.starred ? 'on' : ''}`}
                  title={cmd.starred ? '取消加星' : '加星（置顶显示）'}
                  onClick={() => void toggleStar(cmd)}
                >
                  <IconStar width={12} height={12} fill={cmd.starred ? 'currentColor' : 'none'} />
                </button>
                <button
                  className="btn small icon-only"
                  title="填入输入框，可继续编辑"
                  onClick={() => writeToTerminal(tabId, cmd.content, false)}
                >
                  <IconInsert />
                </button>
                <button
                  className="btn small icon-only"
                  title="填入并立即发送"
                  onClick={() => writeToTerminal(tabId, cmd.content, true)}
                >
                  <IconSend />
                </button>
              </div>
            ))}
          </div>
        ))}
      </div>

      {/* 提示队列：回合结束（Stop hook）时自动发送下一条 */}
      <div className="queue-section">
        <div className="cmd-group-title queue-title" onClick={() => setQueueOpen((v) => !v)}>
          提示队列（{queue.length}）{queueOpen ? '' : ' · 已折叠'}
        </div>
        {queueOpen && (
          <>
            {queue.length > 0 && (
              <div className="queue-list">
                {queue.map((item, i) => (
                  <div key={i} className="queue-item" title={item}>
                    <span className="queue-index">{i + 1}</span>
                    <span className="queue-text">{item}</span>
                    <button
                      className="item-x"
                      style={{ visibility: 'visible' }}
                      title="移除"
                      onClick={() => onQueueChange(queue.filter((_, j) => j !== i))}
                    >
                      <IconClose width={10} height={10} />
                    </button>
                  </div>
                ))}
              </div>
            )}
            <textarea
              className="input"
              style={{ width: '100%', minHeight: 52, marginTop: 4 }}
              placeholder="排队的提示词，当前回合结束后自动发送"
              value={draft}
              onChange={(e) => setDraft(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter' && e.ctrlKey) {
                  e.preventDefault()
                  enqueue()
                }
              }}
            />
            <div style={{ display: 'flex', gap: 5, marginTop: 4 }}>
              <button className="btn small" disabled={!draft.trim()} onClick={enqueue}>
                <IconPlus />
                加入队列 (Ctrl+Enter)
              </button>
              <button
                className="btn small"
                disabled={queue.length === 0}
                title="不等回合结束，立即发送队列第一条"
                onClick={() => {
                  const [next, ...rest] = queue
                  onQueueChange(rest)
                  writeToTerminal(tabId, next, true)
                }}
              >
                <IconSend />
                立即发首条
              </button>
            </div>
            <div style={{ color: 'var(--text-faint)', fontSize: 11, marginTop: 4 }}>
              需登记 hooks（设置页）才能感知回合结束并自动发送
            </div>
          </>
        )}
      </div>
    </div>
  )
}
