#!/usr/bin/env node

import { execFileSync } from "node:child_process"
import { existsSync, mkdirSync, rmSync, copyFileSync, writeFileSync } from "node:fs"
import { dirname, join, relative } from "node:path"
import { fileURLToPath } from "node:url"

const SOURCE_REPO = "https://github.com/nolly-studio/cult-ui.git"
const SOURCE_COMMIT = "a3308bad8496b036adf2fbd29d50b877fb3c5987"

const __filename = fileURLToPath(import.meta.url)
const skillDir = dirname(dirname(__filename))
const cacheDir = join(skillDir, ".cache")
const usingExternalSource = Boolean(process.env.CULT_UI_SOURCE)
const repoDir = process.env.CULT_UI_SOURCE || join(cacheDir, "cult-ui")
const vendorDir = join(skillDir, "vendor", "cult-ui-selected")

const selectedFiles = [
  "LICENSE.md",
  "README.md",
  "apps/www/registry/default/ui/animated-number.tsx",
  "apps/www/registry/default/ui/side-panel.tsx",
  "apps/www/registry/default/ui/floating-panel.tsx",
  "apps/www/registry/default/ui/popover.tsx",
  "apps/www/registry/default/ui/popover-form.tsx",
  "apps/www/registry/default/ui/sortable-list.tsx",
  "apps/www/registry/default/ui/toolbar-expandable.tsx",
  "apps/www/registry/default/ui/prompt-library.tsx",
  "apps/www/registry/default/ui/ai-instructions.tsx",
  "apps/www/registry/default/ui/code-block.tsx",
  "apps/www/registry/default/ui/mock-browser-window.tsx",
  "apps/www/registry/default/ui/choice-poll.tsx",
  "apps/www/registry/default/ui/feature-voting.tsx",
  "apps/www/registry/default/ui/vote-tally.tsx",
  "apps/www/registry/default/ui/timer.tsx",
  "apps/www/registry/default/example/animated-number-demo.tsx",
  "apps/www/registry/default/example/side-panel-demo.tsx",
  "apps/www/registry/default/example/floating-panel-demo.tsx",
  "apps/www/registry/default/example/popover-demo.tsx",
  "apps/www/registry/default/example/popover-form-demo.tsx",
  "apps/www/registry/default/example/sortable-list-demo.tsx",
  "apps/www/registry/default/example/toolbar-expandable-demo.tsx",
  "apps/www/registry/default/example/prompt-library-demo.tsx",
  "apps/www/registry/default/example/ai-instructions-demo.tsx",
  "apps/www/registry/default/example/code-block-demo.tsx",
  "apps/www/registry/default/example/mock-browser-window-demo.tsx",
  "apps/www/registry/default/example/choice-poll-demo.tsx",
  "apps/www/registry/default/example/feature-voting-demo.tsx",
  "apps/www/registry/default/example/vote-tally-demo.tsx",
  "apps/www/registry/default/example/timer-demo.tsx",
  "apps/www/app/(app)/themes/cards/data-table.tsx",
  "apps/www/app/(app)/themes/cards/metric.tsx",
  "apps/www/app/(app)/themes/cards/stats.tsx",
  "apps/www/app/(app)/themes/cards/activity-goal.tsx",
  "apps/www/public/registry/styles/default/table.json",
  "apps/www/public/migrate/blocks/ai-artifact-table-light.png",
  "apps/www/public/migrate/blocks/ai-artifact-table-dark.png",
  "apps/www/public/migrate/blocks/ai-artifact-chart-light.png",
  "apps/www/public/migrate/blocks/ai-artifact-chart-dark.png",
  "apps/www/public/migrate/blocks/example-agent-data-analysis-light.png",
  "apps/www/public/migrate/blocks/example-agent-data-analysis-dark.png",
]

function run(command, args, cwd) {
  execFileSync(command, args, { cwd, stdio: "inherit" })
}

function ensureRepo() {
  if (!usingExternalSource) {
    mkdirSync(cacheDir, { recursive: true })
  }

  if (!existsSync(repoDir)) {
    run("git", ["clone", SOURCE_REPO, repoDir], skillDir)
  }

  run("git", ["fetch", "--depth", "1", "origin", SOURCE_COMMIT], repoDir)
  run("git", ["checkout", "--detach", SOURCE_COMMIT], repoDir)
}

function copySelectedFiles() {
  rmSync(vendorDir, { recursive: true, force: true })
  mkdirSync(vendorDir, { recursive: true })

  const copied = []
  const missing = []

  for (const file of selectedFiles) {
    const source = join(repoDir, file)
    const destination = join(vendorDir, file)

    if (!existsSync(source)) {
      missing.push(file)
      continue
    }

    mkdirSync(dirname(destination), { recursive: true })
    copyFileSync(source, destination)
    copied.push(file)
  }

  const manifest = {
    sourceRepo: SOURCE_REPO,
    sourceCommit: SOURCE_COMMIT,
    generatedAt: new Date().toISOString(),
    copied,
    missing,
    notes: [
      "Cult UI is MIT-licensed at the pinned source commit.",
      "This package copies a selected dashboard-relevant subset only.",
      "Do not assume offsite/pro links in the README are included in this license bundle.",
    ],
  }

  writeFileSync(
    join(vendorDir, "MANIFEST.generated.json"),
    `${JSON.stringify(manifest, null, 2)}\n`
  )

  writeFileSync(
    join(vendorDir, "SOURCE.md"),
    [
      "# Cult UI Selected Vendor Bundle",
      "",
      `Source repo: ${SOURCE_REPO}`,
      `Pinned commit: ${SOURCE_COMMIT}`,
      "",
      "This folder is generated by `scripts/sync-cult-ui.mjs`.",
      "Keep `LICENSE.md` with any redistributed or adapted source.",
      "",
      "Copied files:",
      ...copied.map((file) => `- ${file}`),
      "",
      missing.length ? "Missing files:" : "Missing files: none",
      ...missing.map((file) => `- ${file}`),
      "",
    ].join("\n")
  )

  console.log(`Copied ${copied.length} files to ${relative(process.cwd(), vendorDir)}`)

  if (missing.length) {
    console.error(`Missing ${missing.length} files:`)
    for (const file of missing) console.error(`- ${file}`)
    process.exitCode = 1
  }
}

ensureRepo()
copySelectedFiles()
