import { readdirSync, readFileSync, writeFileSync } from "node:fs"
import { basename, join } from "node:path"

const presetDirectory = "preset-theme"
const outputFile = "apps/agent-html-app/src/gallery/theme-presets.generated.ts"

function slugifyPresetName(name) {
  return name
    .toLowerCase()
    .replace(/\+/g, "plus")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
}

function extractCssBlock(css, selector) {
  const pattern = new RegExp(`${selector.replace(".", "\\.")}\\s*\\{([\\s\\S]*?)\\}`)
  const match = css.match(pattern)

  return match?.[1] ?? ""
}

function parseCssVariables(block) {
  const variables = {}
  const declarationPattern = /(--[a-zA-Z0-9-]+)\s*:\s*([^;]+);/g
  let match

  while ((match = declarationPattern.exec(block)) !== null) {
    variables[match[1]] = match[2].trim()
  }

  return variables
}

function formatVariables(variables, indent = "      ") {
  const entries = Object.entries(variables)

  if (entries.length === 0) {
    return "{}"
  }

  return [
    "{",
    ...entries.map(
      ([name, value]) => `${indent}${JSON.stringify(name)}: ${JSON.stringify(value)},`
    ),
    `${indent.slice(0, -2)}}`,
  ].join("\n")
}

const presetFiles = readdirSync(presetDirectory)
  .filter((fileName) => fileName.endsWith(".css"))
  .sort((left, right) => left.localeCompare(right))

const presets = presetFiles.map((fileName) => {
  const label = basename(fileName, ".css")
  const css = readFileSync(join(presetDirectory, fileName), "utf8")

  return {
    id: slugifyPresetName(label),
    label,
    lightCssVariables: parseCssVariables(extractCssBlock(css, ":root")),
    darkCssVariables: parseCssVariables(extractCssBlock(css, ".dark")),
  }
})

const output = `// This file is generated by tools/import-gallery-theme-presets.mjs.
// Do not edit manually.

import type { GalleryThemePreset } from "@/app/gallery/editor-panels"

export const generatedGalleryThemePresets = [
${presets
  .map(
    (preset) => `  {
    id: ${JSON.stringify(preset.id)},
    label: ${JSON.stringify(preset.label)},
    lightCssVariables: ${formatVariables(preset.lightCssVariables)},
    darkCssVariables: ${formatVariables(preset.darkCssVariables)},
  },`
  )
  .join("\n")}
] satisfies GalleryThemePreset[]
`

writeFileSync(outputFile, output)
