import type { ComponentType } from "react";
import type { Post } from "../../types/post";
import { TextBubble } from "./bubbles/TextBubble";
import { FileDocBubble } from "./bubbles/FileDocBubble";
import { ImageBubble } from "./bubbles/ImageBubble";
import { ImageWithTextBubble } from "./bubbles/ImageWithTextBubble";
import { AlbumBubble } from "./bubbles/AlbumBubble";
import { VideoBubble } from "./bubbles/VideoBubble";
import { LinkPreviewCard } from "./LinkPreviewCard";
import { formatDateTime } from "./utils/formatTime";
import { FavoriteButton } from "../../favorites/FavoriteButton";
import { BubbleAttachmentDownloadButton } from "./BubbleAttachmentDownloadButton";

export type MessageBubbleVariant = "default" | "latest";

type BubbleComponent = ComponentType<{
  post: Post;
  variant?: MessageBubbleVariant;
}>;

export function pickBubble(post: Post): BubbleComponent {
  const a = post.attachments;
  if (a.length === 0) return TextBubble;
  if (a.length >= 2 && a.every((x) => x.kind === "image")) return AlbumBubble;
  const only = a[0];
  if (only.kind === "video") return VideoBubble;
  if (only.kind === "image") {
    return post.text ? ImageWithTextBubble : ImageBubble;
  }
  return FileDocBubble;
}

export function MessageBubble({
  post,
  fluid = false,
  variant = "default",
  onFavoriteChange,
}: {
  post: Post;
  /** When true, fill the parent container instead of applying the standalone
   *  feed max-widths. Used by the desktop 3-column masonry on the home page. */
  fluid?: boolean;
  /** Desktop latest-updates cards follow the dedicated Figma masonry design. */
  variant?: MessageBubbleVariant;
  onFavoriteChange?: (postId: string, favorited: boolean) => void;
}) {
  const Bubble = pickBubble(post);
  const isVisual =
    Bubble === AlbumBubble ||
    Bubble === VideoBubble ||
    Bubble === ImageBubble ||
    Bubble === ImageWithTextBubble;
  const isFileBubble = Bubble === FileDocBubble;
  const isLatestVariant = variant === "latest";
  const isLatestFileCard = isLatestVariant && isFileBubble;

  return (
    <div
      id={`post-${post.id}`}
      className={
        fluid
          ? "w-full scroll-mt-[82px] md:scroll-mt-[98px]"
          : "mx-auto w-full max-w-[358px] scroll-mt-[82px] md:max-w-[680px] md:scroll-mt-[98px] lg:max-w-[900px] xl:max-w-[1120px]"
      }
    >
      <article
        className={`relative w-full overflow-hidden rounded-2xl bg-[#272632] text-left shadow-sm ${
          isVisual || isLatestFileCard ? "p-0" : "px-4 py-3"
        }`}
      >
        {isLatestVariant && !isFileBubble ? (
          <FavoriteButton
            resourceId={post.id}
            size="sm"
            className="absolute z-20 bottom-4 right-4 shadow-lg shadow-black/30"
            onFavoriteChange={(favorited) =>
              onFavoriteChange?.(post.id, favorited)
            }
          />
        ) : null}

        <Bubble post={post} variant={variant} />

        {post.linkPreview ? (
          <div className={isVisual ? "px-4 pt-3" : "mt-3"}>
            <LinkPreviewCard preview={post.linkPreview} />
          </div>
        ) : null}

        {!isLatestVariant ? (
          <div
            className={`flex items-center justify-between gap-3 ${
              isVisual ? "px-4 pb-3 pt-3" : "mt-3"
            }`}
          >
            <time
              dateTime={post.publishedAt}
              className="min-w-0 truncate text-[12px] leading-[19px] text-[#A8A9AE]"
            >
              {formatDateTime(post.publishedAt)}
            </time>
            <div className="flex shrink-0 items-center gap-2">
              <FavoriteButton
                resourceId={post.id}
                size="sm"
                onFavoriteChange={(favorited) =>
                  onFavoriteChange?.(post.id, favorited)
                }
              />
              {isFileBubble && post.attachments.length === 1 ? (
                <BubbleAttachmentDownloadButton
                  postId={post.id}
                  attachment={post.attachments[0]}
                />
              ) : null}
            </div>
          </div>
        ) : null}

        {isLatestVariant && !isFileBubble ? (
          <time
            dateTime={post.publishedAt}
            className={`block text-right text-[12px] leading-[19px] text-[#A8A9AE] ${
              isVisual ? "px-4 pb-3 pt-0.5" : "mt-3"
            }`}
          >
            {formatDateTime(post.publishedAt)}
          </time>
        ) : null}
      </article>
    </div>
  );
}
