import { clsx } from 'clsx';
import { User, Bot, Image, FileText, Download, ExternalLink } from 'lucide-react';
import ReactMarkdown from 'react-markdown';
import { FileAttachment } from '../stores/chatStore';

interface Message {
  id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  createdAt: string;
  attachments?: FileAttachment[];
  metadata?: {
    toolCalls?: Array<{
      name: string;
      result: unknown;
    }>;
  };
}

interface MessageBubbleProps {
  message: Message;
  isStreaming?: boolean;
}

export function MessageBubble({ message, isStreaming }: MessageBubbleProps) {
  const isUser = message.role === 'user';
  const hasAttachments = message.attachments && message.attachments.length > 0;

  return (
    <div
      className={clsx(
        'flex gap-3 message-enter',
        isUser ? 'flex-row-reverse' : 'flex-row',
      )}
    >
      {/* Avatar */}
      <div
        className={clsx(
          'flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center',
          isUser ? 'bg-primary-100' : 'bg-secondary-100',
        )}
      >
        {isUser ? (
          <User className="w-4 h-4 text-primary-600" />
        ) : (
          <Bot className="w-4 h-4 text-secondary-600" />
        )}
      </div>

      {/* Message content */}
      <div className="max-w-[80%] space-y-2">
        {/* 文件附件 */}
        {hasAttachments && (
          <div className={clsx('flex flex-wrap gap-2', isUser ? 'justify-end' : 'justify-start')}>
            {message.attachments!.map((attachment) => (
              <AttachmentPreview key={attachment.id} attachment={attachment} isUser={isUser} />
            ))}
          </div>
        )}

        {/* 文本内容 */}
        {message.content && (
          <div
            className={clsx(
              'rounded-2xl px-4 py-3',
              isUser
                ? 'bg-primary-600 text-white rounded-tr-sm'
                : 'bg-secondary-100 text-secondary-900 rounded-tl-sm',
            )}
          >
            <div className="prose prose-sm max-w-none break-words">
              {isUser ? (
                <p className="m-0 whitespace-pre-wrap">{message.content}</p>
              ) : (
                <ReactMarkdown
                  components={{
                    h1: ({ children }) => <h2 className="text-lg font-bold mt-3 mb-2 first:mt-0">{children}</h2>,
                    h2: ({ children }) => <h3 className="text-base font-bold mt-3 mb-2 first:mt-0">{children}</h3>,
                    h3: ({ children }) => <h4 className="text-sm font-bold mt-2 mb-1">{children}</h4>,
                    p: ({ children }) => <p className="my-2 first:mt-0 last:mb-0">{children}</p>,
                    ul: ({ children }) => <ul className="my-2 pl-4 list-disc">{children}</ul>,
                    ol: ({ children }) => <ol className="my-2 pl-4 list-decimal">{children}</ol>,
                    li: ({ children }) => <li className="my-1">{children}</li>,
                    strong: ({ children }) => <strong className="font-semibold">{children}</strong>,
                    a: ({ href, children }) => (
                      <a href={href} className="text-primary-600 hover:underline" target="_blank" rel="noopener noreferrer">
                        {children}
                      </a>
                    ),
                  }}
                >
                  {message.content}
                </ReactMarkdown>
              )}
              {isStreaming && (
                <span className="inline-block w-1 h-4 ml-1 bg-current animate-pulse" />
              )}
            </div>

            {/* Tool call results (e.g., payment QR code) */}
            {message.metadata?.toolCalls?.map((toolCall, index) => (
              <ToolCallResult key={index} toolCall={toolCall} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function AttachmentPreview({
  attachment,
  isUser,
}: {
  attachment: FileAttachment;
  isUser: boolean;
}) {
  const isImage = attachment.type === 'image';

  const formatFileSize = (bytes: number) => {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  };

  if (isImage && (attachment.downloadUrl || attachment.thumbnailUrl)) {
    return (
      <a
        href={attachment.downloadUrl}
        target="_blank"
        rel="noopener noreferrer"
        className="block group relative"
      >
        <img
          src={attachment.thumbnailUrl || attachment.downloadUrl}
          alt={attachment.originalName}
          className={clsx(
            'max-w-[200px] max-h-[200px] rounded-lg object-cover',
            'border-2 transition-all',
            isUser ? 'border-primary-400' : 'border-secondary-200',
            'group-hover:opacity-90',
          )}
        />
        <div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity bg-black/30 rounded-lg">
          <ExternalLink className="w-6 h-6 text-white" />
        </div>
      </a>
    );
  }

  return (
    <a
      href={attachment.downloadUrl}
      target="_blank"
      rel="noopener noreferrer"
      className={clsx(
        'flex items-center gap-3 px-3 py-2 rounded-lg transition-all',
        isUser
          ? 'bg-primary-500 hover:bg-primary-400'
          : 'bg-white border border-secondary-200 hover:border-secondary-300',
      )}
    >
      {isImage ? (
        <Image className={clsx('w-8 h-8', isUser ? 'text-white/80' : 'text-blue-500')} />
      ) : (
        <FileText className={clsx('w-8 h-8', isUser ? 'text-white/80' : 'text-orange-500')} />
      )}

      <div className="flex flex-col">
        <span
          className={clsx(
            'text-sm max-w-[150px] truncate',
            isUser ? 'text-white' : 'text-secondary-700',
          )}
        >
          {attachment.originalName}
        </span>
        <span className={clsx('text-xs', isUser ? 'text-white/70' : 'text-secondary-400')}>
          {formatFileSize(attachment.size)}
        </span>
      </div>

      <Download className={clsx('w-4 h-4 ml-1', isUser ? 'text-white/70' : 'text-secondary-400')} />
    </a>
  );
}

function ToolCallResult({
  toolCall,
}: {
  toolCall: { name: string; result: unknown };
}) {
  if (toolCall.name === 'generate_payment') {
    const result = toolCall.result as {
      qrCodeUrl?: string;
      amount?: number;
      message?: string;
    };

    return (
      <div className="mt-3 p-3 bg-white rounded-lg border border-secondary-200">
        <p className="text-sm text-secondary-600 mb-2">{result.message}</p>
        {result.qrCodeUrl && (
          <div className="flex flex-col items-center">
            <div className="w-32 h-32 bg-secondary-100 rounded-lg flex items-center justify-center">
              {/* In production, this would be an actual QR code image */}
              <span className="text-xs text-secondary-400">支付二维码</span>
            </div>
            <p className="mt-2 text-lg font-semibold text-primary-600">
              ¥{result.amount}
            </p>
          </div>
        )}
      </div>
    );
  }

  return null;
}
