#!/usr/bin/env bun
/**
 * Analytics scrape CLI — GitHub PR-merged adoption.
 *
 * Usage:
 *   bun run analytics:scrape --from YYYY-MM-DD
 *   bun run analytics:scrape --weeks N
 *
 * Outputs (all under analytics/data/):
 *   weekly-metrics.csv     weekly PR counts across managed repos
 *   repo-adoption.csv      per-repo rollup for the whole window
 *   squad-adoption.csv     per-squad rollup (derived from PR branch names)
 */

import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { collectAnalytics } from "@/analytics/metrics.js";
import { toCSV } from "@/analytics/csv.js";
import type { RepoAdoptionRow, SquadAdoptionRow, WeeklyMetric } from "@/analytics/types.js";
import { createGitHubTokenProvider } from "@/github/auth.js";
import { RepoRegistry } from "@/repo/registry.js";
import { loadConfig } from "@/utils/config.js";
import { createLogger } from "@/utils/logger.js";

const WEEKLY_COLUMNS = [
  "weekStart",
  "weekEnd",
  "prsMergedTotal",
  "prsMergedBot",
  "prsMergedOtherBots",
] as const satisfies ReadonlyArray<keyof WeeklyMetric>;

const REPO_ADOPTION_COLUMNS = [
  "repo",
  "prsMergedTotal",
  "prsMergedBot",
  "prsMergedOtherBots",
] as const satisfies ReadonlyArray<keyof RepoAdoptionRow>;

const SQUAD_ADOPTION_COLUMNS = [
  "squad",
  "tribe",
  "prsMergedTotal",
  "prsMergedBot",
  "prsMergedOtherBots",
] as const satisfies ReadonlyArray<keyof SquadAdoptionRow>;

function parseIsoDate(value: string): Date | undefined {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return undefined;
  const d = new Date(`${value}T00:00:00Z`);
  return Number.isNaN(d.getTime()) ? undefined : d;
}

interface CliArgs {
  weeks: number | undefined;
  startDate: Date | undefined;
}

function parseArgs(argv: string[]): CliArgs {
  let weeks: number | undefined;
  let startDate: Date | undefined;
  for (let i = 0; i < argv.length; i++) {
    const arg = argv[i];
    if (arg === "--weeks") {
      const next = argv[i + 1];
      if (next) {
        const parsed = Number.parseInt(next, 10);
        if (Number.isFinite(parsed) && parsed > 0) weeks = parsed;
        i++;
      }
    } else if (arg?.startsWith("--weeks=")) {
      const value = arg.slice("--weeks=".length);
      const parsed = Number.parseInt(value, 10);
      if (Number.isFinite(parsed) && parsed > 0) weeks = parsed;
    } else if (arg === "--from") {
      const next = argv[i + 1];
      if (next) {
        startDate = parseIsoDate(next);
        i++;
      }
    } else if (arg?.startsWith("--from=")) {
      startDate = parseIsoDate(arg.slice("--from=".length));
    }
  }
  return { weeks, startDate };
}

async function main(): Promise<void> {
  const config = loadConfig();
  const logger = createLogger(config.logLevel).child({ module: "analytics-cli" });
  const { weeks, startDate } = parseArgs(process.argv.slice(2));

  if (!startDate && (!weeks || weeks <= 0)) {
    console.error(
      "Usage: bun run analytics:scrape --from YYYY-MM-DD\n" +
        "   or  bun run analytics:scrape --weeks N",
    );
    process.exit(2);
  }

  const repoRegistry = new RepoRegistry();
  const getGitHubToken = createGitHubTokenProvider(config);

  logger.info(
    {
      startDate: startDate?.toISOString() ?? null,
      weeks: weeks ?? null,
      repos: repoRegistry.getAll().length,
      botLogin: config.githubBotUser,
    },
    "analytics_scrape_start",
  );

  const report = await collectAnalytics({
    logger,
    repos: repoRegistry.getAll(),
    getGitHubToken,
    botLogin: config.githubBotUser,
    startDate,
    maxWeeks: weeks,
  });

  const here = dirname(fileURLToPath(import.meta.url));
  const outDir = join(here, "data");
  mkdirSync(outDir, { recursive: true });

  writeFileSync(join(outDir, "weekly-metrics.csv"), toCSV(report.weekly, WEEKLY_COLUMNS));
  writeFileSync(join(outDir, "repo-adoption.csv"), toCSV(report.byRepo, REPO_ADOPTION_COLUMNS));
  writeFileSync(join(outDir, "squad-adoption.csv"), toCSV(report.bySquad, SQUAD_ADOPTION_COLUMNS));

  logger.info(
    {
      outDir,
      weeks: report.weekly.length,
      repos: report.byRepo.length,
      squads: report.bySquad.length,
      startDate: report.meta.startDate,
    },
    "analytics_scrape_done",
  );
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
