import { useEffect, useState } from 'react';
import {
  Drawer,
  Form,
  Input,
  Select,
  Switch,
  Button,
  Space,
  Alert,
  InputNumber,
  Card,
  Spin,
} from 'antd';
import {
  ExperimentOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
} from '@ant-design/icons';
import {
  useMcpServer,
  useCreateMcpServer,
  useUpdateMcpServer,
  useTestMcpConfig,
  type CreateMcpServerDto,
  type McpTransportType,
  type TestConnectionResult,
} from '../../application/useMcp';

const { TextArea } = Input;

interface ServerFormDrawerProps {
  open: boolean;
  editingServerId: string | null;
  onClose: () => void;
}

export function ServerFormDrawer({ open, editingServerId, onClose }: ServerFormDrawerProps) {
  const [form] = Form.useForm();
  const [transport, setTransport] = useState<McpTransportType>('stdio');
  const [testResult, setTestResult] = useState<TestConnectionResult | null>(null);

  const isEditing = !!editingServerId;

  const { data: editingServer, isLoading: loadingServer } = useMcpServer(
    editingServerId,
    isEditing && open,
  );
  const createMutation = useCreateMcpServer();
  const updateMutation = useUpdateMcpServer();
  const testMutation = useTestMcpConfig();

  useEffect(() => {
    if (open && editingServer && isEditing) {
      form.setFieldsValue({
        serverId: editingServer.serverId,
        name: editingServer.name,
        description: editingServer.description,
        transport: editingServer.transport,
        command: editingServer.command,
        args: editingServer.args?.join('\n') || '',
        env: editingServer.env ? JSON.stringify(editingServer.env, null, 2) : '',
        url: editingServer.url,
        toolsConcurrencySafe: editingServer.toolsConcurrencySafe,
        connectTimeoutMs: editingServer.connectTimeoutMs,
        toolTimeoutMs: editingServer.toolTimeoutMs,
        enabled: editingServer.enabled,
      });
      setTransport(editingServer.transport);
    } else if (open && !isEditing) {
      form.resetFields();
      setTransport('stdio');
    }
    setTestResult(null);
  }, [open, editingServer, isEditing, form]);

  const buildDto = (values: any): CreateMcpServerDto => {
    const argsStr: string = values.args || '';
    const envStr: string = values.env || '';

    return {
      serverId: values.serverId,
      name: values.name,
      description: values.description || undefined,
      transport: values.transport,
      command: values.command || undefined,
      args: argsStr ? argsStr.split('\n').filter((a: string) => a.trim()) : undefined,
      env: envStr.trim() ? JSON.parse(envStr) : undefined,
      url: values.url || undefined,
      toolsConcurrencySafe: values.toolsConcurrencySafe,
      connectTimeoutMs: values.connectTimeoutMs,
      toolTimeoutMs: values.toolTimeoutMs,
      enabled: values.enabled,
    };
  };

  const handleSubmit = async (values: any) => {
    const dto = buildDto(values);
    if (isEditing) {
      await updateMutation.mutateAsync({ id: editingServerId, dto });
    } else {
      await createMutation.mutateAsync(dto);
    }
    onClose();
  };

  const handleTest = async () => {
    try {
      const values = await form.validateFields();
      const dto = buildDto(values);
      const result = await testMutation.mutateAsync(dto);
      setTestResult(result);
    } catch {
      // validation failed
    }
  };

  return (
    <Drawer
      title={isEditing ? '编辑 MCP Server' : '添加 MCP Server'}
      width={640}
      open={open}
      onClose={onClose}
      extra={
        <Space>
          <Button onClick={onClose}>取消</Button>
          <Button
            type="primary"
            onClick={() => form.submit()}
            loading={createMutation.isPending || updateMutation.isPending}
          >
            {isEditing ? '保存' : '创建'}
          </Button>
        </Space>
      }
    >
      {loadingServer ? (
        <div className="flex justify-center items-center h-64"><Spin size="large" /></div>
      ) : (
        <Form
          form={form}
          layout="vertical"
          onFinish={handleSubmit}
          initialValues={{
            transport: 'stdio',
            toolsConcurrencySafe: true,
            connectTimeoutMs: 10000,
            toolTimeoutMs: 30000,
            enabled: true,
          }}
        >
          <Card title="基本信息" size="small" className="mb-4">
            <Form.Item
              name="serverId"
              label="Server ID"
              rules={[
                { required: true, message: '必填' },
                { pattern: /^[a-z0-9-_]+$/, message: '仅限小写字母、数字、连字符、下划线' },
              ]}
              extra="唯一标识，用于工具名前缀（如 calendar-server）"
            >
              <Input placeholder="calendar-server" disabled={isEditing} />
            </Form.Item>

            <Form.Item name="name" label="名称" rules={[{ required: true, message: '必填' }]}>
              <Input placeholder="Calendar MCP Server" />
            </Form.Item>

            <Form.Item name="description" label="描述">
              <TextArea rows={2} placeholder="可选描述" />
            </Form.Item>
          </Card>

          <Card title="传输配置" size="small" className="mb-4">
            <Form.Item name="transport" label="传输类型" rules={[{ required: true }]}>
              <Select onChange={(v: McpTransportType) => setTransport(v)}>
                <Select.Option value="stdio">stdio（本地进程）</Select.Option>
                <Select.Option value="sse">SSE（HTTP 流式）</Select.Option>
              </Select>
            </Form.Item>

            {transport === 'stdio' ? (
              <>
                <Form.Item
                  name="command"
                  label="命令"
                  rules={[{ required: true, message: 'stdio 传输需要指定命令' }]}
                >
                  <Input placeholder="node" />
                </Form.Item>

                <Form.Item name="args" label="参数（每行一个）">
                  <TextArea rows={3} placeholder={"/path/to/server/index.js\n--option=value"} />
                </Form.Item>

                <Form.Item
                  name="env"
                  label="环境变量（JSON）"
                  rules={[{
                    validator: (_, value) => {
                      if (!value || !value.trim()) return Promise.resolve();
                      try { JSON.parse(value); return Promise.resolve(); }
                      catch { return Promise.reject('无效的 JSON 格式'); }
                    },
                  }]}
                >
                  <TextArea rows={3} placeholder='{"API_KEY": "your-key"}' />
                </Form.Item>
              </>
            ) : (
              <Form.Item
                name="url"
                label="服务器 URL"
                rules={[{ required: true, message: 'SSE 传输需要指定 URL' }]}
              >
                <Input placeholder="https://example.com/mcp/sse" />
              </Form.Item>
            )}
          </Card>

          <Card title="高级设置" size="small" className="mb-4">
            <Form.Item name="toolsConcurrencySafe" label="工具可并发" valuePropName="checked" extra="此服务器的工具是否可以并行调用">
              <Switch />
            </Form.Item>
            <Form.Item name="connectTimeoutMs" label="连接超时（ms）">
              <InputNumber min={1000} max={60000} step={1000} style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="toolTimeoutMs" label="工具执行超时（ms）">
              <InputNumber min={5000} max={300000} step={5000} style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="enabled" label="启用" valuePropName="checked" extra="启动时自动连接">
              <Switch />
            </Form.Item>
          </Card>

          <Card title="测试连接" size="small">
            <Space direction="vertical" style={{ width: '100%' }}>
              <Button icon={<ExperimentOutlined />} onClick={handleTest} loading={testMutation.isPending} block>
                测试连接
              </Button>
              {testResult && (
                <Alert
                  message={testResult.success ? '连接成功' : '连接失败'}
                  description={testResult.success ? `成功连接，发现 ${testResult.toolCount} 个工具。` : testResult.error}
                  type={testResult.success ? 'success' : 'error'}
                  showIcon
                  icon={testResult.success ? <CheckCircleOutlined /> : <CloseCircleOutlined />}
                />
              )}
            </Space>
          </Card>
        </Form>
      )}
    </Drawer>
  );
}
