/**
 * 项目 Claude 会话管理器（底部第三个 tab）。
 *
 * - 上方表单：选 profile（下拉，复用 useIssues 的 ClaudeProfile 列表）+ 首个提示词
 *   （可选，多行）+「创建」按钮 → 主进程开一个 cc 终端 tab 并捕获会话。
 * - 下方列表：每行显示名字（双击行内改名，Enter 提交、Esc 取消）、profile 文件名、
 *   创建时间；点击行（非编辑区）→ 主进程新终端 resume；行尾删除按钮（仅移除记录）。
 */

import type { ClaudeProfile } from '../hooks/useIssues'
import type { ManagedSession, ManagedSessionsData } from '../types'
import { Download, Plus, Terminal, Trash2, X } from 'lucide-react'
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'

interface ManagedSessionsPanelProps {
  data: ManagedSessionsData
  profiles: ClaudeProfile[]
  onCreate: (profilePath: string, name?: string, prompt?: string) => void
  onRename: (id: string, name: string) => void
  onResume: (id: string) => void
  onDelete: (id: string) => void
  onCloseTab: (id: string) => void
  importableSessions: Array<{ id: string, name: string, mtimeMs: number }>
  importableLoading: boolean
  onListImportable: () => void
  onImport: (sessionId: string, name: string) => void
}

function basename(p?: string): string {
  if (!p)
    return ''
  const idx = Math.max(p.lastIndexOf('/'), p.lastIndexOf('\\'))
  return idx >= 0 ? p.slice(idx + 1) : p
}

function formatTime(ts: number): string {
  if (!ts)
    return ''
  try {
    return new Date(ts).toLocaleString(undefined, {
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    })
  }
  catch {
    return ''
  }
}

export function ManagedSessionsPanel({
  data,
  profiles,
  onCreate,
  onRename,
  onResume,
  onDelete,
  onCloseTab,
  importableSessions,
  importableLoading,
  onListImportable,
  onImport,
}: ManagedSessionsPanelProps) {
  const [selectedProfile, setSelectedProfile] = useState<string>('')
  const [name, setName] = useState<string>('')
  const [prompt, setPrompt] = useState<string>('')
  const [importOpen, setImportOpen] = useState(false)
  const importWrapRef = useRef<HTMLDivElement | null>(null)

  // 默认选中官方 profile（profiles 异步到达后；用户手动改选后不覆盖）。
  useEffect(() => {
    if (selectedProfile || profiles.length === 0)
      return
    const official = profiles.find(p => p.name.toLowerCase() === 'offical')
    setSelectedProfile((official ?? profiles[0]).path)
  }, [profiles, selectedProfile])

  // 弹层：外点击 / Esc 关闭
  useEffect(() => {
    if (!importOpen)
      return
    function onKey(e: KeyboardEvent): void {
      if (e.key === 'Escape')
        setImportOpen(false)
    }
    function onPointer(e: MouseEvent): void {
      const el = importWrapRef.current
      if (!el)
        return
      if (e.target instanceof Node && !el.contains(e.target))
        setImportOpen(false)
    }
    window.addEventListener('keydown', onKey)
    window.addEventListener('mousedown', onPointer)
    return () => {
      window.removeEventListener('keydown', onKey)
      window.removeEventListener('mousedown', onPointer)
    }
  }, [importOpen])

  const sessions = useMemo(
    () => [...data.sessions].sort((a, b) => b.createdAt - a.createdAt),
    [data.sessions],
  )

  const canCreate = selectedProfile.trim() !== ''

  const handleCreate = useCallback((): void => {
    if (!canCreate)
      return
    const trimmedName = name.trim()
    const trimmedPrompt = prompt.trim()
    onCreate(selectedProfile, trimmedName || undefined, trimmedPrompt || undefined)
    setName('')
    setPrompt('')
  }, [canCreate, name, prompt, selectedProfile, onCreate])

  const openImport = useCallback((): void => {
    setImportOpen(true)
    onListImportable()
  }, [onListImportable])

  const pickImport = useCallback((sessionId: string, sessionName: string): void => {
    onImport(sessionId, sessionName)
    setImportOpen(false)
  }, [onImport])

  return (
    <div className="flex h-full w-full flex-col overflow-hidden bg-[var(--vscode-editor-background)] text-[var(--vscode-foreground)]">
      {/* 上方表单 */}
      <div className="shrink-0 border-b border-[var(--vscode-panel-border)] p-2">
        <div className="flex flex-col gap-2">
          <div className="flex items-center gap-2">
            <span className="w-12 shrink-0 text-xs text-[var(--vscode-descriptionForeground)]">Profile</span>
            <select
              value={selectedProfile}
              onChange={e => setSelectedProfile(e.target.value)}
              className="min-w-0 flex-1 rounded border border-[var(--vscode-input-border,var(--vscode-panel-border))] bg-[var(--vscode-input-background)] px-2 py-1 text-xs text-[var(--vscode-input-foreground)] outline-none focus:ring-1 focus:ring-inset focus:ring-[var(--vscode-focusBorder)]"
            >
              {profiles.length === 0 && (
                <option value="">（无可用 profile）</option>
              )}
              {profiles.map(p => (
                <option key={p.path} value={p.path}>{p.name}</option>
              ))}
            </select>
          </div>
          <div className="flex items-center gap-2">
            <span className="w-12 shrink-0 text-xs text-[var(--vscode-descriptionForeground)]">名字</span>
            <div className="relative min-w-0 flex-1" ref={importWrapRef}>
              <div className="flex items-center gap-1">
                <input
                  type="text"
                  value={name}
                  onChange={e => setName(e.target.value)}
                  placeholder="会话名字（可选）"
                  className="min-w-0 flex-1 rounded border border-[var(--vscode-input-border,var(--vscode-panel-border))] bg-[var(--vscode-input-background)] px-2 py-1 text-xs text-[var(--vscode-input-foreground)] outline-none placeholder:text-[var(--vscode-input-placeholderForeground)] focus:ring-1 focus:ring-inset focus:ring-[var(--vscode-focusBorder)]"
                />
                <button
                  type="button"
                  onClick={openImport}
                  title="导入已 /rename 的命名会话"
                  className="flex shrink-0 items-center gap-1 rounded border border-[var(--vscode-input-border,var(--vscode-panel-border))] bg-[var(--vscode-button-secondaryBackground,var(--vscode-input-background))] px-2 py-1 text-xs text-[var(--vscode-button-secondaryForeground,var(--vscode-foreground))] hover:bg-[var(--vscode-button-secondaryHoverBackground,var(--vscode-toolbar-hoverBackground))]"
                >
                  <Download className="size-3.5" />
                  <span>导入</span>
                </button>
              </div>
              {importOpen && (
                <div
                  className="absolute left-0 right-0 top-full z-20 mt-1 max-h-48 overflow-auto rounded border border-[var(--vscode-panel-border)] bg-[var(--vscode-editorWidget-background,var(--vscode-editor-background))] shadow-md"
                  role="listbox"
                  aria-label="可导入的命名会话"
                >
                  {importableLoading
                    ? (
                        <div className="px-2 py-3 text-center text-xs text-[var(--vscode-descriptionForeground)]">
                          加载中…
                        </div>
                      )
                    : importableSessions.length === 0
                      ? (
                          <div className="px-2 py-3 text-center text-xs text-[var(--vscode-descriptionForeground)]">
                            没有可导入的命名会话
                          </div>
                        )
                      : (
                          <ul className="flex flex-col py-1">
                            {importableSessions.map(s => (
                              <li key={s.id}>
                                <button
                                  type="button"
                                  role="option"
                                  onClick={() => pickImport(s.id, s.name)}
                                  className="flex w-full flex-col items-start gap-0.5 px-2 py-1.5 text-left hover:bg-[var(--vscode-list-hoverBackground)]"
                                >
                                  <span className="truncate text-xs">{s.name}</span>
                                  <span className="truncate text-[10px] text-[var(--vscode-descriptionForeground)]">
                                    {formatTime(s.mtimeMs)}
                                  </span>
                                </button>
                              </li>
                            ))}
                          </ul>
                        )}
                </div>
              )}
            </div>
          </div>
          <div className="flex items-start gap-2">
            <span className="w-12 shrink-0 pt-1 text-xs text-[var(--vscode-descriptionForeground)]">提示词</span>
            <textarea
              value={prompt}
              onChange={e => setPrompt(e.target.value)}
              placeholder="首个提示词（可选）"
              rows={2}
              className="min-w-0 flex-1 resize-y rounded border border-[var(--vscode-input-border,var(--vscode-panel-border))] bg-[var(--vscode-input-background)] px-2 py-1 text-xs text-[var(--vscode-input-foreground)] outline-none placeholder:text-[var(--vscode-input-placeholderForeground)] focus:ring-1 focus:ring-inset focus:ring-[var(--vscode-focusBorder)]"
            />
          </div>
          <div className="flex justify-end">
            <button
              type="button"
              onClick={handleCreate}
              disabled={!canCreate}
              className="flex items-center gap-1 rounded bg-[var(--vscode-button-background)] px-3 py-1 text-xs text-[var(--vscode-button-foreground)] hover:bg-[var(--vscode-button-hoverBackground)] disabled:cursor-not-allowed disabled:opacity-50"
            >
              <Plus className="size-3.5" />
              <span>创建</span>
            </button>
          </div>
        </div>
      </div>

      {/* 下方会话列表 */}
      <div className="min-h-0 flex-1 overflow-auto">
        {sessions.length === 0
          ? (
              <div className="flex h-full w-full items-center justify-center p-4 text-xs text-[var(--vscode-descriptionForeground)]">
                还没有会话，先在上方创建一个
              </div>
            )
          : (
              <ul className="flex flex-col">
                {sessions.map(s => (
                  <SessionRow
                    key={s.id}
                    session={s}
                    onRename={onRename}
                    onResume={onResume}
                    onDelete={onDelete}
                    onCloseTab={onCloseTab}
                  />
                ))}
              </ul>
            )}
      </div>
    </div>
  )
}

interface SessionRowProps {
  session: ManagedSession
  onRename: (id: string, name: string) => void
  onResume: (id: string) => void
  onDelete: (id: string) => void
  onCloseTab: (id: string) => void
}

function SessionRow({ session, onRename, onResume, onDelete, onCloseTab }: SessionRowProps) {
  const [editing, setEditing] = useState(false)
  const [draft, setDraft] = useState(session.name)
  const inputRef = useRef<HTMLInputElement | null>(null)

  useLayoutEffect(() => {
    if (!editing)
      return
    const el = inputRef.current
    if (!el)
      return
    el.focus()
    el.select()
  }, [editing])

  const beginEdit = useCallback((): void => {
    setDraft(session.name)
    setEditing(true)
  }, [session.name])

  const commit = useCallback((): void => {
    const trimmed = draft.trim()
    if (trimmed && trimmed !== session.name)
      onRename(session.id, trimmed)
    setEditing(false)
  }, [draft, session.id, session.name, onRename])

  const cancel = useCallback((): void => {
    setEditing(false)
    setDraft(session.name)
  }, [session.name])

  const profileName = basename(session.profilePath)
  const created = formatTime(session.createdAt)

  return (
    <li
      className="group flex items-center gap-2 border-b border-[var(--vscode-panel-border)] px-2 py-1.5 hover:bg-[var(--vscode-list-hoverBackground)]"
    >
      <button
        type="button"
        onClick={() => onResume(session.id)}
        title="点击恢复会话（新终端 resume）"
        className="grid size-6 shrink-0 place-items-center rounded text-[var(--vscode-descriptionForeground)] hover:bg-[var(--vscode-toolbar-hoverBackground,var(--vscode-list-hoverBackground))] hover:text-[var(--vscode-foreground)]"
        aria-label="恢复会话"
      >
        <Terminal className="size-3.5" />
      </button>

      <div
        className="min-w-0 flex-1 cursor-pointer"
        onClick={() => {
          if (!editing)
            onResume(session.id)
        }}
      >
        {editing
          ? (
              <input
                ref={inputRef}
                type="text"
                value={draft}
                onChange={e => setDraft(e.target.value)}
                onClick={e => e.stopPropagation()}
                onBlur={commit}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    e.preventDefault()
                    commit()
                  }
                  else if (e.key === 'Escape') {
                    e.preventDefault()
                    cancel()
                  }
                }}
                className="w-full bg-transparent px-0 py-0 text-xs text-[var(--vscode-input-foreground)] outline-none focus:ring-1 focus:ring-inset focus:ring-[var(--vscode-focusBorder)]"
              />
            )
          : (
              <div className="flex min-w-0 flex-col">
                <span
                  className="truncate text-xs"
                  onDoubleClick={(e) => {
                    e.stopPropagation()
                    beginEdit()
                  }}
                  title="双击改名"
                >
                  {session.name || <span className="opacity-40">(未命名)</span>}
                </span>
                <span className="truncate text-[10px] text-[var(--vscode-descriptionForeground)]">
                  {[profileName, created].filter(Boolean).join(' · ')}
                </span>
              </div>
            )}
      </div>

      {session.tabOpen && (
        <button
          type="button"
          onClick={(e) => {
            e.stopPropagation()
            onCloseTab(session.id)
          }}
          title="关闭会话 tab"
          aria-label="关闭会话 tab"
          className="grid size-6 shrink-0 place-items-center rounded text-[var(--vscode-descriptionForeground)] opacity-70 transition-opacity hover:bg-[var(--vscode-toolbar-hoverBackground,var(--vscode-list-hoverBackground))] hover:text-[var(--vscode-foreground)]"
        >
          <X className="size-3.5" />
        </button>
      )}

      <button
        type="button"
        onClick={(e) => {
          e.stopPropagation()
          onDelete(session.id)
        }}
        title="从列表移除（不删 jsonl）"
        aria-label="从列表移除"
        className="grid size-6 shrink-0 place-items-center rounded text-[var(--vscode-descriptionForeground)] opacity-0 transition-opacity hover:bg-[var(--vscode-toolbar-hoverBackground,var(--vscode-list-hoverBackground))] hover:text-state-red group-hover:opacity-70"
      >
        <Trash2 className="size-3.5" />
      </button>
    </li>
  )
}
