"use client";

/**
 * Announcements — 公告列表（批次 A）
 *
 * 数据源：useAnnouncements
 * 视图：公告列表（置顶标记 + 已读/未读状态 + 类型筛选）
 */

import { useMemo, useState } from "react";
import Link from "next/link";
import { useAnnouncements } from "@/lib/graphql/hooks";
import type { AnnouncementType } from "@/lib/graphql/types";

const TYPE_LABELS: Record<AnnouncementType, string> = {
  school: "校级",
  grade: "年级",
  class: "班级",
};

export default function AnnouncementsPage(): JSX.Element {
  const { data, fetching, error, reexecute } = useAnnouncements();
  const [typeFilter, setTypeFilter] = useState<string>("all");

  const announcements = data ?? [];
  const filtered = useMemo(() => {
    const list = typeFilter === "all" ? announcements : announcements.filter((a) => a.type === typeFilter);
    return [...list].sort((a, b) => {
      if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1;
      const ta = a.publishedAt ? new Date(a.publishedAt).getTime() : 0;
      const tb = b.publishedAt ? new Date(b.publishedAt).getTime() : 0;
      return tb - ta;
    });
  }, [announcements, typeFilter]);

  return (
    <div className="px-6 lg:px-10 py-8 lg:py-10 max-w-5xl mx-auto">
      <header className="mb-6">
        <p className="text-xs uppercase tracking-wider" style={{ color: "var(--color-ink-muted)" }}>
          信息公告
        </p>
        <h1 className="mt-2 text-3xl lg:text-4xl font-serif" style={{ color: "var(--color-ink)" }}>
          公告
        </h1>
        <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
          查看学校、年级及班级发布的通知与公告。
        </p>
      </header>

      <div className="rule-thin mb-6" />

      <div className="flex items-center gap-3 mb-6">
        {(["all", "school", "grade", "class"] as const).map((t) => (
          <button
            key={t}
            type="button"
            onClick={() => setTypeFilter(t)}
            className="px-3 py-1.5 rounded-sm text-xs transition-colors"
            style={{
              background: typeFilter === t ? "var(--color-accent-muted)" : "transparent",
              border: `1px solid ${typeFilter === t ? "var(--color-accent)" : "var(--color-rule)"}`,
              color: typeFilter === t ? "var(--color-accent)" : "var(--color-ink-muted)",
            }}
          >
            {t === "all" ? "全部" : TYPE_LABELS[t]}
          </button>
        ))}
      </div>

      {fetching ? (
        <LoadingSkeleton />
      ) : error ? (
        <ErrorState message={error.message} onRetry={() => reexecute()} />
      ) : filtered.length === 0 ? (
        <EmptyState />
      ) : (
        <ul className="space-y-3">
          {filtered.map((a) => (
            <li key={a.id}>
              <Link href={`/announcements/${a.id}`} className="block">
                <article
                  className="card-paper p-4 transition-opacity hover:opacity-80"
                  style={{
                    borderLeft: a.isPinned ? "3px solid var(--color-accent)" : "1px solid var(--color-rule)",
                  }}
                >
                  <div className="flex items-start justify-between gap-4 mb-1">
                    <div className="flex items-center gap-2">
                      <span className="badge badge-info">{TYPE_LABELS[a.type]}</span>
                      {a.isPinned && (
                        <span className="badge badge-warning">置顶</span>
                      )}
                      {!a.isReadByCurrentUser && (
                        <span className="inline-block w-2 h-2 rounded-full" style={{ background: "var(--color-accent)" }} aria-label="未读" />
                      )}
                    </div>
                    <span className="text-xs" style={{ color: "var(--color-ink-muted)" }}>
                      {a.publishedAt ? new Date(a.publishedAt).toLocaleDateString("zh-CN") : "—"}
                    </span>
                  </div>
                  <p className="text-sm font-medium" style={{ color: "var(--color-ink)" }}>
                    {a.title}
                  </p>
                  <p className="mt-1 text-xs text-truncate" style={{ color: "var(--color-ink-muted)" }}>
                    {a.content.slice(0, 80)}...
                  </p>
                  <p className="mt-1 text-xs" style={{ color: "var(--color-ink-subtle)" }}>
                    {a.authorName ?? "—"}
                  </p>
                </article>
              </Link>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

function LoadingSkeleton(): JSX.Element {
  return (
    <div className="space-y-3" aria-busy="true" aria-live="polite">
      {[0, 1, 2, 3].map((i) => (
        <div
          key={i}
          className="h-20 animate-pulse rounded-sm"
          style={{ background: "var(--color-rule)", opacity: 0.3 }}
        />
      ))}
      <span className="sr-only">正在加载公告...</span>
    </div>
  );
}

function ErrorState({ message, onRetry }: { message: string; onRetry: () => void }): JSX.Element {
  return (
    <div role="alert" className="card-paper p-8 text-center" style={{ borderColor: "var(--color-danger)" }}>
      <p className="text-base font-serif" style={{ color: "var(--color-danger)" }}>
        公告加载失败
      </p>
      <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
        {message}
      </p>
      <button type="button" onClick={onRetry} className="mt-4 btn-secondary text-xs">
        重新加载
      </button>
    </div>
  );
}

function EmptyState(): JSX.Element {
  return (
    <div className="card-paper p-8 text-center">
      <p className="text-4xl font-serif" style={{ color: "var(--color-ink-subtle)" }} aria-hidden="true">
        ◇
      </p>
      <p className="mt-4 text-base font-serif" style={{ color: "var(--color-ink)" }}>
        暂无公告
      </p>
    </div>
  );
}
