import Link from "next/link";
import { ChevronRight, Clock3 } from "lucide-react";

import { Badge } from "@/components/ui/Badge";
import { StatusDot } from "@/components/ui/StatusDot";
import type { ProjectResponse } from "@/lib/api/types";
import {
  formatProjectUpdatedAt,
  pendingReviewCount,
} from "@/lib/projects/projects";
import { cardClass, cn, focusRing } from "@/lib/ui/variants";

interface ProjectCardProps {
  project: ProjectResponse;
  compact?: boolean;
}

// 缺一句话故事时的中性占位——避免卡片正文塌陷成空白（P3-2）。
const LOGLINE_PLACEHOLDER = "还没有一句话故事，进入写作台补上一句梗概。";

// 书脊/封面暖色板：全部取自现有语义 token（朱砂/琥珀），仅调透明度，无硬编码 hex。
const COVER_TINTS = [
  "bg-[var(--color-cinnabar-wash)] text-cinnabar",
  "bg-cinnabar/10 text-cinnabar",
  "bg-cinnabar/[0.16] text-cinnabar",
  "bg-overdue/10 text-overdue",
  "bg-overdue/[0.18] text-overdue",
  "bg-surface-strong text-body-strong",
] as const;

// 由 id/title 确定性取暖色底色块（djb2 变体哈希，同一本书永远同一色）。
function coverTint(seed: string): string {
  let hash = 0;
  for (const ch of seed) hash = (hash * 31 + (ch.codePointAt(0) ?? 0)) >>> 0;
  return COVER_TINTS[hash % COVER_TINTS.length] ?? COVER_TINTS[0];
}

// 取书名首个字符作封面字（Array.from 保证 CJK/emoji 不被截断）。
function coverGlyph(title: string): string {
  return Array.from(title.trim())[0] ?? "书";
}

interface CoverProps {
  project: ProjectResponse;
  size: "sm" | "md";
}

// 书脊色块：填补此前的空白，给每本书一个稳定的视觉锚点。
function Cover({ project, size }: CoverProps) {
  const tint = coverTint(project.id || project.title || "");
  const box = size === "md" ? "h-12 w-12 text-title-lg" : "h-10 w-10 text-title-md";
  return (
    <span
      aria-hidden="true"
      className={cn(
        "flex shrink-0 items-center justify-center rounded-md font-serif",
        box,
        tint,
      )}
    >
      {coverGlyph(project.title || "")}
    </span>
  );
}

// 作品卡（UX §6.1）：书脊色块 + 书名衬线 + 一句话故事 + 元信息行。
// M1 无字数/章数端点 → 不展示该统计（避免编造 API）。
export function ProjectCard({ project, compact = false }: ProjectCardProps) {
  const pendingCount = pendingReviewCount(project);
  const updatedLabel = formatProjectUpdatedAt(project.updated_at);
  const title = project.title || "未命名作品";
  const logline = project.logline?.trim();

  if (compact) {
    return (
      <Link
        href={`/projects/${project.id}/write`}
        className={cardClass({
          tone: "card",
          interactive: true,
          className: cn("group flex items-center gap-4 p-4", focusRing),
        })}
      >
        <Cover project={project} size="sm" />
        <span className="min-w-0 flex-1">
          <span className="block truncate font-serif text-title-md text-ink">
            〈{title}〉
          </span>
          <span className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-caption">
            <GenreBadge genre={project.genre} />
            <PendingNote count={pendingCount} />
            <span className="min-w-0 flex-1 truncate text-muted-soft">
              {logline ?? LOGLINE_PLACEHOLDER}
            </span>
          </span>
          <span className="mt-1 flex items-center gap-1 font-mono text-2xs text-muted-soft">
            <Clock3 className="h-3 w-3" aria-hidden="true" />
            最近编辑 {updatedLabel}
          </span>
        </span>
        <ChevronRight
          className="h-4 w-4 shrink-0 text-muted-soft transition-colors duration-fast ease-standard group-hover:text-cinnabar"
          aria-hidden="true"
        />
      </Link>
    );
  }

  return (
    <Link
      href={`/projects/${project.id}/write`}
      className={cardClass({
        tone: "card",
        interactive: true,
        className: cn("group flex h-full flex-col gap-4 p-5", focusRing),
      })}
    >
      <div className="flex items-center gap-3">
        <Cover project={project} size="md" />
        <h2 className="min-w-0 flex-1 truncate font-serif text-title-lg text-ink">
          〈{title}〉
        </h2>
        <ChevronRight
          className="h-4 w-4 shrink-0 text-muted-soft transition-colors duration-fast ease-standard group-hover:text-cinnabar"
          aria-hidden="true"
        />
      </div>
      <p
        className={cn(
          "line-clamp-2 min-h-[3rem] text-body leading-6",
          logline ? "text-body" : "text-muted-soft",
        )}
      >
        {logline ?? LOGLINE_PLACEHOLDER}
      </p>
      <div className="mt-auto flex flex-wrap items-center gap-x-3 gap-y-2">
        <GenreBadge genre={project.genre} />
        <PendingNote count={pendingCount} />
        <span className="ml-auto flex items-center gap-1 font-mono text-caption text-muted-soft">
          <Clock3 className="h-3.5 w-3.5" aria-hidden="true" />
          {updatedLabel}
        </span>
      </div>
    </Link>
  );
}

// 题材徽章：有值用中性徽章，缺失给稳定占位而非空白。
function GenreBadge({ genre }: { genre?: string | null }) {
  const value = genre?.trim();
  if (value) return <Badge>{value}</Badge>;
  return <Badge className="border-dashed text-muted-soft">未定题材</Badge>;
}

// 待审提示：状态点 + 文字（不单靠颜色传达状态）。
function PendingNote({ count }: { count: number }) {
  if (count <= 0) return null;
  return (
    <span className="inline-flex items-center gap-1.5 text-caption text-ink-soft">
      <StatusDot tone="warning" label={`${count} 章待审`} />
      {count} 待审
    </span>
  );
}
