import { useState, forwardRef, useImperativeHandle } from 'react'
import { Loader2 } from 'lucide-react'
import { useMemoizedFn } from 'ahooks'
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'
import { toast } from 'sonner'

interface MCPJsonEditorProps {
  value: string
  onChange: (value: string) => void
  onSave?: (parsedConfig: Record<string, unknown>) => void | Promise<void>
  showButtons?: boolean
}

export interface MCPJsonEditorRef {
  triggerSave: () => Promise<void>
}

export const MCPJsonEditor = forwardRef<MCPJsonEditorRef, MCPJsonEditorProps>(
  ({ value, onChange, onSave, showButtons = true }, ref) => {
    const [jsonValue, setJsonValue] = useState(value)
    const [isSaving, setIsSaving] = useState(false)

    const parseJsonToConfig = useMemoizedFn(async () => {
      if (isSaving) return
      setIsSaving(true)
      try {
        const res = JSON.parse(jsonValue)
        const { mcpServers = {} as Record<string, unknown> } = res
        const mcpServer = Object.entries(mcpServers)[0]

        if (!mcpServer) {
          toast.error('未检测到合法的MCP配置')
          return
        }

        const [key, value] = mcpServer as [string, Record<string, unknown>]
        const code = key
        const command = value.command ?? ''
        const args = value.args ?? []
        const env = value.env ?? {}
        const url = value.url ?? ''

        if ((!url && !command) || !code) {
          toast.error('非法配置')
          return
        }

        const type = command ? 'command' : 'sse'
        const argsString = (args as string[]).join(' ')
        const envString = Object.entries(env)
          .map(([key, value]) => `${key}=${value}`)
          .join('\n')

        if (
          type === 'command' &&
          !['npx', 'uv', 'uvx'].includes(value.command as string ?? '')
        ) {
          toast.error(`非法配置，不支持的命令: ${value.command}`)
          return
        }

        const parsedConfig = {
          type,
          command,
          code,
          name: code,
          args: argsString,
          env: envString,
          url,
          headers: value.headers ?? '',
        }

        onChange(jsonValue)
        await onSave?.(parsedConfig)
      } catch {
        toast.error('解析失败，请检查JSON格式')
      } finally {
        setIsSaving(false)
      }
    })

    const handleJsonChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
      const newValue = e.target.value
      setJsonValue(newValue)
      onChange(newValue)
    }

    useImperativeHandle(ref, () => ({
      triggerSave: parseJsonToConfig,
    }))

    return (
      <div className='w-full h-full flex flex-col' style={{ pointerEvents: 'auto' }}>
        <div className='flex-1 flex flex-col' style={{ pointerEvents: 'auto' }}>
          <Textarea
            className='flex-1 rounded-xl border border-input bg-card focus:border-primary/40 focus:ring-2 focus:ring-ring'
            style={{
              resize: 'none',
              fontSize: '14px',
              lineHeight: '1.5',
              fontFamily: 'Monaco, Menlo, "Ubuntu Mono", consolas, "source-code-pro", monospace',
              minHeight: '300px',
              pointerEvents: 'auto',
              zIndex: 1,
              position: 'relative',
              cursor: 'text',
              caretColor: 'var(--primary)',
              outline: 'none',
              userSelect: 'text',
            }}
            autoFocus
            placeholder={`仅支持解析一个MCP，如果有多个仅解析第一个，示例：
{
  "mcpServers": {
    "RedNote MCP": {
      "command": "npx",
      "args": ["rednote-mcp", "--stdio"]
    }
  }
}

或者 SSE 方式：
{
  "mcpServers": {
    "Weather MCP": {
      "url": "http://localhost:8000/mcp"
    }
  }
}`}
            value={jsonValue}
            onChange={handleJsonChange}
          />
        </div>
        {showButtons && (
          <div className='shrink-0 pt-3 flex items-center justify-end gap-3'>
            <Button onClick={parseJsonToConfig} disabled={isSaving}>
              {isSaving && <Loader2 className='h-4 w-4 animate-spin' />}
              {isSaving ? '解析中...' : '解析并保存'}
            </Button>
          </div>
        )}
      </div>
    )
  },
)

MCPJsonEditor.displayName = 'MCPJsonEditor'
