import { useEffect, useState } from 'react';
import { Button, Card, List, Modal, Form, Input, Select, Tag, Space, Popconfirm, App as AntApp, Tooltip, Alert } from 'antd';
import { McpAPI, McpServer, McpStatus } from '../api';

interface Props {
  agentId: string;
}

const PRESETS: { label: string; description: string; config: any }[] = [
  {
    label: 'filesystem (官方 NPM)',
    description: '本地文件系统操作（读、列目录）。请把最后一个参数改成你要暴露给智能体的目录绝对路径。',
    config: {
      mcpServers: {
        filesystem: {
          command: 'npx',
          args: ['-y', '@modelcontextprotocol/server-filesystem', '/path/to/your/dir']
        }
      }
    }
  },
  {
    label: 'fetch (官方 NPM)',
    description: '抓取网页/URL 内容',
    config: {
      mcpServers: {
        fetch: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-fetch'] }
      }
    }
  },
  {
    label: 'sequential-thinking (官方 NPM)',
    description: '辅助思维链推理',
    config: {
      mcpServers: {
        'sequential-thinking': {
          command: 'npx',
          args: ['-y', '@modelcontextprotocol/server-sequential-thinking']
        }
      }
    }
  }
];

export default function McpPanel({ agentId }: Props) {
  const { message } = AntApp.useApp();
  const [servers, setServers] = useState<McpServer[]>([]);
  const [statusList, setStatusList] = useState<McpStatus[]>([]);
  const [statusLoading, setStatusLoading] = useState(false);
  const [editing, setEditing] = useState<McpServer | null>(null);
  const [createOpen, setCreateOpen] = useState(false);
  const [importOpen, setImportOpen] = useState(false);
  const [importJson, setImportJson] = useState('');

  const refresh = async () => {
    const list = await McpAPI.list(agentId);
    setServers(list);
  };

  const refreshStatus = async () => {
    setStatusLoading(true);
    try {
      const s = await McpAPI.status(agentId);
      setStatusList(s);
    } catch (e: any) {
      message.error('状态获取失败：' + (e?.message ?? e));
    } finally {
      setStatusLoading(false);
    }
  };

  useEffect(() => {
    refresh();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [agentId]);

  const handleSave = async (values: any) => {
    try {
      // args 字符串 → 数组
      let args: string[] = [];
      if (typeof values.argsText === 'string') {
        args = values.argsText
          .split(/\r?\n/)
          .map((s: string) => s.trim())
          .filter(Boolean);
      }
      let env: Record<string, string> = {};
      if (values.envText) {
        try {
          env = JSON.parse(values.envText);
        } catch {
          message.error('env 必须是合法 JSON 对象');
          return;
        }
      }
      const payload = {
        name: values.name,
        transport: values.transport,
        command: values.command || '',
        args,
        env,
        url: values.url || ''
      };
      if (editing) {
        await McpAPI.update(agentId, editing.id, payload);
        message.success('已更新');
      } else {
        await McpAPI.create(agentId, payload);
        message.success('已创建');
      }
      setEditing(null);
      setCreateOpen(false);
      refresh();
    } catch (e: any) {
      message.error('保存失败：' + (e?.message ?? e));
    }
  };

  const handleImport = async () => {
    let parsed: any;
    try {
      parsed = JSON.parse(importJson);
    } catch {
      message.error('JSON 解析失败');
      return;
    }
    try {
      const r = await McpAPI.importJSON(agentId, parsed, false);
      message.success(`已导入 ${r.imported} 个 MCP Server`);
      setImportOpen(false);
      setImportJson('');
      refresh();
    } catch (e: any) {
      message.error('导入失败：' + (e?.message ?? e));
    }
  };

  return (
    <Card
      title={
        <Space>
          <span>🔌 MCP Servers</span>
          <Tag>{servers.length} 个</Tag>
        </Space>
      }
      extra={
        <Space>
          <Button onClick={refreshStatus} loading={statusLoading}>
            🔄 刷新连接状态
          </Button>
          <Button onClick={() => setImportOpen(true)}>📥 导入 JSON</Button>
          <Button
            type="primary"
            onClick={() => {
              setEditing(null);
              setCreateOpen(true);
            }}
          >
            ➕ 新增
          </Button>
        </Space>
      }
    >
      <Alert
        style={{ marginBottom: 12 }}
        type="info"
        showIcon
        message="MCP (Model Context Protocol) 让智能体能调用外部工具。本机首次连接 stdio 类型会启动子进程，可能需要数秒。"
      />

      <List
        dataSource={servers}
        locale={{ emptyText: '尚未配置 MCP Server' }}
        renderItem={(s) => {
          const status = statusList.find((x) => x.id === s.id);
          return (
            <List.Item
              actions={[
                <Button
                  key="edit"
                  size="small"
                  onClick={() => {
                    setEditing(s);
                    setCreateOpen(true);
                  }}
                >
                  编辑
                </Button>,
                <Popconfirm
                  key="del"
                  title="确认删除该 MCP Server？"
                  onConfirm={async () => {
                    await McpAPI.remove(agentId, s.id);
                    message.success('已删除');
                    refresh();
                  }}
                >
                  <Button danger size="small">
                    删除
                  </Button>
                </Popconfirm>
              ]}
            >
              <List.Item.Meta
                title={
                  <Space>
                    <Tag color={s.transport === 'stdio' ? 'blue' : 'green'}>{s.transport}</Tag>
                    <span>{s.name}</span>
                    {!s.enabled && <Tag>已停用</Tag>}
                    {status?.error && (
                      <Tooltip title={status.error}>
                        <Tag color="error">连接失败</Tag>
                      </Tooltip>
                    )}
                    {status && !status.error && (
                      <Tag color="success">{status.toolCount} 工具就绪</Tag>
                    )}
                  </Space>
                }
                description={
                  <Space direction="vertical" size={2} style={{ width: '100%' }}>
                    <code style={{ fontSize: 12, color: '#6b7280' }}>
                      {s.transport === 'stdio'
                        ? `${s.command} ${s.args.join(' ')}`
                        : s.url}
                    </code>
                    {status?.tools && status.tools.length > 0 && (
                      <Space wrap size={4}>
                        {status.tools.slice(0, 8).map((t) => (
                          <Tooltip key={t.name} title={t.description}>
                            <Tag color="purple" style={{ fontSize: 11 }}>
                              {t.name}
                            </Tag>
                          </Tooltip>
                        ))}
                        {status.tools.length > 8 && <Tag>+{status.tools.length - 8}</Tag>}
                      </Space>
                    )}
                  </Space>
                }
              />
            </List.Item>
          );
        }}
      />

      <Modal
        open={createOpen}
        title={editing ? '编辑 MCP Server' : '新增 MCP Server'}
        width={680}
        onCancel={() => {
          setCreateOpen(false);
          setEditing(null);
        }}
        footer={null}
        destroyOnHidden
      >
        <McpForm
          initial={editing}
          onSubmit={handleSave}
          onCancel={() => {
            setCreateOpen(false);
            setEditing(null);
          }}
        />
      </Modal>

      <Modal
        open={importOpen}
        title="📥 导入 mcpServers JSON"
        width={760}
        onCancel={() => setImportOpen(false)}
        onOk={handleImport}
        okText="导入"
        cancelText="取消"
      >
        <Alert
          type="info"
          showIcon
          message="兼容 Claude Desktop / Cursor 的 mcpServers 配置格式。"
          style={{ marginBottom: 12 }}
        />
        <Space style={{ marginBottom: 8 }} wrap>
          {PRESETS.map((p) => (
            <Tooltip key={p.label} title={p.description}>
              <Button size="small" onClick={() => setImportJson(JSON.stringify(p.config, null, 2))}>
                {p.label}
              </Button>
            </Tooltip>
          ))}
        </Space>
        <Input.TextArea
          value={importJson}
          onChange={(e) => setImportJson(e.target.value)}
          placeholder={`{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
    }
  }
}`}
          autoSize={{ minRows: 12, maxRows: 20 }}
          style={{ fontFamily: 'Consolas, Menlo, monospace', fontSize: 13 }}
        />
      </Modal>
    </Card>
  );
}

function McpForm({
  initial,
  onSubmit,
  onCancel
}: {
  initial: McpServer | null;
  onSubmit: (values: any) => void;
  onCancel: () => void;
}) {
  const [form] = Form.useForm();
  const [transport, setTransport] = useState<'stdio' | 'sse' | 'http'>(initial?.transport ?? 'stdio');

  useEffect(() => {
    form.setFieldsValue({
      name: initial?.name ?? '',
      transport: initial?.transport ?? 'stdio',
      command: initial?.command ?? '',
      argsText: (initial?.args ?? []).join('\n'),
      envText: initial?.env ? JSON.stringify(initial.env, null, 2) : '',
      url: initial?.url ?? ''
    });
    setTransport(initial?.transport ?? 'stdio');
  }, [initial, form]);

  return (
    <Form form={form} layout="vertical" onFinish={onSubmit}>
      <Form.Item name="name" label="名称" rules={[{ required: true }]}>
        <Input placeholder="例如 filesystem / playwright" />
      </Form.Item>
      <Form.Item name="transport" label="Transport" rules={[{ required: true }]}>
        <Select
          options={[
            { value: 'stdio', label: 'stdio (本机进程)' },
            { value: 'sse', label: 'SSE (远程)' },
            { value: 'http', label: 'HTTP (Streamable)' }
          ]}
          onChange={(v) => setTransport(v as any)}
        />
      </Form.Item>

      {transport === 'stdio' ? (
        <>
          <Form.Item name="command" label="Command" rules={[{ required: true }]} extra="如 npx / node / python">
            <Input placeholder="npx" />
          </Form.Item>
          <Form.Item name="argsText" label="Args (每行一个)">
            <Input.TextArea
              autoSize={{ minRows: 3, maxRows: 8 }}
              placeholder={'-y\n@modelcontextprotocol/server-filesystem\n/path/to/dir'}
              style={{ fontFamily: 'Consolas, monospace', fontSize: 13 }}
            />
          </Form.Item>
          <Form.Item name="envText" label="Env (JSON 对象)">
            <Input.TextArea
              autoSize={{ minRows: 2, maxRows: 6 }}
              placeholder={'{ "API_KEY": "xxx" }'}
              style={{ fontFamily: 'Consolas, monospace', fontSize: 13 }}
            />
          </Form.Item>
        </>
      ) : (
        <Form.Item name="url" label="URL" rules={[{ required: true }]}>
          <Input placeholder="https://example.com/mcp" />
        </Form.Item>
      )}

      <Space style={{ justifyContent: 'flex-end', width: '100%' }}>
        <Button onClick={onCancel}>取消</Button>
        <Button type="primary" htmlType="submit">
          保存
        </Button>
      </Space>
    </Form>
  );
}
