"use client";

import { Download, FileText, Lock } from "lucide-react";
import { useT, useLocale } from "@/shared/i18n/client";
import { formatDateTime } from "@/shared/lib/format-date";
import { formatFileSize } from "@/shared/lib/storage-url";
import { cn } from "@/shared/lib/utils";
import { displayName } from "@/shared/lib/user-display";
import { MessageBody } from "@/presentation/components/tickets/message-body";
import { AudioPlayer } from "./audio-player";
import { PersonAvatar } from "./person-avatar";
import { formatClock, isAudioAttachment } from "./support-utils";
import type { TicketMessage, TicketMessageAttachment } from "@/domain/entities/ticket";

interface ThreadMessageProps {
  message: TicketMessage;
  /** Written by the Dadycar team (shown on the right). */
  fromTeam: boolean;
  isMine: boolean;
  isFirstInGroup: boolean;
  isLastInGroup: boolean;
  onOpenImage: (attachment: TicketMessageAttachment) => void;
}

export function ThreadMessage({ message, fromTeam, isMine, isFirstInGroup, isLastInGroup, onOpenImage }: ThreadMessageProps) {
  const t = useT();
  const locale = useLocale();
  const isNote = message.kind === "internal";
  const images = message.attachments.filter((a) => a.is_image);
  const audios = message.attachments.filter((a) => !a.is_image && isAudioAttachment(a));
  const files = message.attachments.filter((a) => !a.is_image && !isAudioAttachment(a));
  const hasBubble = !!message.body?.trim() || audios.length > 0 || files.length > 0;
  const author = message.author;

  const bubbleTone = isNote
    ? "bg-amber-50 text-amber-950 ring-1 ring-amber-200/80 dark:bg-amber-950/30 dark:text-amber-100 dark:ring-amber-900/60"
    : fromTeam
      ? "bg-primary text-primary-foreground"
      : "bg-muted text-foreground";

  const big = "rounded-2xl";
  const corner = fromTeam
    ? cn(!isFirstInGroup && "rounded-tr-md", !isLastInGroup && "rounded-br-md")
    : cn(!isFirstInGroup && "rounded-tl-md", !isLastInGroup && "rounded-bl-md");

  return (
    <div
      id={`message-${message.id}`}
      className={cn("flex gap-2.5", fromTeam ? "flex-row-reverse" : "flex-row", isFirstInGroup ? "mt-4" : "mt-0.5")}
    >
      <div className="w-8 shrink-0 self-end">
        {isLastInGroup && author && (
          <PersonAvatar name={author.name} email={author.email} initials={author.initials} avatarUrl={author.avatar_url} size={32} />
        )}
      </div>

      <div className={cn("flex min-w-0 max-w-[72%] flex-col", fromTeam ? "items-end" : "items-start")}>
        {isFirstInGroup && (
          <div className={cn("mb-1 flex items-center gap-1.5 px-1 text-[11px] text-muted-foreground", fromTeam && "flex-row-reverse")}>
            <span className="font-medium text-foreground/80">
              {isMine ? t.support.you : author ? displayName(author) : "—"}
            </span>
            {isNote && (
              <span className="inline-flex items-center gap-1 rounded-full bg-amber-100 px-1.5 py-px text-[10px] font-medium text-amber-800 dark:bg-amber-900/50 dark:text-amber-300">
                <Lock className="h-2.5 w-2.5" /> {t.support.thread.internalNote}
              </span>
            )}
          </div>
        )}

        {images.length > 0 && (
          <div className={cn("mb-1 flex flex-wrap gap-1.5", fromTeam && "justify-end")}>
            {images.map((image) => (
              <button
                key={image.id}
                type="button"
                onClick={() => onOpenImage(image)}
                className="overflow-hidden rounded-2xl ring-1 ring-border transition-opacity hover:opacity-90"
              >
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img
                  src={image.url}
                  alt={image.uploaded_file_name}
                  loading="lazy"
                  className={cn("bg-muted object-cover", images.length > 1 ? "h-28 w-28" : "max-h-64 min-h-32 w-60")}
                />
              </button>
            ))}
          </div>
        )}

        {hasBubble && (
          <div
            title={formatDateTime(message.created_at, locale)}
            className={cn("min-w-0 px-3.5 py-2 text-sm leading-relaxed shadow-xs", big, corner, bubbleTone)}
          >
            {message.body?.trim() && (
              <div className={cn("whitespace-pre-wrap break-words", fromTeam && !isNote && "text-primary-foreground [&_*]:text-primary-foreground [&_a]:underline [&_code]:bg-white/20 [&_span.rounded]:bg-white/20")}>
                <MessageBody body={message.body} />
              </div>
            )}
            {audios.map((audio) => (
              <AudioPlayer key={audio.id} url={audio.url} fileName={audio.uploaded_file_name} inverted={fromTeam && !isNote} />
            ))}
            {files.map((file) => (
              <a
                key={file.id}
                href={file.url}
                target="_blank"
                rel="noopener noreferrer"
                className={cn(
                  "mt-1.5 flex items-center gap-2.5 rounded-xl px-2.5 py-2 text-xs transition-colors first:mt-0",
                  fromTeam && !isNote ? "bg-white/15 hover:bg-white/25" : "bg-background/70 hover:bg-background",
                )}
              >
                <FileText className="h-5 w-5 shrink-0 opacity-80" />
                <span className="min-w-0 flex-1">
                  <span className="block truncate font-medium">{file.uploaded_file_name}</span>
                  <span className="opacity-70">{formatFileSize(file.file_size)}</span>
                </span>
                <Download className="h-3.5 w-3.5 shrink-0 opacity-70" />
              </a>
            ))}
          </div>
        )}

        {isLastInGroup && (
          <span className="mt-1 px-1 text-[10px] tabular-nums text-muted-foreground">
            {formatClock(message.created_at, locale)}
            {message.edited_at && ` · ${t.ticketDetail.communications.editedAt}`}
          </span>
        )}
      </div>
    </div>
  );
}
