import { useEffect, useMemo, useState } from 'react'
import {
  Alert,
  Button,
  Card,
  Col,
  Descriptions,
  Empty,
  Input,
  List,
  Row,
  Space,
  Spin,
  Statistic,
  Tag,
  Typography,
  message,
} from 'antd'
import { mcpApi } from '@/lib/api'
import type { JsonSchema, McpContent, McpManagedStatus, McpServerConfig, McpToolDescriptor } from '@/types/system'

const { TextArea } = Input

function statusColor(state?: string) {
  switch (state) {
    case 'running':
      return 'green'
    case 'starting':
      return 'orange'
    case 'external':
      return 'blue'
    default:
      return 'default'
  }
}

function asSchemaRecord(value: unknown): Record<string, unknown> {
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    return {}
  }
  return value as Record<string, unknown>
}

function buildExampleValue(schema?: JsonSchema | Record<string, unknown> | unknown): unknown {
  const current = asSchemaRecord(schema)
  if ('default' in current) {
    return current.default
  }

  const enumValues = Array.isArray(current.enum) ? current.enum : []
  if (enumValues.length > 0) {
    return enumValues[0]
  }

  const schemaType = typeof current.type === 'string' ? current.type : ''
  switch (schemaType) {
    case 'string':
      return ''
    case 'number':
    case 'integer':
      return 0
    case 'boolean':
      return false
    case 'array':
      return current.items ? [buildExampleValue(current.items)] : []
    case 'object':
      break
    default:
      if (!current.properties) {
        return {}
      }
  }

  const properties = asSchemaRecord(current.properties)
  const result: Record<string, unknown> = {}
  for (const [key, value] of Object.entries(properties)) {
    result[key] = buildExampleValue(value)
  }
  return result
}

function buildExampleArguments(tool?: McpToolDescriptor | null) {
  if (!tool?.inputSchema) {
    return '{}'
  }

  return JSON.stringify(buildExampleValue(tool.inputSchema), null, 2)
}

function renderContent(content: McpContent, index: number) {
  if (content.type === 'image' && content.data) {
    const mimeType = content.mimeType || 'image/png'
    return (
      <Card key={`content-${index}`} type="inner" title={`结果 ${index + 1} · image`}>
        <img
          alt={`mcp-result-${index + 1}`}
          src={`data:${mimeType};base64,${content.data}`}
          style={{ maxWidth: '100%', borderRadius: 12 }}
        />
      </Card>
    )
  }

  return (
    <Card key={`content-${index}`} type="inner" title={`结果 ${index + 1} · ${content.type || 'unknown'}`}>
      <pre style={{ margin: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
        {content.text || JSON.stringify(content, null, 2)}
      </pre>
    </Card>
  )
}

export function McpTestPage() {
  const [status, setStatus] = useState<McpManagedStatus | null>(null)
  const [serverConfig, setServerConfig] = useState<McpServerConfig | null>(null)
  const [tools, setTools] = useState<McpToolDescriptor[]>([])
  const [selectedToolName, setSelectedToolName] = useState('')
  const [argumentsText, setArgumentsText] = useState('{}')
  const [result, setResult] = useState<McpContent[]>([])
  const [loading, setLoading] = useState(true)
  const [actionLoading, setActionLoading] = useState(false)
  const [calling, setCalling] = useState(false)

  const selectedTool = useMemo(
    () => tools.find((item) => item.name === selectedToolName) || null,
    [selectedToolName, tools],
  )

  const reload = async () => {
    setLoading(true)
    try {
      const statusRes = await mcpApi.getStatus()
      setStatus(statusRes.data.status)
      setServerConfig(statusRes.data.mcpServerConfig)

      if (!statusRes.data.status.reachable) {
        setTools([])
        return
      }

      const listRes = await mcpApi.getList()
      const nextTools = listRes.data.list?.tools || []
      setStatus(listRes.data.status)
      setServerConfig(listRes.data.mcpServerConfig)
      setTools(nextTools)
      if (nextTools.length > 0) {
        setSelectedToolName((current) =>
          nextTools.some((item) => item.name === current) ? current : nextTools[0].name,
        )
      }
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    reload()
  }, [])

  useEffect(() => {
    setArgumentsText(buildExampleArguments(selectedTool))
  }, [selectedTool])

  const runAction = async (action: 'start' | 'stop') => {
    setActionLoading(true)
    try {
      if (action === 'start') {
        await mcpApi.start()
        message.success('MCP 独立服务已启动')
      } else {
        await mcpApi.stop()
        message.success('MCP 独立服务已停用')
        setResult([])
      }
      await reload()
    } finally {
      setActionLoading(false)
    }
  }

  const callTool = async () => {
    if (!selectedToolName) {
      message.warning('请先选择一个工具')
      return
    }

    let parsedArguments: Record<string, unknown> = {}
    try {
      parsedArguments = JSON.parse(argumentsText || '{}') as Record<string, unknown>
    } catch {
      message.error('参数 JSON 解析失败，请先修正格式')
      return
    }

    setCalling(true)
    try {
      const response = await mcpApi.test({
        name: selectedToolName,
        arguments: parsedArguments,
      })
      setResult(response.data)
      message.success('工具调用成功')
    } finally {
      setCalling(false)
    }
  }

  const activeServer = useMemo(() => {
    if (!serverConfig?.mcpServers) {
      return null
    }
    const [serverName, serverValue] = Object.entries(serverConfig.mcpServers)[0] || []
    if (!serverName || !serverValue) {
      return null
    }
    return {
      serverName,
      ...serverValue,
    }
  }, [serverConfig])

  return (
    <div className="page-stack">
      <Card className="glass-panel page-panel">
        <div className="section-heading">
          <div>
            <Typography.Title level={2} style={{ marginBottom: 8 }}>
              MCP Tools 管理
            </Typography.Title>
            <Typography.Paragraph className="text-muted" style={{ marginBottom: 0 }}>
              当前页直接管理 MCP 独立服务，并可在登录态下调用工具验证新项目接入是否正常。
            </Typography.Paragraph>
          </div>
          <Space>
            <Button onClick={reload} loading={loading}>
              刷新状态
            </Button>
            <Button type="primary" onClick={() => runAction('start')} loading={actionLoading}>
              启动服务
            </Button>
            <Button danger onClick={() => runAction('stop')} loading={actionLoading}>
              停用服务
            </Button>
          </Space>
        </div>
        {status?.lastError ? (
          <Alert
            type="warning"
            showIcon
            message={status.message || 'MCP 状态异常'}
            description={status.lastError}
            style={{ marginBottom: 16 }}
          />
        ) : null}
        <Row gutter={[16, 16]}>
          <Col xs={24} md={6}>
            <Card bordered={false}>
              <Statistic title="服务状态" value={status?.state || 'stopped'} />
            </Card>
          </Col>
          <Col xs={24} md={6}>
            <Card bordered={false}>
              <Statistic title="已注册工具" value={tools.length} />
            </Card>
          </Col>
          <Col xs={24} md={6}>
            <Card bordered={false}>
              <Statistic title="鉴权请求头" value={status?.authHeader || '-'} />
            </Card>
          </Col>
          <Col xs={24} md={6}>
            <Card bordered={false}>
              <Statistic title="监听地址" value={status?.listenAddr || '-'} />
            </Card>
          </Col>
        </Row>
      </Card>

      <Card className="glass-panel page-panel" loading={loading}>
        <Descriptions
          title="服务连接信息"
          bordered
          column={1}
          items={[
            {
              key: 'status',
              label: '运行状态',
              children: (
                <Space>
                  <Tag color={statusColor(status?.state)}>{status?.state || 'stopped'}</Tag>
                  <span>{status?.message || '未获取状态信息'}</span>
                </Space>
              ),
            },
            { key: 'managed', label: '托管状态', children: status?.managed ? '页面托管' : '外部或未启动' },
            { key: 'reachable', label: '健康检查', children: status?.reachable ? '可访问' : '不可访问' },
            { key: 'baseURL', label: 'MCP 地址', children: status?.baseURL || '-' },
            { key: 'healthURL', label: '健康检查地址', children: status?.healthURL || '-' },
            { key: 'logPath', label: '日志文件', children: status?.logPath || '-' },
            { key: 'config', label: '客户端配置', children: activeServer ? JSON.stringify(activeServer, null, 2) : '-' },
          ]}
        />
      </Card>

      <Row gutter={[16, 16]}>
        <Col xs={24} xl={8}>
          <Card className="glass-panel page-panel" title={`工具列表${loading ? '' : ` (${tools.length})`}`}>
            {loading ? (
              <div className="fullscreen-status" style={{ minHeight: 240 }}>
                <Spin />
              </div>
            ) : tools.length === 0 ? (
              <Empty description={status?.reachable ? '当前服务未返回工具' : '请先启动 MCP 独立服务'} />
            ) : (
              <List
                dataSource={tools}
                renderItem={(tool) => (
                  <List.Item
                    style={{
                      cursor: 'pointer',
                      borderRadius: 12,
                      paddingInline: 12,
                      background: tool.name === selectedToolName ? 'rgba(24, 144, 255, 0.08)' : 'transparent',
                    }}
                    onClick={() => setSelectedToolName(tool.name)}
                  >
                    <List.Item.Meta
                      title={
                        <Space>
                          <span>{tool.name}</span>
                          {tool.name === selectedToolName ? <Tag color="blue">当前</Tag> : null}
                        </Space>
                      }
                      description={tool.description || '未提供工具描述'}
                    />
                  </List.Item>
                )}
              />
            )}
          </Card>
        </Col>
        <Col xs={24} xl={16}>
          <Card
            className="glass-panel page-panel"
            title={selectedTool ? `工具调试 · ${selectedTool.name}` : '工具调试'}
            extra={
              <Button type="primary" loading={calling} onClick={callTool} disabled={!selectedTool}>
                调用工具
              </Button>
            }
          >
            {selectedTool ? (
              <Space direction="vertical" size={16} style={{ width: '100%' }}>
                <Alert
                  type="info"
                  showIcon
                  message={selectedTool.description || '当前工具未提供描述'}
                />
                <div>
                  <Typography.Title level={5}>输入 Schema</Typography.Title>
                  <pre style={{ margin: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
                    {JSON.stringify(selectedTool.inputSchema || {}, null, 2)}
                  </pre>
                </div>
                <div>
                  <Typography.Title level={5}>调用参数 JSON</Typography.Title>
                  <TextArea
                    value={argumentsText}
                    onChange={(event) => setArgumentsText(event.target.value)}
                    autoSize={{ minRows: 12, maxRows: 24 }}
                    style={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace' }}
                  />
                </div>
              </Space>
            ) : (
              <Empty description="请先从左侧选择一个工具" />
            )}
          </Card>
        </Col>
      </Row>

      <Card className="glass-panel page-panel" title="调用结果">
        {result.length === 0 ? (
          <Empty description="工具调用结果会显示在这里" />
        ) : (
          <Space direction="vertical" size={16} style={{ width: '100%' }}>
            {result.map((item, index) => renderContent(item, index))}
          </Space>
        )}
      </Card>
    </div>
  )
}
