/**
 * json-render 注册表
 *
 * 使用官方 defineRegistry API 创建组件注册表
 */

'use client';

import { useState } from 'react';
import { defineRegistry, type BaseComponentProps } from '@json-render/react';
import { useActionEmit } from '@/lib/action-context';
import { z } from 'zod';
import catalog, {
  CardProps,
  StackProps,
  HeadingProps,
  TextProps,
  ButtonProps,
  BadgeProps,
  SeparatorProps,
  InputProps,
  TextAreaProps,
  DataTableProps,
  TranslationResultProps,
  NovelListProps,
  ChapterReaderProps,
  CodeBlockProps,
  ToolCallProps,
  LoginPanelProps,
  McpStatusProps,
  SuggestionButtonsProps,
} from './catalog/catalog';

// ============ 基础组件 ============

const Card = ({ props, children }: BaseComponentProps<z.infer<typeof CardProps>>) => (
  <div className={`bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 shadow-sm p-4 ${props.className || ''}`}>
    {props.title && <h3 className="text-lg font-semibold mb-3 text-gray-900 dark:text-white">{props.title}</h3>}
    {children}
  </div>
);

const Stack = ({ props, children }: BaseComponentProps<z.infer<typeof StackProps>>) => {
  const directionClass = props.direction === 'row' ? 'flex-row' : 'flex-col';
  const spacingClass = (props.spacing ?? 2) > 0 ? `gap-${props.spacing ?? 2}` : '';
  const alignClass = props.align === 'center' ? 'items-center'
    : props.align === 'end' ? 'items-end'
    : props.align === 'stretch' ? 'items-stretch'
    : 'items-start';

  return (
    <div className={`flex ${directionClass} ${spacingClass} ${alignClass} ${props.className || ''}`}>
      {children}
    </div>
  );
};

const Heading = ({ props }: BaseComponentProps<z.infer<typeof HeadingProps>>) => {
  const level = props.level || 'h2';
  const Tag = level as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
  const sizeClasses: Record<string, string> = {
    h1: 'text-3xl font-bold',
    h2: 'text-2xl font-semibold',
    h3: 'text-xl font-semibold',
    h4: 'text-lg font-medium',
    h5: 'text-base font-medium',
    h6: 'text-sm font-medium',
  };
  const sizeClass = sizeClasses[level] || sizeClasses.h2;

  return <Tag className={`${sizeClass} text-gray-900 dark:text-white ${props.className || ''}`}>{props.text}</Tag>;
};

const Text = ({ props }: BaseComponentProps<z.infer<typeof TextProps>>) => {
  const variantClasses: Record<string, string> = {
    default: 'text-gray-700 dark:text-gray-300',
    muted: 'text-gray-500 dark:text-gray-400',
    primary: 'text-blue-600 dark:text-blue-400',
    success: 'text-green-600 dark:text-green-400',
    warning: 'text-yellow-600 dark:text-yellow-400',
    destructive: 'text-red-600 dark:text-red-400',
  };
  const sizeClasses: Record<string, string> = {
    xs: 'text-xs',
    sm: 'text-sm',
    md: 'text-base',
    lg: 'text-lg',
    xl: 'text-xl',
  };
  const color = props.color || 'default';
  const size = props.size || 'md';

  return <p className={`${variantClasses[color]} ${sizeClasses[size]} ${props.className || ''}`}>{props.text}</p>;
};

const Button = ({ props, emit }: BaseComponentProps<z.infer<typeof ButtonProps>>) => {
  const variantClasses: Record<string, string> = {
    default: 'bg-gray-200 hover:bg-gray-300 text-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 dark:text-gray-200',
    primary: 'bg-blue-600 hover:bg-blue-700 text-white',
    secondary: 'bg-purple-600 hover:bg-purple-700 text-white',
    outline: 'border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300',
    ghost: 'hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300',
    destructive: 'bg-red-600 hover:bg-red-700 text-white',
  };
  const variant = props.variant || 'default';

  const handleClick = () => {
    if (props.disabled) return;
    if (props.onClick) {
      emit(props.onClick);
    }
  };

  return (
    <button
      onClick={handleClick}
      disabled={props.disabled}
      className={`${variantClasses[variant]} px-4 py-2 rounded-md font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${props.className || ''}`}
    >
      {props.label}
    </button>
  );
};

const Badge = ({ props }: BaseComponentProps<z.infer<typeof BadgeProps>>) => {
  const variantClasses: Record<string, string> = {
    default: 'bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200',
    primary: 'bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200',
    secondary: 'bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-200',
    success: 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200',
    warning: 'bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-200',
    destructive: 'bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200',
  };
  const variant = props.variant || 'default';

  return (
    <span className={`inline-flex items-center px-2 py-1 rounded-md text-xs font-medium ${variantClasses[variant]} ${props.className || ''}`}>
      {props.text}
    </span>
  );
};

const Separator = ({ props }: BaseComponentProps<z.infer<typeof SeparatorProps>>) => {
  const orientation = props.orientation || 'horizontal';
  const orientationClass = orientation === 'vertical' ? 'w-px h-full' : 'h-px w-full';
  return <div className={`bg-gray-200 dark:bg-gray-700 ${orientationClass} ${props.className || ''}`} />;
};

const Input = ({ props }: BaseComponentProps<z.infer<typeof InputProps>>) => (
  <input
    type={props.type || 'text'}
    placeholder={props.placeholder}
    disabled={props.disabled}
    className={`w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50 ${props.className || ''}`}
  />
);

const TextArea = ({ props }: BaseComponentProps<z.infer<typeof TextAreaProps>>) => (
  <textarea
    placeholder={props.placeholder}
    rows={props.rows || 3}
    disabled={props.disabled}
    className={`w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50 resize-none ${props.className || ''}`}
  />
);

const DataTable = ({ props }: BaseComponentProps<z.infer<typeof DataTableProps>>) => (
  <div className={`overflow-x-auto ${props.className || ''}`}>
    <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
      <thead className="bg-gray-50 dark:bg-gray-800">
        <tr>
          {props.columns?.map((col) => (
            <th key={col.key} className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
              {col.label}
            </th>
          ))}
        </tr>
      </thead>
      <tbody className="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
        {props.data?.map((row, idx) => (
          <tr key={idx} className="hover:bg-gray-50 dark:hover:bg-gray-800">
            {props.columns?.map((col) => (
              <td key={col.key} className="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                {String(row[col.key] ?? '')}
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  </div>
);

// ============ MCP 专用组件 ============

const TranslationResult = ({ props }: BaseComponentProps<z.infer<typeof TranslationResultProps>>) => {
  const [copied, setCopied] = useState(false);

  const handleCopy = () => {
    if (props.translated) {
      navigator.clipboard.writeText(props.translated);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  return (
    <div className={`bg-white dark:bg-gray-800 rounded-xl shadow-md border border-gray-200 dark:border-gray-700 overflow-hidden ${props.className || ''}`}>
      <div className="bg-gradient-to-r from-blue-500 to-purple-500 px-4 py-3 flex items-center gap-2">
        <span className="text-xl">🌐</span>
        <h4 className="font-semibold text-white">翻译结果</h4>
      </div>

      <div className="p-4">
        {props.original && (
          <div className="bg-gray-50 dark:bg-gray-900/50 rounded-lg p-3 mb-3">
            <span className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">原文</span>
            <p className="text-gray-600 dark:text-gray-400 leading-relaxed mt-1">{props.original}</p>
          </div>
        )}

        <div className="bg-gradient-to-br from-blue-50 to-purple-50 dark:from-blue-900/20 dark:to-purple-900/20 rounded-lg p-3 border border-blue-100 dark:border-blue-800/50 mb-3">
          <span className="text-xs font-medium text-blue-600 dark:text-blue-400 uppercase tracking-wide">译文</span>
          <p className="text-gray-900 dark:text-gray-100 font-medium leading-relaxed mt-1">{props.translated}</p>
        </div>

        {props.termsUsed && props.termsUsed.length > 0 && (
          <div className="bg-gray-50 dark:bg-gray-900/50 rounded-lg p-3">
            <span className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">使用术语</span>
            <div className="flex flex-wrap gap-2 mt-1">
              {props.termsUsed.map((term, idx) => (
                <span key={idx} className="inline-flex items-center px-2 py-1 rounded-md text-xs font-medium bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-200">
                  {term}
                </span>
              ))}
            </div>
          </div>
        )}
      </div>

      <div className="px-4 py-3 bg-gray-50 dark:bg-gray-900/30 border-t dark:border-gray-700 flex gap-2">
        <button
          onClick={handleCopy}
          className="flex-1 flex items-center justify-center gap-1 px-3 py-2 text-sm bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
        >
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
          </svg>
          <span>{copied ? '已复制！' : '复制译文'}</span>
        </button>
      </div>
    </div>
  );
};

const NovelList = ({ props, emit }: BaseComponentProps<z.infer<typeof NovelListProps>>) => (
  <div className={`space-y-3 ${props.className || ''}`}>
    {props.novels?.map((novel) => (
      <div
        key={String(novel.id)}
        onClick={() => emit('selectNovel')}
        className="bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 p-4 hover:shadow-md hover:border-blue-300 dark:hover:border-blue-600 transition-all cursor-pointer"
      >
        <h4 className="font-semibold text-lg text-gray-900 dark:text-white mb-1">{novel.title}</h4>
        {novel.author && <p className="text-sm text-gray-500 dark:text-gray-400 mb-2">By {novel.author}</p>}
        {novel.description && <p className="text-sm text-gray-600 dark:text-gray-300 mb-2 line-clamp-2">{novel.description}</p>}
        <div className="flex items-center gap-2">
          {novel.chapterCount && (
            <span className="inline-flex items-center px-2 py-1 rounded-md text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200">
              {novel.chapterCount} chapters
            </span>
          )}
          {novel.tags?.map((tag) => (
            <span key={tag} className="inline-flex items-center px-2 py-1 rounded-md text-xs font-medium bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200">
              {tag}
            </span>
          ))}
        </div>
      </div>
    ))}
  </div>
);

const ChapterReader = ({ props }: BaseComponentProps<z.infer<typeof ChapterReaderProps>>) => (
  <div className={`bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 p-6 ${props.className || ''}`}>
    <div className="border-b dark:border-gray-700 pb-4 mb-4">
      {props.novelTitle && <p className="text-sm text-gray-500 dark:text-gray-400 mb-1">{props.novelTitle}</p>}
      {props.chapterTitle && <h2 className="text-2xl font-bold text-gray-900 dark:text-white">{props.chapterTitle}</h2>}
      {props.chapterNumber && props.totalChapters && (
        <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
          Chapter {props.chapterNumber} of {props.totalChapters}
        </p>
      )}
    </div>
    <div className="prose dark:prose-invert max-w-none">
      <p className="text-gray-700 dark:text-gray-300 whitespace-pre-wrap leading-relaxed">{props.content}</p>
    </div>
  </div>
);

const CodeBlock = ({ props }: BaseComponentProps<z.infer<typeof CodeBlockProps>>) => {
  const [copied, setCopied] = useState(false);

  const handleCopy = () => {
    if (props.code) {
      navigator.clipboard.writeText(props.code);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  return (
    <div className={`bg-gray-900 dark:bg-gray-950 rounded-lg overflow-hidden ${props.className || ''}`}>
      <div className="flex items-center justify-between px-4 py-2 bg-gray-800 dark:bg-gray-900">
        <span className="text-xs text-gray-400 uppercase">{props.language || 'text'}</span>
        <button
          onClick={handleCopy}
          className="text-xs text-gray-400 hover:text-white transition-colors"
        >
          {copied ? '已复制!' : 'Copy'}
        </button>
      </div>
      <pre className="p-4 overflow-x-auto">
        <code className="text-sm text-gray-100 font-mono">{props.code}</code>
      </pre>
    </div>
  );
};

const ToolCall = ({ props }: BaseComponentProps<z.infer<typeof ToolCallProps>>) => {
  const statusConfig: Record<string, { icon: string; color: string; bg: string }> = {
    pending: { icon: '⏳', color: 'text-yellow-600', bg: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-300 dark:border-yellow-700' },
    running: { icon: '🔄', color: 'text-blue-600', bg: 'bg-blue-50 dark:bg-blue-900/20 border-blue-300 dark:border-blue-700' },
    success: { icon: '✅', color: 'text-green-600', bg: 'bg-green-50 dark:bg-green-900/20 border-green-300 dark:border-green-700' },
    error: { icon: '❌', color: 'text-red-600', bg: 'bg-red-50 dark:bg-red-900/20 border-red-300 dark:border-red-700' },
  };
  const status = props.status || 'success';
  const config = statusConfig[status];

  return (
    <div className={`border-l-4 p-3 rounded-r ${config.bg}`}>
      <div className="flex items-center gap-2 mb-2">
        <span className="text-lg">{config.icon}</span>
        <span className={`font-mono text-sm font-medium ${config.color}`}>{props.toolName}</span>
      </div>
      {props.result && status === 'success' && (
        <div className="mt-2">
          <p className="text-xs text-gray-500 dark:text-gray-400 mb-1">Result:</p>
          <pre className="text-xs bg-gray-100 dark:bg-gray-900 p-2 rounded overflow-x-auto">
            {typeof props.result === 'string' ? props.result : JSON.stringify(props.result, null, 2)}
          </pre>
        </div>
      )}
      {status === 'error' && (
        <div className="mt-2">
          <p className="text-xs text-red-600 dark:text-red-400">Error occurred</p>
        </div>
      )}
    </div>
  );
};

const LoginPanel = ({ props, emit }: BaseComponentProps<z.infer<typeof LoginPanelProps>>) => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleLogin = () => {
    if (props.onLogin) {
      emit(props.onLogin);
    }
  };

  return (
    <div className={`bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 p-6 ${props.className || ''}`}>
      <div className="text-center mb-6">
        <div className="text-4xl mb-2">🔐</div>
        <h3 className="text-xl font-semibold text-gray-900 dark:text-white">{props.serverName || 'MCP Server'}</h3>
        <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">Sign in to continue</p>
      </div>
      <div className="space-y-4">
        <div>
          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Email</label>
          <input
            type="email"
            placeholder="your@email.com"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500"
          />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Password</label>
          <input
            type="password"
            placeholder="••••••••"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500"
          />
        </div>
        <button
          onClick={handleLogin}
          className="w-full bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md font-medium transition-colors"
        >
          Sign In
        </button>
      </div>
    </div>
  );
};

const McpStatus = ({ props }: BaseComponentProps<z.infer<typeof McpStatusProps>>) => (
  <div className={`flex items-center gap-2 px-3 py-2 rounded-lg ${props.connected ? 'bg-green-100 dark:bg-green-900/30' : 'bg-red-100 dark:bg-red-900/30'} ${props.className || ''}`}>
    <span className={`w-2 h-2 rounded-full ${props.connected ? 'bg-green-500' : 'bg-red-500'}`} />
    <span className="text-sm font-medium">
      {props.serverId}: {props.connected ? 'Connected' : 'Disconnected'}
    </span>
  </div>
);

const SuggestionButtons = ({ props }: BaseComponentProps<z.infer<typeof SuggestionButtonsProps>>) => {
  const { emit } = useActionEmit();

  const handleSelect = (suggestion: { label: string; message?: string }) => {
    const message = suggestion.message || suggestion.label;
    emit('sendMessage', { message });
  };

  return (
    <div className="flex flex-wrap gap-2">
      {props.suggestions?.map((s, i) => (
        <button
          key={i}
          onClick={() => handleSelect(s)}
          className="px-3 py-1.5 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 rounded-full text-sm transition-colors flex items-center gap-1.5"
        >
          {s.icon && <span>{s.icon}</span>}
          <span>{s.label}</span>
        </button>
      ))}
    </div>
  );
};

// ============ 创建并导出注册表 ============

const { registry } = defineRegistry(catalog, {
  components: {
    // 基础组件
    card: Card,
    stack: Stack,
    heading: Heading,
    text: Text,
    button: Button,
    badge: Badge,
    separator: Separator,
    input: Input,
    'text-area': TextArea,
    'data-table': DataTable,

    // MCP 专用组件
    'translation-result': TranslationResult,
    'novel-list': NovelList,
    'chapter-reader': ChapterReader,
    'code-block': CodeBlock,
    'tool-call': ToolCall,
    'login-panel': LoginPanel,
    'mcp-status': McpStatus,
    'suggestion-buttons': SuggestionButtons,
  },
});

export { registry };
export type { BaseComponentProps } from '@json-render/react';
