import { useCallback, useEffect, useState } from 'react'
import { mcpDelete, mcpList, mcpSave } from '../ipc'
import type { Config, McpServers } from '../types'
import { ConfirmDialog, Modal } from './Modal'
import { IconEdit, IconPlus, IconTrash } from './Icons'

type Scope = 'global' | 'project'

interface Props {
  config: Config
}

const STDIO_TEMPLATE = `{
  "command": "npx",
  "args": ["-y", "@some/mcp-server"],
  "env": {}
}`

/** 单个服务器条目的一行摘要：stdio 显示命令，http/sse 显示地址 */
function summarize(value: unknown): string {
  if (!value || typeof value !== 'object') return ''
  const v = value as Record<string, unknown>
  if (typeof v.url === 'string') return `${(v.type as string) ?? 'http'} · ${v.url}`
  const cmd = typeof v.command === 'string' ? v.command : ''
  const args = Array.isArray(v.args) ? (v.args as unknown[]).join(' ') : ''
  return `stdio · ${cmd} ${args}`.trim()
}

interface EditState {
  scope: Scope
  name: string
  json: string
  isNew: boolean
}

/** MCP 服务器管理：全局（~/.claude.json）与项目（.mcp.json）两个作用域的增删改 */
export function McpPage({ config }: Props) {
  const [projectPath, setProjectPath] = useState(config.projects[0]?.path ?? '')
  const [servers, setServers] = useState<McpServers | null>(null)
  const [editing, setEditing] = useState<EditState | null>(null)
  const [deleting, setDeleting] = useState<{ scope: Scope; name: string } | null>(null)
  const [error, setError] = useState('')

  const refresh = useCallback(async () => {
    setServers(await mcpList(projectPath || null))
  }, [projectPath])

  useEffect(() => {
    void refresh()
  }, [refresh])

  const save = async (state: EditState) => {
    setError('')
    try {
      await mcpSave(state.scope, state.scope === 'project' ? projectPath : null, state.name, state.json)
      setEditing(null)
      await refresh()
    } catch (e) {
      setError(String(e))
    }
  }

  const renderSection = (scope: Scope, title: string, desc: string, map: Record<string, unknown>) => (
    <div style={{ marginBottom: 22 }}>
      <div className="toolbar" style={{ marginBottom: 8 }}>
        <div>
          <div style={{ fontWeight: 600 }}>{title}</div>
          <div style={{ color: 'var(--text-dim)', fontSize: 12 }}>{desc}</div>
        </div>
        <div className="spacer" />
        {scope === 'project' && (
          <select className="select" value={projectPath} onChange={(e) => setProjectPath(e.target.value)}>
            {config.projects.map((p) => (
              <option key={p.path} value={p.path}>
                {p.name}
              </option>
            ))}
          </select>
        )}
        <button
          className="btn primary"
          disabled={scope === 'project' && !projectPath}
          onClick={() => setEditing({ scope, name: '', json: STDIO_TEMPLATE, isNew: true })}
        >
          <IconPlus />
          添加
        </button>
      </div>
      <div className="row-list">
        {Object.keys(map).length === 0 && <div className="empty-hint">没有配置的服务器</div>}
        {Object.entries(map).map(([name, value]) => (
          <div key={name} className="row">
            <div className="row-main">
              <div className="row-title">{name}</div>
              <div className="row-sub" style={{ fontFamily: 'var(--font-mono)' }}>
                {summarize(value)}
              </div>
            </div>
            <div className="row-actions">
              <button
                className="btn small"
                title="编辑"
                onClick={() =>
                  setEditing({
                    scope,
                    name,
                    json: JSON.stringify(value, null, 2),
                    isNew: false
                  })
                }
              >
                <IconEdit />
              </button>
              <button className="btn small danger" title="删除" onClick={() => setDeleting({ scope, name })}>
                <IconTrash />
              </button>
            </div>
          </div>
        ))}
      </div>
    </div>
  )

  return (
    <div className="page">
      <h2>MCP 服务器</h2>
      <p className="page-desc">管理 Claude Code 的 MCP 服务器配置。改动对新开的会话生效。</p>
      {error && <div style={{ color: 'var(--danger)', marginBottom: 10 }}>{error}</div>}
      {servers && renderSection('global', '全局', '~/.claude.json · 所有项目可用', servers.global)}
      {servers &&
        renderSection(
          'project',
          '项目',
          `${projectPath || '（无项目）'}\\.mcp.json · 可随仓库提交共享`,
          servers.project
        )}

      {editing && (
        <Modal
          title={editing.isNew ? '添加 MCP 服务器' : `编辑：${editing.name}`}
          width={560}
          onClose={() => setEditing(null)}
          footer={
            <>
              <button className="btn" onClick={() => setEditing(null)}>
                取消
              </button>
              <button
                className="btn primary"
                disabled={!editing.name.trim()}
                onClick={() => void save(editing)}
              >
                保存
              </button>
            </>
          }
        >
          <label className="label">名称</label>
          <input
            className="input"
            style={{ width: '100%' }}
            value={editing.name}
            disabled={!editing.isNew}
            autoFocus={editing.isNew}
            onChange={(e) => setEditing({ ...editing, name: e.target.value })}
          />
          <label className="label">
            服务器配置（JSON：stdio 用 command/args/env，远程用 type/url/headers）
          </label>
          <textarea
            className="input"
            style={{ width: '100%', minHeight: 180 }}
            value={editing.json}
            onChange={(e) => setEditing({ ...editing, json: e.target.value })}
          />
        </Modal>
      )}

      {deleting && (
        <ConfirmDialog
          title="删除 MCP 服务器"
          message={`确定从${deleting.scope === 'global' ? '全局' : '项目'}配置中删除「${deleting.name}」？`}
          confirmText="删除"
          danger
          onCancel={() => setDeleting(null)}
          onConfirm={async () => {
            await mcpDelete(deleting.scope, deleting.scope === 'project' ? projectPath : null, deleting.name)
            setDeleting(null)
            await refresh()
          }}
        />
      )}
    </div>
  )
}
