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

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

const CARD_CLASS =
  "group flex w-[232px] shrink-0 flex-col overflow-hidden rounded-xl border border-ark-line bg-ark-panel transition hover:border-ark-gold/55 max-[439px]:w-[232px] min-[440px]:w-[230px] sm:w-[240px] lg:w-[246.4px] min-[1100px]:max-xl:w-[273px] xl:w-[246.4px]";

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

export function RecommendedCard({
  r,
  visualIndex = 0,
}: {
  r: RecommendedResource;
  visualIndex?: number;
}) {
  const { t } = useI18n();
  const [isDownloading, setIsDownloading] = useState(false);
  const cover = useMemo(() => {
    const original = r.coverImage || r.previewUrl;
    if (isPlaceholderAsset(original)) {
      return officialRecommendationCoverFallbacks[
        visualIndex % officialRecommendationCoverFallbacks.length
      ];
    }
    return assetUrl(original);
  }, [r.coverImage, r.previewUrl, visualIndex]);
  const dateStr = formatDateYmd(r.updatedAt);

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

  return (
    <article className={CARD_CLASS}>
      <Link
        to={`/resource/${r.id}`}
        className="relative block aspect-[246.4/138.6] overflow-hidden bg-black"
      >
        {cover ? (
          <img
            src={cover}
            alt=""
            className="h-full w-full object-cover transition duration-300 group-hover:scale-[1.02]"
            loading="lazy"
          />
        ) : (
          <div className="h-full w-full bg-gradient-to-br from-neutral-900 to-neutral-950" />
        )}
        {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}
      </Link>
      <div className="flex min-h-[121px] flex-1 flex-col p-4 pt-3">
        <Link
          to={`/resource/${r.id}`}
          className="text-base font-bold leading-snug text-white line-clamp-2 hover:text-ark-gold2"
        >
          {r.title}
        </Link>
        <div className="mt-auto flex items-center justify-between gap-2 pt-4 text-xs text-ark-muted">
          <div className="min-w-0 truncate">
            <span className="text-neutral-400">{r.categoryName}</span>
            <span className="mx-1.5 text-ark-line">·</span>
            <time dateTime={r.updatedAt}>{dateStr}</time>
          </div>
          {dl ? (
            <button
              type="button"
              className="shrink-0 rounded-lg p-1 text-ark-gold outline-none hover:bg-ark-gold/10 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={async (e) => {
                e.preventDefault();
                e.stopPropagation();
                if (isDownloading) return;
                setIsDownloading(true);
                try {
                  if (r.downloadPostId && r.downloadAttachmentId) {
                    await downloadAttachment(
                      r.downloadPostId,
                      r.downloadAttachmentId,
                      r.title,
                    );
                    return;
                  }
                  try {
                    await postJSON(`/api/resources/${r.id}/download`, {});
                  } catch {
                    /* ignore */
                  }
                  await downloadFile(dl, r.title);
                } catch {
                  /* ignore */
                } finally {
                  setIsDownloading(false);
                }
              }}
            >
              {isDownloading ? (
                <LoaderCircle
                  className="h-5 w-5 animate-spin"
                  strokeWidth={2.2}
                />
              ) : (
                <Download className="h-5 w-5" strokeWidth={2.2} />
              )}
            </button>
          ) : null}
        </div>
      </div>
    </article>
  );
}

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

  return (
    <article
      className={`${CARD_CLASS} cursor-default opacity-95`}
      aria-label="即将到来"
    >
      <div className="relative block aspect-[246.4/138.6] overflow-hidden bg-black">
        <img
          src={cover}
          alt=""
          className="h-full w-full object-cover opacity-75 grayscale-[15%]"
          loading="lazy"
        />
        <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-[121px] flex-1 flex-col p-4 pt-3">
        <div className="text-base font-bold leading-snug text-white line-clamp-2">
          即将到来
        </div>
        <div className="mt-auto pt-4 text-xs text-ark-muted">
          更多内容准备中
        </div>
      </div>
    </article>
  );
}
