const fs = require("fs");
const path = require("path");

/**
 * Determine the paths based on setup mode (theme vs project)
 * @returns {Object} Configuration object with paths and mode info
 */
function determinePaths() {
  const rootHugoToml = path.join(__dirname, "../hugo.toml");
  const exampleSiteHugoToml = path.join(__dirname, "../exampleSite/hugo.toml");

  if (fs.existsSync(exampleSiteHugoToml)) {
    // Theme setup mode - exampleSite structure exists
    return {
      hugoTomlPath: exampleSiteHugoToml,
      themePath: path.join(__dirname, "../exampleSite/data/theme.json"),
      outputPath: path.join(__dirname, "../assets/css/generated-theme.css"),
      isThemeSetup: true,
    };
  } else if (fs.existsSync(rootHugoToml)) {
    // Project setup mode - hugo.toml at root
    try {
      const hugoTomlContent = fs.readFileSync(rootHugoToml, "utf8");
      const themeNameMatch = hugoTomlContent.match(
        /^theme\s*=\s*["'\[]?"?([^"'\]]+)"?[\]"]?/m,
      );

      if (!themeNameMatch || !themeNameMatch[1]) {
        throw new Error("Could not extract theme name from hugo.toml");
      }

      const themeName = themeNameMatch[1];
      return {
        hugoTomlPath: rootHugoToml,
        themePath: path.join(__dirname, "../data/theme.json"),
        outputPath: path.join(
          __dirname,
          `../themes/${themeName}/assets/css/generated-theme.css`,
        ),
        isThemeSetup: false,
      };
    } catch (error) {
      throw new Error(`Failed to determine paths: ${error.message}`);
    }
  } else {
    throw new Error(
      "Could not determine setup mode: neither exampleSite/hugo.toml nor root hugo.toml found",
    );
  }
}

const { themePath, outputPath } = determinePaths();

// Helper to convert color name from snake_case to kebab-case
const toKebab = (str) => str.replace(/_/g, "-");

// Helper to extract a clean font name
const findFont = (fontStr) =>
  fontStr.replace(/\+/g, " ").replace(/:[^:]+/g, "");

/**
 * Add color entries to CSS array
 * @param {Array} cssLines - Array of CSS lines to append to
 * @param {Object} colors - Color object to process
 * @param {string} prefix - Optional prefix for color variable names
 */
function addColorsToCss(cssLines, colors, prefix = "") {
  Object.entries(colors).forEach(([key, value]) => {
    const colorName = prefix
      ? `--color-${prefix}-${toKebab(key)}`
      : `--color-${toKebab(key)}`;
    cssLines.push(`  ${colorName}: ${value};`);
  });
}

/**
 * Generate theme CSS from theme.json configuration
 * @throws {Error} If theme.json is missing or invalid
 */
function generateThemeCSS() {
  // Validate that theme.json exists
  if (!fs.existsSync(themePath)) {
    throw new Error(`Theme configuration not found: ${themePath}`);
  }

  try {
    // Read and parse theme configuration
    const themeConfig = JSON.parse(fs.readFileSync(themePath, "utf8"));

    // Validate required theme structure
    if (!themeConfig.colors || !themeConfig.fonts) {
      throw new Error(
        "Invalid theme.json: missing 'colors' or 'fonts' section",
      );
    }

    // Build CSS using array for better performance
    const cssLines = [
      "/**",
      ' * Auto-generated from "data/theme.json"',
      " * DO NOT EDIT THIS FILE MANUALLY",
      " * Run: node scripts/themeGenerator.js",
      " */",
      "",
      "@theme {",
      "  /* === Colors === */",
    ];

    // Add default theme colors
    if (themeConfig.colors.default?.theme_color) {
      addColorsToCss(cssLines, themeConfig.colors.default.theme_color);
    }

    // Add default text colors
    if (themeConfig.colors.default?.text_color) {
      addColorsToCss(cssLines, themeConfig.colors.default.text_color);
    }

    // Add darkmode colors (if available)
    if (themeConfig.colors.darkmode) {
      cssLines.push("", "  /* === Darkmode Colors === */");

      if (themeConfig.colors.darkmode.theme_color) {
        addColorsToCss(
          cssLines,
          themeConfig.colors.darkmode.theme_color,
          "darkmode",
        );
      }

      if (themeConfig.colors.darkmode.text_color) {
        addColorsToCss(
          cssLines,
          themeConfig.colors.darkmode.text_color,
          "darkmode",
        );
      }
    }

    // Add font families
    cssLines.push("", "  /* === Font Families === */");
    const fontFamily = themeConfig.fonts.font_family || {};
    Object.entries(fontFamily)
      .filter(([key]) => !key.includes("type"))
      .forEach(([key, font]) => {
        const fontFallback = fontFamily[`${key}_type`] || "sans-serif";
        const fontValue = `${findFont(font)}, ${fontFallback}`;
        cssLines.push(`  --font-${toKebab(key)}: ${fontValue};`);
      });

    // Add font sizes
    cssLines.push("", "  /* === Font Sizes === */");
    const baseSize = Number(themeConfig.fonts.font_size?.base || 16);
    const scale = Number(themeConfig.fonts.font_size?.scale || 1.25);

    cssLines.push(`  --text-base: ${baseSize}px;`);
    cssLines.push(`  --text-base-sm: ${baseSize * 0.8}px;`);

    let currentSize = scale;
    for (let i = 6; i >= 1; i--) {
      cssLines.push(`  --text-h${i}: ${currentSize}rem;`);
      cssLines.push(`  --text-h${i}-sm: ${currentSize * 0.9}rem;`);
      currentSize *= scale;
    }

    cssLines.push("}");

    // Ensure output directory exists
    const outputDir = path.dirname(outputPath);
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
    }

    // Write the file
    fs.writeFileSync(outputPath, cssLines.join("\n") + "\n");
    console.log("✅ Theme CSS generated successfully at:", outputPath);
  } catch (error) {
    throw new Error(`Failed to generate theme CSS: ${error.message}`);
  }
}

// Generate CSS on startup
try {
  generateThemeCSS();
} catch (error) {
  console.error("❌ Error:", error.message);
  process.exit(1);
}

// Check for --watch flag
if (process.argv.includes("--watch")) {
  let debounceTimer;

  const watcher = fs.watch(themePath, (eventType) => {
    if (eventType === "change") {
      // Debounce to avoid multiple triggers
      clearTimeout(debounceTimer);
      debounceTimer = setTimeout(() => {
        try {
          generateThemeCSS();
        } catch (error) {
          console.error("❌ Error regenerating theme CSS:", error.message);
        }
      }, 300);
    }
  });

  // Handle graceful shutdown
  process.on("SIGINT", () => {
    clearTimeout(debounceTimer);
    watcher.close();
    console.log("\n👋 Watcher stopped");
    process.exit(0);
  });

  console.log("👁️  Watching for changes to:", themePath);
}
