import { LoaderCircle } from "lucide-react";
import { DownloadCloudIcon } from "../icons/DownloadCloudIcon";
import { useState, type MouseEvent } from "react";
import { useI18n } from "../../i18n";
import type { Attachment } from "../../types/post";
import { downloadAttachment } from "./utils/downloadFile";
import { formatBytes } from "./utils/formatBytes";
import { useToast } from "../Toast";

type AttachmentDownloadPillProps = {
  postId: string;
  attachment: Attachment;
  leadingLabel?: string;
  className?: string;
  /**
   * When true, the pill scales with its host container's width via container-
   * query units (clamped 22-30px). The host element must establish a query
   * container with `style={{ containerType: "inline-size" }}`. Use this on
   * album tiles so the pill shrinks on small thumbnails in mixed layouts.
   * Defaults to false (fixed 30px) for standalone images/videos.
   */
  adaptive?: boolean;
  /**
   * Visual size. `sm` (default, 30 px tall) for inline tiles where space is
   * tight. `lg` (44 px tall with a 24 px icon and 14 px text) for overlay
   * surfaces like the image lightbox or fullscreen video player where the
   * affordance can breathe and should feel touch-friendly.
   * Ignored when `adaptive` is set.
   */
  size?: "sm" | "lg";
};

export function AttachmentDownloadPill({
  postId,
  attachment,
  leadingLabel,
  className = "absolute left-2 top-2",
  adaptive = false,
  size = "sm",
}: AttachmentDownloadPillProps) {
  const { t } = useI18n();
  const { showToast } = useToast();
  const [isDownloading, setIsDownloading] = useState(false);

  const handleDownload = async (e: MouseEvent<HTMLButtonElement>) => {
    e.stopPropagation();
    if (isDownloading) return;
    setIsDownloading(true);
    try {
      await downloadAttachment(postId, attachment.id, attachment.filename);
    } catch {
      showToast(t("downloadFail"), "error");
    } finally {
      setIsDownloading(false);
    }
  };

  const isLg = !adaptive && size === "lg";

  const fontCls = adaptive
    ? "text-[clamp(10px,7cqw,12px)]"
    : isLg
      ? "text-[14px] font-medium"
      : "text-[12px]";

  const squareCls = adaptive
    ? "h-[clamp(22px,18cqw,30px)] w-[clamp(22px,18cqw,30px)]"
    : isLg
      ? "h-[44px] w-[44px]"
      : "h-[30px] w-[30px]";

  const iconCls = adaptive
    ? "h-[clamp(13px,11cqw,18px)] w-[clamp(13px,11cqw,18px)]"
    : isLg
      ? "h-[22px] w-[22px]"
      : "h-[18px] w-[18px]";

  const textBoxCls = adaptive
    ? "h-[clamp(22px,18cqw,30px)] px-[clamp(6px,6cqw,10px)]"
    : isLg
      ? "h-[44px] px-4"
      : "h-[30px] px-2.5";

  return (
    <button
      type="button"
      onClick={handleDownload}
      disabled={isDownloading}
      className={`group z-10 inline-flex overflow-hidden rounded-full bg-black/80 ${fontCls} text-white shadow-lg ring-1 ring-inset ring-white/20 backdrop-blur-md transition hover:bg-black/90 disabled:cursor-wait ${className}`}
      aria-label={
        isDownloading ? t("downloading") : `Download ${attachment.filename}`
      }
      aria-busy={isDownloading}
    >
      <span
        className={`flex items-center justify-center bg-[#545454]/50 transition group-hover:bg-[#545454]/70 ${squareCls}`}
      >
        {isDownloading ? (
          <LoaderCircle
            className={`${iconCls} animate-spin`}
            strokeWidth={2.3}
          />
        ) : (
          <DownloadCloudIcon className={iconCls} />
        )}
      </span>
      <span className={`flex items-center gap-1 ${textBoxCls}`}>
        {isDownloading ? (
          t("downloading")
        ) : (
          <>
            {leadingLabel ? (
              <>
                <span>{leadingLabel}</span>
                <span className="opacity-60">·</span>
              </>
            ) : null}
            <span>{formatBytes(attachment.sizeBytes)}</span>
          </>
        )}
      </span>
    </button>
  );
}
