import { Download, LoaderCircle } from "lucide-react";
import { m } from "framer-motion";
import { Link } from "react-router-dom";
import type { Resource } from "../api";
import { assetUrl } from "../api";
import { useI18n } from "../i18n";
import { useMemo, useState } from "react";
import { formatDateYmd } from "../utils/format";
import { DownloadCloudIcon } from "./icons/DownloadCloudIcon";
import { officialRecommendationCoverFallbacks } from "./FigmaBanner";
import {
  downloadAttachment,
  downloadFile,
} from "./messageStream/utils/downloadFile";
import { useToast } from "./Toast";

function isPlaceholderAsset(path: string | undefined | null) {
  return !path || path.includes("placeholder-cover");
}

const CARD_BASE_CLASS =
  "group flex shrink-0 flex-col overflow-hidden rounded-xl border bg-[#1D1E23] transition hover:border-ark-gold/55 hover:shadow-lg hover:shadow-black/30";

const CARD_HOVER_SPRING = {
  type: "spring",
  stiffness: 380,
  damping: 26,
} as const;

const CARD_CAROUSEL_SIZE_CLASS =
  "w-[208px] md:w-[240px] lg:w-[246.4px] min-[1100px]:max-xl:w-[273px] xl:w-[246.4px]";

const CARD_GRID_SIZE_CLASS = "w-full max-w-[360px] md:max-w-none";

type RecommendedResource = Resource & {
  downloadPostId?: string;
  downloadAttachmentId?: string;
};

export function RecommendedCard({
  r,
  visualIndex = 0,
  useFigmaDesign = false,
  layout = "carousel",
}: {
  r: RecommendedResource;
  visualIndex?: number;
  useFigmaDesign?: boolean;
  layout?: "carousel" | "grid";
}) {
  const { t } = useI18n();
  const { showToast } = useToast();
  const [isDownloading, setIsDownloading] = useState(false);
  const figmaCover =
    officialRecommendationCoverFallbacks[
      visualIndex % officialRecommendationCoverFallbacks.length
    ];
  const cover = useMemo(() => {
    const original = r.coverImage || r.previewUrl;
    if (isPlaceholderAsset(original)) {
      return useFigmaDesign ? "" : figmaCover;
    }
    return assetUrl(original);
  }, [figmaCover, r.coverImage, r.previewUrl, useFigmaDesign]);
  const displayTitle = r.title;
  const displayCategoryName = r.categoryName;
  const dateStr = formatDateYmd(r.updatedAt);
  const dateTime = r.updatedAt;

  const dl =
    r.isDownloadable && (r.fileUrl || r.previewUrl)
      ? assetUrl(r.fileUrl || r.previewUrl)
      : "";

  const handleDownload = async () => {
    if (isDownloading) return;
    setIsDownloading(true);
    try {
      if (r.downloadPostId && r.downloadAttachmentId) {
        await downloadAttachment(
          r.downloadPostId,
          r.downloadAttachmentId,
          displayTitle,
        );
      } else {
        await downloadFile(dl, displayTitle);
      }
    } catch {
      showToast(t("downloadFail"), "error");
    } finally {
      setIsDownloading(false);
    }
  };

  return (
    <m.article
      whileHover={{ y: -4 }}
      transition={CARD_HOVER_SPRING}
      className={`relative ${CARD_BASE_CLASS} ${
        layout === "grid" ? CARD_GRID_SIZE_CLASS : CARD_CAROUSEL_SIZE_CLASS
      } ${
        useFigmaDesign
          ? "border-[#27292E]"
          : "border-transparent md:border-ark-line md:bg-ark-panel"
      }`}
    >
      <Link
        to={`/resource/${r.id}`}
        aria-label={displayTitle}
        className="absolute inset-0 z-10 outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/70"
      />
      <div className="relative block aspect-[208/108] overflow-hidden bg-[#111116]">
        {cover ? (
          <img
            src={cover}
            alt=""
            className="ark-img-fade h-full w-full object-cover transition duration-300 group-hover:scale-[1.02]"
            loading="lazy"
            decoding="async"
            onLoad={(e) => e.currentTarget.classList.add("is-loaded")}
          />
        ) : (
          <div className="h-full w-full bg-gradient-to-br from-neutral-900 to-neutral-950" />
        )}
        {!useFigmaDesign && r.badgeLabel ? (
          <span className="absolute left-3 top-3 rounded-md bg-ark-gold px-2.5 py-1 text-xs font-semibold text-black">
            {r.badgeLabel}
          </span>
        ) : null}
      </div>
      <div
        className={
          useFigmaDesign
            ? "flex h-[131px] flex-col px-4 py-3"
            : "flex min-h-[131px] flex-1 flex-col p-4 pt-3 md:min-h-[121px]"
        }
      >
        <div className="flex flex-col gap-1.5">
          <h3 className="text-[15px] font-semibold leading-[21.72px] text-white line-clamp-2 transition-colors group-hover:text-ark-gold2 md:text-base md:font-bold md:leading-snug">
            {displayTitle}
          </h3>
          {useFigmaDesign ? (
            <div className="truncate text-[12px] font-normal leading-[17.376px] text-[#A8A9AE]">
              {displayCategoryName}
            </div>
          ) : null}
        </div>
        <div
          className={
            useFigmaDesign
              ? "mt-auto flex h-10 items-end justify-between gap-2"
              : "mt-auto flex items-center justify-between gap-2 pt-4 text-[12px] leading-[17.38px] text-ark-muted"
          }
        >
          <div
            className={
              useFigmaDesign
                ? "min-w-0 truncate pb-[1px] text-[12px] font-normal leading-[17.376px] text-[#A8A9AE]"
                : "min-w-0 truncate"
            }
          >
            {useFigmaDesign ? null : (
              <>
                <span className="text-neutral-400">{displayCategoryName}</span>
                <span className="mx-1.5 text-ark-line">·</span>
              </>
            )}
            <time dateTime={dateTime}>{dateStr}</time>
          </div>
          {dl ? (
            <button
              type="button"
              className={
                useFigmaDesign
                  ? "relative z-20 flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[#191921] text-ark-gold outline-none transition hover:bg-[#22232D] active:scale-95 focus-visible:ring-2 focus-visible:ring-ark-gold/80 disabled:cursor-wait"
                  : "relative z-20 shrink-0 rounded-lg p-1 text-ark-gold outline-none transition hover:bg-ark-gold/10 active:scale-95 focus-visible:ring-2 focus-visible:ring-ark-gold/80 disabled:cursor-wait"
              }
              title={isDownloading ? t("downloading") : t("download")}
              aria-label={isDownloading ? t("downloading") : t("download")}
              aria-busy={isDownloading}
              disabled={isDownloading}
              onClick={(e) => {
                e.preventDefault();
                e.stopPropagation();
                void handleDownload();
              }}
            >
              {isDownloading ? (
                <LoaderCircle
                  className="h-5 w-5 animate-spin"
                  strokeWidth={2.2}
                />
              ) : useFigmaDesign ? (
                <DownloadCloudIcon className="h-6 w-6" />
              ) : (
                <Download className="h-5 w-5" strokeWidth={2.2} />
              )}
            </button>
          ) : null}
        </div>
      </div>
    </m.article>
  );
}

export function ComingSoonRecommendedCard({
  visualIndex = 0,
}: {
  visualIndex?: number;
}) {
  const cover =
    officialRecommendationCoverFallbacks[
      visualIndex % officialRecommendationCoverFallbacks.length
    ];

  return (
    <article
      className={`${CARD_BASE_CLASS} ${CARD_CAROUSEL_SIZE_CLASS} cursor-default border-transparent opacity-95 md:border-ark-line md:bg-ark-panel`}
      aria-label="即将到来"
    >
      <div className="relative block h-[108px] overflow-hidden bg-black md:aspect-[246.4/138.6] md:h-auto">
        <img
          src={cover}
          alt=""
          className="h-full w-full object-cover opacity-75 grayscale-[15%]"
          loading="lazy"
          decoding="async"
        />
        <span className="absolute left-3 top-3 rounded-md bg-ark-gold px-2.5 py-1 text-xs font-semibold text-black">
          即将到来
        </span>
      </div>
      <div className="flex min-h-[131px] flex-1 flex-col p-4 pt-3 md:min-h-[121px]">
        <div className="text-[15px] font-semibold leading-[21.72px] text-white line-clamp-2 md:text-base md:font-bold md:leading-snug">
          即将到来
        </div>
        <div className="mt-auto pt-4 text-xs text-ark-muted">
          更多内容准备中
        </div>
      </div>
    </article>
  );
}
