import { getCategoryNames as readCategoryNames, getPublishedArticles as readPublishedArticles, type Article } from "./article-store";

export type { Article };
export const PAGE_SIZE = 9;

const CATEGORY_SLUGS: Record<string, string> = {
  学情指南: "learning-profile",
  学习方法: "learning-methods",
  家长课堂: "parent-guides",
  服务说明: "service-guides",
};

function fallbackSlug(category: string): string {
  const ascii = category.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
  if (ascii) return ascii;
  let hash = 0;
  for (const char of category) hash = (hash * 31 + (char.codePointAt(0) ?? 0)) >>> 0;
  return `c${hash.toString(36)}`;
}

export const categoryToSlug = (category: string) => CATEGORY_SLUGS[category] ?? fallbackSlug(category);

export function slugToCategory(slug: string, categories: string[]): string | undefined {
  return categories.find((category) => categoryToSlug(category) === slug);
}

export async function getPublishedArticles(): Promise<Article[]> {
  return readPublishedArticles();
}

export async function getCategoryNames(): Promise<string[]> {
  return readCategoryNames();
}

export interface CategoryInfo {
  name: string;
  slug: string;
  count: number;
}

export function getCategories(items: Article[], categoryNames: string[] = []): CategoryInfo[] {
  const counts = new Map<string, number>(categoryNames.map((name) => [name, 0]));
  for (const item of items) counts.set(item.data.category, (counts.get(item.data.category) ?? 0) + 1);
  return [...counts.entries()]
    .map(([name, count]) => ({ name, slug: categoryToSlug(name), count }))
    .sort((a, b) => b.count - a.count || a.name.localeCompare(b.name, "zh-CN"));
}

export const lastPageOf = (total: number, pageSize = PAGE_SIZE) => Math.max(1, Math.ceil(total / pageSize));
export const pageSlice = <T>(items: T[], page: number, pageSize = PAGE_SIZE) => items.slice((page - 1) * pageSize, page * pageSize);
export const fmtDate = (date: Date) => date.toISOString().slice(0, 10);

export function paginationWindow(current: number, last: number, span = 2): number[] {
  const pages = new Set<number>([1, last]);
  for (let page = current - span; page <= current + span; page++) if (page >= 1 && page <= last) pages.add(page);
  const sorted = [...pages].sort((a, b) => a - b);
  const result: number[] = [];
  let previous = 0;
  for (const page of sorted) {
    if (previous && page - previous > 1) result.push(0);
    result.push(page);
    previous = page;
  }
  return result;
}
