export const STATIC_STICKER_CATALOG_SCHEMA_VERSION = "StaticStickerCatalog/v1" as const;
export const STATIC_STICKER_CATALOG_ORIGIN = "bundled_read_only" as const;

export interface StaticStickerThumbnailReference {
  media: "thumbnail";
  resource_id: string;
  resource_version: string;
  url: string;
}

export interface StaticStickerCatalogItem {
  stable_id: string;
  part: number;
  order: number;
  original_filename: string;
  relative_path: string;
  width: number;
  height: number;
  mime_type: "image/png" | "image/webp";
  mime: "image/png" | "image/webp";
  sha256: string;
  original_reference: string;
  thumbnail_reference: StaticStickerThumbnailReference;
  resource_version: string;
  enabled: boolean;
  origin: "bundled_read_only" | "admin_uploaded";
}

export interface StaticStickerCatalog {
  schema_version: typeof STATIC_STICKER_CATALOG_SCHEMA_VERSION;
  release_version: string;
  manifest_sha256: string;
  count: number;
  part_counts: Record<string, number>;
  duplicate_sha256_groups: Array<{ sha256: string; stable_ids: string[] }>;
  items: StaticStickerCatalogItem[];
}

export interface VirtualStickerWindowOptions {
  itemHeight: number;
  viewportHeight: number;
  columns: number;
  overscanScreens: number;
  scrollTop: number;
}

export interface VirtualStickerWindow<T extends { stable_id: string }> {
  start: number;
  end: number;
  top_spacer_px: number;
  bottom_spacer_px: number;
  items: T[];
}

export function stableStickerId(index: number): string {
  if (!Number.isInteger(index) || index < 1) throw new Error("sticker_index_invalid");
  return `STK${String(index).padStart(index < 1_000 ? 3 : 4, "0")}`;
}

export function getVirtualStickerWindow<T extends { stable_id: string }>(items: readonly T[], options: VirtualStickerWindowOptions): VirtualStickerWindow<T> {
  const itemHeight = Math.max(1, options.itemHeight);
  const viewportHeight = Math.max(1, options.viewportHeight);
  const columns = Math.max(1, Math.floor(options.columns));
  const overscanScreens = Math.max(0, options.overscanScreens);
  const scrollTop = Math.max(0, options.scrollTop);
  const totalRows = Math.ceil(items.length / columns);
  const visibleRows = Math.max(1, Math.ceil(viewportHeight / itemHeight));
  const overscanRows = Math.ceil((visibleRows * overscanScreens) / 2);
  const firstVisibleRow = Math.min(totalRows, Math.floor(scrollTop / itemHeight));
  const startRow = Math.max(0, firstVisibleRow - overscanRows);
  const endRow = Math.min(totalRows, firstVisibleRow + visibleRows + overscanRows);
  const start = startRow * columns;
  const end = Math.min(items.length, endRow * columns);
  return {
    bottom_spacer_px: Math.max(0, (totalRows - endRow) * itemHeight),
    end,
    items: items.slice(start, end) as T[],
    start,
    top_spacer_px: startRow * itemHeight,
  };
}

export function staticStickerThumbnailUrl(item: Pick<StaticStickerCatalogItem, "resource_version" | "stable_id">): string {
  return `/api/v1/assets/public/${encodeURIComponent(item.resource_version)}/${encodeURIComponent(item.stable_id)}?variant=thumbnail`;
}

export function staticStickerOriginalUrl(item: Pick<StaticStickerCatalogItem, "resource_version" | "stable_id">): string {
  return `/api/v1/assets/public/${encodeURIComponent(item.resource_version)}/${encodeURIComponent(item.stable_id)}`;
}
