import type { PlopTypes } from '@turbo/gen'

/**
 * Platform module scaffolder — the single source of truth for `@platform-modules/*` STRUCTURE.
 *
 * Code rules live in docs/standards/coding-standard.md; this only emits the
 * uniform package skeleton (the i18n / i18n-react shape) so every module starts
 * identical. Two generators:
 *   - `mod-package`       a core @platform-modules/<name> (seam + optional capability subpaths)
 *   - `mod-react-sibling` a flat @platform-modules/<core>-react adapter (never a subpath)
 *
 * Run: `pnpm turbo gen mod-package` / `pnpm turbo gen mod-react-sibling`.
 * `packages/*` is a workspace glob, so a new package is auto-registered — no edit.
 */

const splitList = (raw: unknown): string[] =>
  String(raw ?? '')
    .split(',')
    .map((s) => s.trim())
    .filter(Boolean)

const KEBAB = /^[a-z][a-z0-9-]*$/

export default function generator(plop: PlopTypes.NodePlopAPI): void {
  // ---- core @platform-modules/<name> package -------------------------------------------
  plop.setGenerator('mod-package', {
    description: 'Scaffold a new @platform-modules/<name> package (core seam + capability subpaths)',
    prompts: [
      {
        type: 'input',
        name: 'name',
        message: "Module name without @platform-modules/ (e.g. 'db', 'rate-limit'):",
        validate: (v: string) => KEBAB.test(v.trim()) || 'lowercase kebab-case (a-z, 0-9, -)',
      },
      {
        type: 'input',
        name: 'capabilities',
        message: 'Capability subpaths, comma-separated (blank = leaf, index only):',
      },
    ],
    actions: (answers?: Record<string, unknown>) => {
      const a = (answers ?? {}) as { name: string; capabilities?: string }
      const name = a.name.trim()
      const capList = splitList(a.capabilities)
      const data = { name, capList }
      const base = `packages/${name}`
      const actions: PlopTypes.ActionType[] = [
        { type: 'add', path: `${base}/package.json`, templateFile: 'templates/package.json.hbs', data },
        { type: 'add', path: `${base}/tsdown.config.ts`, templateFile: 'templates/tsdown.config.ts.hbs', data },
        { type: 'add', path: `${base}/tsconfig.json`, templateFile: 'templates/tsconfig.json.hbs', data },
        { type: 'add', path: `${base}/src/index.ts`, templateFile: 'templates/index.ts.hbs', data },
        { type: 'add', path: `${base}/src/index.test.ts`, templateFile: 'templates/index.test.ts.hbs', data },
      ]
      for (const cap of capList) {
        actions.push(
          { type: 'add', path: `${base}/src/${cap}.ts`, templateFile: 'templates/capability.ts.hbs', data: { ...data, cap } },
          { type: 'add', path: `${base}/src/${cap}.test.ts`, templateFile: 'templates/capability.test.ts.hbs', data: { ...data, cap } },
        )
      }
      return actions
    },
  })

  // ---- @platform-modules/<core>-react framework sibling (flat, never a /react subpath) --
  plop.setGenerator('mod-react-sibling', {
    description: 'Scaffold a @platform-modules/<core>-react adapter (headless: hook + render-prop)',
    prompts: [
      {
        type: 'input',
        name: 'core',
        message: "Core module it adapts, without @platform-modules/ (e.g. 'i18n'):",
        validate: (v: string) => KEBAB.test(v.trim()) || 'lowercase kebab-case (a-z, 0-9, -)',
      },
    ],
    actions: (answers?: Record<string, unknown>) => {
      const a = (answers ?? {}) as { core: string }
      const core = a.core.trim()
      const data = { core }
      const base = `packages/${core}-react`
      return [
        { type: 'add', path: `${base}/package.json`, templateFile: 'templates/react/package.json.hbs', data },
        { type: 'add', path: `${base}/tsdown.config.ts`, templateFile: 'templates/react/tsdown.config.ts.hbs', data },
        { type: 'add', path: `${base}/tsconfig.json`, templateFile: 'templates/tsconfig.json.hbs', data },
        { type: 'add', path: `${base}/vitest.config.ts`, templateFile: 'templates/react/vitest.config.ts.hbs', data },
        { type: 'add', path: `${base}/src/index.tsx`, templateFile: 'templates/react/index.tsx.hbs', data },
        { type: 'add', path: `${base}/src/index.test.tsx`, templateFile: 'templates/react/index.test.tsx.hbs', data },
      ]
    },
  })
}
