/**
 * Extracts plan data from plans/open/ and plans/done/ directories.
 * Generates plans.json with all open and done plans.
 * 
 * Runs via GitHub Actions (hourly) or manual npm script.
 * Output: docs/public/data/plans.json
 */

import fs from "fs";
import path from "path";

interface PlanData {
  date: string;
  slug: string;
  title: string;
  preface: string;
  status: "open" | "done";
}

/**
 * Extract date from filename like "2026-02-06-list-scrollable.md"
 */
function extractDate(filename: string): string {
  const match = filename.match(/^(\d{4}-\d{2}-\d{2})/);
  return match ? match[1] : "";
}

/**
 * Extract slug from filename like "2026-02-06-list-scrollable.md"
 */
function extractSlug(filename: string): string {
  const match = filename.match(/^\d{4}-\d{2}-\d{2}-(.+)\.md$/);
  return match ? match[1] : "";
}

/**
 * Extract H1 title from markdown content
 */
function extractTitle(content: string): string {
  const match = content.match(/^#\s+(.+)$/m);
  return match ? match[1].trim() : "Untitled";
}

/**
 * Extract first ## section (Preface) from markdown content.
 * Returns the full text until the next ## section or end of file.
 */
function extractPreface(content: string): string {
  // Find first ## section
  const match = content.match(/^##\s+Preface\s*\n([\s\S]*?)(?=\n##\s|\Z)/m);
  return match ? match[1].trim() : "";
}

/**
 * Read all plan files from a directory
 */
function readPlansFromDir(dirPath: string, status: "open" | "done"): PlanData[] {
  if (!fs.existsSync(dirPath)) {
    console.warn(`Directory not found: ${dirPath}`);
    return [];
  }

  const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(".md"));

  return files
    .map((filename) => {
      const filePath = path.join(dirPath, filename);
      const content = fs.readFileSync(filePath, "utf-8");

      return {
        date: extractDate(filename),
        slug: extractSlug(filename),
        title: extractTitle(content),
        preface: extractPreface(content),
        status,
      };
    })
    .filter((plan) => plan.date && plan.slug && plan.preface); // Skip invalid plans
}

/**
 * Main execution
 */
function main() {
  const projectRoot = path.resolve(process.cwd(), "..");
  const openDir = path.join(projectRoot, "plans", "open");
  const doneDir = path.join(projectRoot, "plans", "done");

  // Read all plans
  const openPlans = readPlansFromDir(openDir, "open");
  const donePlans = readPlansFromDir(doneDir, "done");

  // Sort by date (newest first)
  const sortByDateDesc = (a: PlanData, b: PlanData) =>
    new Date(b.date).getTime() - new Date(a.date).getTime();

  openPlans.sort(sortByDateDesc);
  donePlans.sort(sortByDateDesc);

  // Build output with all plans
  const output = {
    generated: new Date().toISOString(),
    open: openPlans.map(({ date, slug, title, preface }) => ({
      date,
      slug,
      title,
      preface,
    })),
    done: donePlans.map(({ date, slug, title, preface }) => ({
      date,
      slug,
      title,
      preface,
    })),
  };

  // Ensure output directory exists
  const outputDir = path.join(process.cwd(), "public", "data");
  fs.mkdirSync(outputDir, { recursive: true });

  // Write JSON
  const outputPath = path.join(outputDir, "plans.json");
  fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));

  console.log(
    `✓ Generated plans.json (${openPlans.length} open, ${donePlans.length} done)`
  );
  console.log(`  Location: ${outputPath}`);
}

main();
