"use client";

import { Check, Copy, RefreshCw } from "lucide-react";
import { useState } from "react";

import { AssistantMarkdown } from "@/components/chat/assistant-markdown";
import { Button } from "@/components/ui/button";
import { authFetch } from "@/lib/auth/client";
import type { Attachment } from "@/lib/chat/types";
import type { ChatMessage as ChatMessageType } from "@/lib/chat/types";

type ChatMessageProps = {
  canRetry: boolean;
  message: ChatMessageType;
  onRetry: () => void;
};

export function ChatMessage({ canRetry, message, onRetry }: ChatMessageProps) {
  const [copied, setCopied] = useState(false);
  const [downloadError, setDownloadError] = useState(false);

  async function downloadAttachment(attachment: Attachment) {
    setDownloadError(false);

    try {
      const response = await authFetch(`/api/attachments/${attachment.id}`, {
        cache: "no-store",
      });
      if (!response.ok) throw new Error("Attachment download failed");

      const objectUrl = URL.createObjectURL(await response.blob());
      try {
        const link = document.createElement("a");
        link.href = objectUrl;
        link.download = attachment.name;
        link.click();
      } finally {
        URL.revokeObjectURL(objectUrl);
      }
    } catch {
      setDownloadError(true);
    }
  }

  if (message.role === "user") {
    return (
      <article className="flex justify-end py-3">
        <div className="max-w-[85%] rounded-2xl rounded-br-md bg-muted px-4 py-2.5 text-sm leading-6 md:max-w-[75%]">
          <p className="whitespace-pre-wrap">{message.content}</p>
          {message.attachments?.map((attachment) => (
            <button
              aria-label={`Скачать ${attachment.name}`}
              className="mt-2 block text-left text-xs underline"
              key={attachment.id}
              onClick={() => void downloadAttachment(attachment)}
              type="button"
            >
              {attachment.name}
            </button>
          ))}
          {downloadError ? (
            <p className="mt-2 text-xs text-destructive" role="alert">
              Не удалось скачать вложение
            </p>
          ) : null}
        </div>
      </article>
    );
  }

  return (
    <article
      aria-live="polite"
      className="group py-4"
      data-status={message.status}
    >
      <div className="flex gap-3">
        <div className="mt-0.5 grid size-7 shrink-0 place-items-center rounded-lg bg-primary text-[10px] font-semibold text-primary-foreground">
          AI
        </div>
        <div className="min-w-0 flex-1">
          {message.status === "streaming" && !message.content ? (
            <span
              aria-label="Модель формирует ответ"
              className="inline-flex items-center gap-1 py-2"
              role="status"
            >
              {[0, 1, 2].map((index) => (
                <span
                  aria-hidden="true"
                  className="size-1.5 animate-bounce rounded-full bg-muted-foreground motion-reduce:animate-none"
                  data-testid="response-placeholder-dot"
                  key={index}
                  style={{ animationDelay: `${index * 120}ms` }}
                />
              ))}
            </span>
          ) : message.content ? (
            <AssistantMarkdown
              content={message.content}
              isStreaming={message.status === "streaming"}
            />
          ) : null}
          {message.status === "stopped" ? (
            <p className="mt-2 text-xs text-muted-foreground">Генерация остановлена</p>
          ) : null}
          {message.content || canRetry ? (
            <div className="mt-2 flex items-center gap-1">
              {message.content ? (
                <Button
                  aria-label="Копировать ответ"
                  onClick={async () => {
                    await navigator.clipboard.writeText(message.content);
                    setCopied(true);
                  }}
                  size="icon-sm"
                  title="Копировать ответ"
                  type="button"
                  variant="ghost"
                >
                  {copied ? (
                    <Check aria-hidden="true" />
                  ) : (
                    <Copy aria-hidden="true" />
                  )}
                </Button>
              ) : null}
              {canRetry ? (
                <Button
                  aria-label="Повторить запрос"
                  onClick={onRetry}
                  size="icon-sm"
                  title="Повторить запрос"
                  type="button"
                  variant="ghost"
                >
                  <RefreshCw aria-hidden="true" />
                </Button>
              ) : null}
            </div>
          ) : null}
        </div>
      </div>
    </article>
  );
}
