#!/usr/bin/env node
/**
 * Pre-commit type check for staged TS files.
 *
 * Writes a temp tsconfig that extends the project root and pins
 * `files` to whatever lint-staged passed in. `tsc -p` then compiles
 * the whole dep graph from those entrypoints — catches errors in
 * the staged code AND in anything it imports — while still skipping
 * the 22s full-project pass.
 *
 * Replaces `tsc-files` (npm), which silently fails under pnpm because
 * its tsc-resolution path (typescript/../.bin/tsc) doesn't exist in
 * pnpm's virtual store layout.
 */

import { spawnSync } from 'node:child_process';
import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from 'node:fs';
import { join, relative, resolve } from 'node:path';

const cwd = process.cwd();
const args = process.argv.slice(2);
const files = args.filter((a) => /\.(ts|tsx)$/.test(a));

if (files.length === 0) {
  process.exit(0);
}

// Temp tsconfig lives inside the project tree (not /tmp) so @types/*
// resolution walks up to node_modules. tsc's "atTypes" auto-discovery
// is anchored to the tsconfig's directory, so a temp config in /tmp
// would miss our @types/node, @types/react, etc.
const baseDir = join(cwd, 'node_modules/.cache/tsc-staged');
mkdirSync(baseDir, { recursive: true });
const tmpDir = mkdtempSync(join(baseDir, 'run-'));
const tmpConfig = join(tmpDir, 'tsconfig.json');

const relFiles = files.map((f) => relative(tmpDir, resolve(cwd, f)));

// Pull in the project's ambient .d.ts files (css module shim,
// react-pdf JSX augment, etc.) so side-effect imports like
// `import 'react-pdf/dist/Page/AnnotationLayer.css'` resolve under the
// staged-only compile. Without this, `include: []` would shut out
// everything in src/types/ and tsc reports TS2882 for any CSS import.
const ambientTypesGlob = relative(tmpDir, join(cwd, 'src/types')) + '/**/*.d.ts';

writeFileSync(
  tmpConfig,
  JSON.stringify(
    {
      extends: relative(tmpDir, join(cwd, 'tsconfig.json')),
      compilerOptions: {
        noEmit: true,
        skipLibCheck: true,
        // Explicitly list `types` so the @types/* auto-discovery
        // finds them — without this, the temp-tsconfig location
        // anchors discovery to .cache/ and misses node/react/etc.
        types: ['node', 'react', 'react-dom'],
      },
      files: relFiles,
      include: [ambientTypesGlob],
    },
    null,
    2,
  ),
);

const tsc = spawnSync('pnpm', ['exec', 'tsc', '-p', tmpConfig, '--pretty'], {
  cwd,
  stdio: 'inherit',
});

rmSync(tmpDir, { recursive: true, force: true });

process.exit(tsc.status ?? 1);
