import { clsx } from 'clsx';
import { User, Bot, Image, FileText, Download, ExternalLink, CheckCircle, Clock, XCircle, AlertCircle, ShoppingBag } from 'lucide-react';
import ReactMarkdown from 'react-markdown';
import { QRCodeSVG } from 'qrcode.react';
import { FileAttachment } from '../stores/chatStore';
import { AssessmentResultCard } from './AssessmentResultCard';

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 {
      success?: boolean;
      qrCodeUrl?: string;
      paymentUrl?: string;
      amount?: number;
      currency?: string;
      message?: string;
      orderId?: string;
      expiresAt?: string;
      error?: string;
    };

    if (!result.success) {
      return (
        <div className="mt-3 p-3 bg-red-50 rounded-lg border border-red-200">
          <div className="flex items-center gap-2">
            <AlertCircle className="w-4 h-4 text-red-500" />
            <p className="text-sm text-red-600">{result.error || '支付创建失败'}</p>
          </div>
        </div>
      );
    }

    return (
      <div className="mt-3 p-4 bg-white rounded-lg border border-secondary-200">
        <p className="text-sm text-secondary-600 mb-3">{result.message}</p>
        <div className="flex flex-col items-center">
          {result.qrCodeUrl ? (
            <div className="p-3 bg-white rounded-lg border border-secondary-100">
              <QRCodeSVG value={result.qrCodeUrl} size={160} level="M" />
            </div>
          ) : result.paymentUrl ? (
            <a
              href={result.paymentUrl}
              target="_blank"
              rel="noopener noreferrer"
              className="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
            >
              前往支付
            </a>
          ) : null}
          <p className="mt-3 text-xl font-semibold text-primary-600">
            ¥{result.amount}
          </p>
          {result.orderId && (
            <p className="mt-1 text-xs text-secondary-400">
              订单号: {result.orderId}
            </p>
          )}
          {result.expiresAt && (
            <p className="mt-1 text-xs text-secondary-400 flex items-center gap-1">
              <Clock className="w-3 h-3" />
              有效期至: {new Date(result.expiresAt).toLocaleTimeString('zh-CN')}
            </p>
          )}
        </div>
      </div>
    );
  }

  if (toolCall.name === 'check_payment_status') {
    const result = toolCall.result as {
      success?: boolean;
      orderId?: string;
      status?: string;
      statusLabel?: string;
      paidAt?: string;
      error?: string;
    };

    if (!result.success) {
      return (
        <div className="mt-3 p-3 bg-red-50 rounded-lg border border-red-200">
          <div className="flex items-center gap-2">
            <AlertCircle className="w-4 h-4 text-red-500" />
            <p className="text-sm text-red-600">{result.error || '查询失败'}</p>
          </div>
        </div>
      );
    }

    const statusConfig: Record<string, { icon: React.ReactNode; color: string }> = {
      PAID: { icon: <CheckCircle className="w-4 h-4 text-green-500" />, color: 'bg-green-50 border-green-200' },
      COMPLETED: { icon: <CheckCircle className="w-4 h-4 text-green-500" />, color: 'bg-green-50 border-green-200' },
      PENDING_PAYMENT: { icon: <Clock className="w-4 h-4 text-yellow-500" />, color: 'bg-yellow-50 border-yellow-200' },
      CREATED: { icon: <Clock className="w-4 h-4 text-yellow-500" />, color: 'bg-yellow-50 border-yellow-200' },
      CANCELLED: { icon: <XCircle className="w-4 h-4 text-red-500" />, color: 'bg-red-50 border-red-200' },
      REFUNDED: { icon: <XCircle className="w-4 h-4 text-orange-500" />, color: 'bg-orange-50 border-orange-200' },
    };
    const config = statusConfig[result.status || ''] || { icon: <Clock className="w-4 h-4 text-secondary-400" />, color: 'bg-secondary-50 border-secondary-200' };

    return (
      <div className={clsx('mt-3 p-3 rounded-lg border', config.color)}>
        <div className="flex items-center gap-2">
          {config.icon}
          <span className="text-sm font-medium">{result.statusLabel || result.status}</span>
        </div>
        {result.orderId && (
          <p className="mt-1 text-xs text-secondary-500">订单号: {result.orderId}</p>
        )}
        {result.paidAt && (
          <p className="mt-1 text-xs text-secondary-500">
            支付时间: {new Date(result.paidAt).toLocaleString('zh-CN')}
          </p>
        )}
      </div>
    );
  }

  if (toolCall.name === 'query_order_history') {
    const result = toolCall.result as {
      success?: boolean;
      totalOrders?: number;
      orders?: Array<{
        orderId: string;
        serviceType: string;
        serviceCategory?: string;
        amount: number;
        currency: string;
        status: string;
        paidAt?: string;
        createdAt: string;
      }>;
      error?: string;
    };

    if (!result.success) {
      return (
        <div className="mt-3 p-3 bg-red-50 rounded-lg border border-red-200">
          <div className="flex items-center gap-2">
            <AlertCircle className="w-4 h-4 text-red-500" />
            <p className="text-sm text-red-600">{result.error || '查询失败'}</p>
          </div>
        </div>
      );
    }

    if (!result.orders || result.orders.length === 0) {
      return (
        <div className="mt-3 p-3 bg-secondary-50 rounded-lg border border-secondary-200">
          <div className="flex items-center gap-2">
            <ShoppingBag className="w-4 h-4 text-secondary-400" />
            <p className="text-sm text-secondary-500">暂无订单记录</p>
          </div>
        </div>
      );
    }

    const statusLabels: Record<string, string> = {
      CREATED: '待支付',
      PENDING_PAYMENT: '待支付',
      PAID: '已支付',
      PROCESSING: '处理中',
      COMPLETED: '已完成',
      CANCELLED: '已取消',
      REFUNDED: '已退款',
    };

    return (
      <div className="mt-3 p-3 bg-white rounded-lg border border-secondary-200">
        <div className="flex items-center gap-2 mb-2">
          <ShoppingBag className="w-4 h-4 text-primary-500" />
          <span className="text-sm font-medium">订单记录 ({result.totalOrders})</span>
        </div>
        <div className="space-y-2">
          {result.orders.map((order) => (
            <div key={order.orderId} className="flex items-center justify-between p-2 bg-secondary-50 rounded text-xs">
              <div>
                <span className="font-medium">{order.serviceCategory || order.serviceType}</span>
                <span className="ml-2 text-secondary-400">
                  {new Date(order.createdAt).toLocaleDateString('zh-CN')}
                </span>
              </div>
              <div className="flex items-center gap-2">
                <span className="font-medium">¥{order.amount}</span>
                <span className={clsx(
                  'px-1.5 py-0.5 rounded text-xs',
                  order.status === 'PAID' || order.status === 'COMPLETED' ? 'bg-green-100 text-green-700' :
                  order.status === 'CANCELLED' || order.status === 'REFUNDED' ? 'bg-red-100 text-red-700' :
                  'bg-yellow-100 text-yellow-700'
                )}>
                  {statusLabels[order.status] || order.status}
                </span>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  if (toolCall.name === 'invoke_assessment_expert') {
    // Assessment expert returns a JSON string; parse it
    try {
      const raw = toolCall.result;
      const data = typeof raw === 'string' ? JSON.parse(raw) : raw;
      if (data?.assessments && Array.isArray(data.assessments)) {
        return <AssessmentResultCard data={data} />;
      }
    } catch {
      // Not parseable — fall through to null
    }
  }

  if (toolCall.name === 'cancel_order') {
    const result = toolCall.result as {
      success?: boolean;
      orderId?: string;
      message?: string;
      error?: string;
    };

    return (
      <div className={clsx(
        'mt-3 p-3 rounded-lg border',
        result.success ? 'bg-green-50 border-green-200' : 'bg-red-50 border-red-200',
      )}>
        <div className="flex items-center gap-2">
          {result.success ? (
            <CheckCircle className="w-4 h-4 text-green-500" />
          ) : (
            <AlertCircle className="w-4 h-4 text-red-500" />
          )}
          <span className="text-sm">
            {result.success ? result.message : result.error}
          </span>
        </div>
        {result.orderId && (
          <p className="mt-1 text-xs text-secondary-500">订单号: {result.orderId}</p>
        )}
      </div>
    );
  }

  return null;
}
