'use client'

import * as React from 'react'
import { Paperclip, Wrench } from 'lucide-react'
import { cn } from '../../lib/utils'
import type { ChatMessageAttachment, ChatMessageData } from './types'
import { isImageName } from './attachment-utils'

export interface ChatMessageProps {
  message: ChatMessageData
  /** Optional custom renderer for the message body (e.g. markdown). */
  renderContent?: (content: string, message: ChatMessageData) => React.ReactNode
  className?: string
}

function StreamingDots() {
  return (
    <span className="ml-1 inline-flex gap-0.5 align-middle" aria-hidden="true">
      <span className="h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.3s]" />
      <span className="h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.15s]" />
      <span className="h-1.5 w-1.5 animate-bounce rounded-full bg-current" />
    </span>
  )
}

/**
 * A single chat row. Text messages render as aligned bubbles (user right,
 * assistant left); `tool` / `status` kinds render as compact centered system
 * rows. Fully generic — no presentation-specific knowledge.
 */
/** Attachment chips/thumbnails rendered on a message bubble. */
function MessageAttachments({
  attachments,
  isUser,
}: {
  attachments: ChatMessageAttachment[]
  isUser: boolean
}) {
  return (
    <ul className="mt-2 flex flex-wrap gap-2" data-testid="chat-message-attachments">
      {attachments.map((a) => {
        const isImage = !!a.fileUrl && isImageName(a.contentType || a.filename)
        const chip = (
          <span
            className={cn(
              'flex items-center gap-1.5 rounded-md border px-1.5 py-1 text-xs',
              isUser
                ? 'border-primary-foreground/30 bg-primary-foreground/10'
                : 'border-border bg-background/60'
            )}
          >
            <Paperclip className="h-3 w-3 shrink-0" aria-hidden="true" />
            <span className="max-w-[10rem] truncate" title={a.filename}>
              {a.filename}
            </span>
          </span>
        )
        return (
          <li key={a.id} data-testid={`chat-message-attachment-${a.id}`}>
            {isImage ? (
              // eslint-disable-next-line @next/next/no-img-element
              <img
                src={a.fileUrl!}
                alt={a.filename}
                className="h-16 w-16 rounded-md border border-border object-cover"
              />
            ) : a.fileUrl ? (
              <a href={a.fileUrl} target="_blank" rel="noreferrer" className="hover:opacity-80">
                {chip}
              </a>
            ) : (
              chip
            )}
          </li>
        )
      })}
    </ul>
  )
}

export function ChatMessage({ message, renderContent, className }: ChatMessageProps) {
  const { role, content, status, kind = 'text', toolName, attachments } = message
  const isStreaming = status === 'streaming'
  const isError = status === 'error'

  if (kind === 'tool' || kind === 'status') {
    return (
      <div
        data-role={role}
        data-kind={kind}
        data-status={status}
        aria-busy={isStreaming || undefined}
        className={cn(
          'mx-auto flex max-w-[90%] items-start gap-2 rounded-md border border-border bg-muted/40 px-3 py-1.5 text-xs text-muted-foreground',
          isError && 'border-red-300 bg-red-50 text-red-700',
          className
        )}
      >
        {kind === 'tool' && <Wrench className="mt-0.5 h-3.5 w-3.5 shrink-0" aria-hidden="true" />}
        {toolName && <span className="shrink-0 font-medium text-foreground">{toolName}</span>}
        <span className="min-w-0 whitespace-pre-wrap break-words">{content}</span>
        {isStreaming && <StreamingDots />}
      </div>
    )
  }

  const isUser = role === 'user'
  const body = renderContent ? renderContent(content, message) : content

  return (
    <div
      data-role={role}
      data-kind={kind}
      data-status={status}
      aria-busy={isStreaming || undefined}
      className={cn('flex w-full', isUser ? 'justify-end' : 'justify-start', className)}
    >
      <div
        className={cn(
          'max-w-[85%] whitespace-pre-wrap break-words rounded-2xl px-4 py-2 text-sm shadow-sm',
          isUser
            ? 'rounded-br-sm bg-primary text-primary-foreground'
            : 'rounded-bl-sm bg-muted text-foreground',
          isError && 'border border-red-300 bg-red-50 text-red-700'
        )}
      >
        {body}
        {isStreaming && <StreamingDots />}
        {attachments && attachments.length > 0 && (
          <MessageAttachments attachments={attachments} isUser={isUser} />
        )}
      </div>
    </div>
  )
}
