---
type Props = {
  href?: string;
  title: string;
  summary?: string;
  imageUrl?: string;
  dateLabel?: string;
  viewsLabel?: string;
  sourceLabel: string;
  isExternal?: boolean;
  linkAttrs?: Record<string, any>;
  mode?: "link" | "modal";
};

const {
  href,
  title,
  summary,
  imageUrl,
  dateLabel,
  viewsLabel,
  sourceLabel,
  isExternal,
  linkAttrs,
  mode = "link",
} = Astro.props;

function truncate(s: string, n: number) {
  const t = (s || "").trim();
  if (!t) return "";
  if (t.length <= n) return t;
  // ASCII ellipsis to avoid encoding issues in generated HTML.
  return `${t.slice(0, Math.max(0, n - 3)).trimEnd()}...`;
}

const summaryText = truncate(summary || "", 180);

const Element = mode === "modal" ? "button" : "a";
const elementProps = mode === "modal" 
  ? { type: "button", ...linkAttrs }
  : { 
      href, 
      target: isExternal ? "_blank" : undefined, 
      rel: isExternal ? "noopener noreferrer" : undefined,
      ...linkAttrs
    };

---

<Element
  class="card"
  {...elementProps}
>
  <div class="card-media">
    {imageUrl ? (
      <div class="img-shimmer-wrap">
        <img src={imageUrl} alt="" loading="lazy" class="img-loading" />
      </div>
    ) : (
      <div class="card-placeholder" />
    )}
  </div>

  <div class="card-body">
    <div class="card-content">
      <h3 class="card-title">{title}</h3>
      {summaryText ? <p class="card-summary">{summaryText}</p> : null}
    </div>

    <div class="card-footer">
      <span class="muted card-date">{dateLabel || ""}</span>
      <span class="muted card-views" aria-hidden={viewsLabel ? undefined : "true"}>
        {viewsLabel || ""}
      </span>
      <span class={`pill pill-${sourceLabel}`}>{sourceLabel}</span>
    </div>
  </div>
</Element>
