// src/lib/gsc/parse.ts — Pure parser for Google Search Console site-list responses.
// No "server-only" import: this module is safe to use in any environment.
import { iso3ToAlpha2 } from "./country-iso3";
import type {
  GscProperty,
  GscQueryCountryRow,
  GscQueryPageRow,
  GscQueryRow,
} from "./types";

const UNVERIFIED = "siteUnverifiedUser";

/** Pick the verified properties out of a webmasters/v3/sites response body. */
export function parseGscSites(body: unknown): GscProperty[] {
  const entries = (body as { siteEntry?: unknown })?.siteEntry;
  if (!Array.isArray(entries)) return [];
  return entries
    .filter(
      (e): e is GscProperty =>
        typeof (e as GscProperty)?.siteUrl === "string" &&
        typeof (e as GscProperty)?.permissionLevel === "string" &&
        (e as GscProperty).permissionLevel !== UNVERIFIED,
    )
    .map((e) => ({ siteUrl: e.siteUrl, permissionLevel: e.permissionLevel }));
}

/** Map a searchAnalytics response (dimensions ["query"]) to typed rows. */
export function parseSearchAnalytics(body: unknown): GscQueryRow[] {
  const rows = (body as { rows?: unknown })?.rows;
  if (!Array.isArray(rows)) return [];
  const out: GscQueryRow[] = [];
  for (const r of rows) {
    const keys = (r as { keys?: unknown })?.keys;
    const query = Array.isArray(keys) ? keys[0] : undefined;
    if (typeof query !== "string") continue;
    const row = r as Record<string, unknown>;
    out.push({
      query,
      clicks: Number(row.clicks ?? 0),
      impressions: Number(row.impressions ?? 0),
      ctr: Number(row.ctr ?? 0),
      position: Number(row.position ?? 0),
    });
  }
  return out;
}

/** Map a searchAnalytics response (dimensions ["query", "page"]) to typed rows. */
export function parseSearchAnalyticsPages(body: unknown): GscQueryPageRow[] {
  const rows = (body as { rows?: unknown })?.rows;
  if (!Array.isArray(rows)) return [];
  const out: GscQueryPageRow[] = [];
  for (const r of rows) {
    const keys = (r as { keys?: unknown })?.keys;
    const query = Array.isArray(keys) ? keys[0] : undefined;
    const page = Array.isArray(keys) ? keys[1] : undefined;
    if (typeof query !== "string" || typeof page !== "string") continue;
    const row = r as Record<string, unknown>;
    out.push({
      query,
      page,
      clicks: Number(row.clicks ?? 0),
      impressions: Number(row.impressions ?? 0),
      ctr: Number(row.ctr ?? 0),
      position: Number(row.position ?? 0),
    });
  }
  return out;
}

/** Map a searchAnalytics response (dimensions ["query", "country"]) to typed
 *  rows. GSC keys the country as alpha-3 lowercase ("fra"); we map it to alpha-2
 *  and skip rows whose country we don't recognise (no usable language signal). */
export function parseSearchAnalyticsCountries(
  body: unknown,
): GscQueryCountryRow[] {
  const rows = (body as { rows?: unknown })?.rows;
  if (!Array.isArray(rows)) return [];
  const out: GscQueryCountryRow[] = [];
  for (const r of rows) {
    const keys = (r as { keys?: unknown })?.keys;
    const query = Array.isArray(keys) ? keys[0] : undefined;
    const iso3 = Array.isArray(keys) ? keys[1] : undefined;
    if (typeof query !== "string" || typeof iso3 !== "string") continue;
    const country = iso3ToAlpha2(iso3);
    if (!country) continue;
    const row = r as Record<string, unknown>;
    out.push({
      query,
      country,
      clicks: Number(row.clicks ?? 0),
      impressions: Number(row.impressions ?? 0),
      ctr: Number(row.ctr ?? 0),
      position: Number(row.position ?? 0),
    });
  }
  return out;
}

/** Top N rows by impressions, descending. */
export function topByImpressions(
  rows: GscQueryRow[],
  n: number,
): GscQueryRow[] {
  return [...rows].sort((a, b) => b.impressions - a.impressions).slice(0, n);
}
