---
import type { CollectionEntry } from 'astro:content';
import EntryThumbnail from './EntryThumbnail.astro';
import VideoThumbnail from './VideoThumbnail.astro';
import {
  PROJECT_THUMBNAIL,
  articlePath,
  entrySlug,
  getHeaderVideo,
  isExternal,
  projectCard,
} from '../lib/site';

interface Props {
  projects: CollectionEntry<'work'>[];
  // Opt-in: eagerly load thumbnails that are reliably above the fold. Lists
  // below substantial content should leave this at zero.
  eagerFirstThumbnail?: boolean;
  eagerThumbnailCount?: number;
}

const {
  projects,
  eagerFirstThumbnail = false,
  eagerThumbnailCount = eagerFirstThumbnail ? 1 : 0,
} = Astro.props;

// Project and article are the same entry now. A card links to its article when
// the entry has a published (non-draft) `article` facet; an entry without one
// is a project card with no article page. When that article has a header video,
// the card thumbnail becomes a click-to-play poster (the card body still opens
// the project site).
function publishedArticleHref(project: CollectionEntry<'work'>) {
  const article = project.data.article;
  if (!article || article.draft) return undefined;
  return articlePath(project);
}

// The whole card opens the project's website: the first link that isn't a
// download (Source / Live / Demo / Site / package page, in author order).
// The Open button is that link, and its overlay makes the entire card
// clickable. Projects without such a link have no Open button and are not
// clickable; their article, if any, is reachable through the Article link.
function websiteUrl(project: CollectionEntry<'work'>) {
  return project.data.links.find((link) => !link.download)?.url;
}
---

<ol class="project-list">
  {
    projects.map((project, index) => {
      const anchor = entrySlug(project);
      const titleId = `${anchor}-title`;
      const card = projectCard(project);
      const essayHref = publishedArticleHref(project);
      const headerVideo = essayHref ? getHeaderVideo(project) : undefined;
      const website = websiteUrl(project);
      const websiteExternal = website ? isExternal(website) : false;
      const eager = index < eagerThumbnailCount;

      return (
        <li class="project-card" id={anchor}>
          {headerVideo ? (
            <VideoThumbnail
              class="entry-thumbnail project-thumbnail"
              variant="card"
              poster={card.thumbnail.src}
              alt={card.thumbnail.alt}
              video={headerVideo}
              widths={PROJECT_THUMBNAIL.widths}
              sizes={PROJECT_THUMBNAIL.sizes}
              loading={eager ? 'eager' : 'lazy'}
              fetchpriority={eager && index === 0 ? 'high' : undefined}
            />
          ) : (
            <EntryThumbnail
              src={card.thumbnail.src}
              alt={card.thumbnail.alt}
              class="project-thumbnail"
              widths={PROJECT_THUMBNAIL.widths}
              sizes={PROJECT_THUMBNAIL.sizes}
              loading={eager ? 'eager' : 'lazy'}
              fetchpriority={eager && index === 0 ? 'high' : undefined}
            />
          )}
          <article class="project-card__summary">
            <div class="project-card__head">
              <h3 id={titleId}>{card.title}</h3>
              <p class="project-description">{card.description}</p>
            </div>
            {(essayHref || website) && (
              <div class="project-card__actions">
                {essayHref && (
                  <a
                    class="project-article-link"
                    href={essayHref}
                    aria-label={`Read the article about ${card.title}`}
                  >
                    Article
                    <span aria-hidden="true">→</span>
                  </a>
                )}
                {website && (
                  <a
                    class="project-card__open"
                    href={website}
                    rel={websiteExternal ? 'noopener noreferrer' : undefined}
                    target={websiteExternal ? '_blank' : undefined}
                    aria-label={
                      websiteExternal
                        ? `Open the ${card.title} site in a new tab`
                        : `Open ${card.title}`
                    }
                  >
                    Open
                    <span aria-hidden="true">↗</span>
                  </a>
                )}
              </div>
            )}
          </article>
        </li>
      );
    })
  }
</ol>
