import Link from "next/link";
import { formatDate } from "@/lib/format";
import { games } from "@/lib/games";
import type { DevblogPost } from "@/lib/devblog";

type Props = {
  posts: DevblogPost[];
  /** Heading level for each entry, so the page outline stays valid. */
  as?: "h2" | "h3";
  /** Show the related game as a tag. Off on a game page (redundant there). */
  showGame?: boolean;
};

/**
 * The devblog entry list. Shared by /devblog, the home page teaser and the
 * "latest articles" block of a game page, so an entry looks identical
 * everywhere it appears.
 */
export function PostList({ posts, as: Tag = "h2", showGame = true }: Props) {
  return (
    <ul className="border-t border-border">
      {posts.map((post) => {
        const gameTitle = post.game
          ? (games.find((g) => g.slug === post.game)?.title ?? post.game)
          : null;

        return (
          <li key={post.slug}>
            {/* The row is a large target with no border of its own, so the
                hover has to be built from three small moves rather than one
                box: a rule that draws down the left edge, the whole block
                nudged away from it, and the rule under it turning accent. */}
            <Link
              href={`/devblog/${post.slug}`}
              className="group relative block border-b border-border py-8 pl-0 transition-colors duration-300 hover:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
            >
              <span
                aria-hidden
                className="absolute bottom-0 left-0 top-0 w-px origin-top scale-y-0 bg-accent transition-transform duration-500 ease-out group-hover:scale-y-100"
              />

              <div className="transition-transform duration-300 ease-out group-hover:translate-x-4">
                <div className="mb-3 flex flex-col gap-2 sm:flex-row sm:items-baseline sm:justify-between">
                  <Tag className="font-display text-2xl tracking-wider transition-colors duration-300 group-hover:text-accent sm:text-3xl">
                    {post.title.toUpperCase()}
                  </Tag>
                  <time
                    dateTime={post.date}
                    className="shrink-0 text-xs tracking-widest text-foreground-muted"
                  >
                    {formatDate(post.date)}
                  </time>
                </div>

                {post.excerpt && (
                  <p className="max-w-2xl leading-relaxed text-foreground-muted">
                    {post.excerpt}
                  </p>
                )}

                <div className="mt-4 flex flex-wrap items-center gap-4">
                  <span className="inline-flex items-center gap-2 font-display text-xs tracking-widest text-foreground-muted transition-colors duration-300 group-hover:text-accent">
                    READ
                    <span
                      aria-hidden
                      className="inline-block transition-transform duration-300 ease-out group-hover:translate-x-1"
                    >
                      →
                    </span>
                  </span>
                  {showGame && gameTitle && (
                    <span className="border border-accent/40 px-2 py-1 text-[0.65rem] uppercase tracking-widest text-accent transition-colors duration-300 group-hover:border-accent">
                      {gameTitle}
                    </span>
                  )}
                </div>
              </div>
            </Link>
          </li>
        );
      })}
    </ul>
  );
}
