import fs from 'node:fs';
import path from 'node:path';
import { describe, expect, it } from 'vitest';

const HANDLER_DIR = path.resolve(process.cwd(), 'src/handlers');

const ID_FIELD_PATTERN =
  /const\s*\{\s*[^}]*\b(?:job|habit|person|partner|item|activity|quest|event|achievement|tooltip|preset)Id\b[^}]*\}\s*=\s*payload\s+as\s+/;

const RESOLVE_PATTERN = /resolvePayload(?:Id|Field|Number)\(/;

function listHandlerFiles(): string[] {
  return fs
    .readdirSync(HANDLER_DIR)
    .filter((f) => f.endsWith('.ts') && f !== 'index.ts' && f !== 'payloadHelpers.ts')
    .map((f) => path.join(HANDLER_DIR, f));
}

describe('handler payload normalization', () => {
  it('does not destructure ID fields directly from payload without resolvePayload helpers', () => {
    const violations: string[] = [];

    for (const file of listHandlerFiles()) {
      const source = fs.readFileSync(file, 'utf8');
      const lines = source.split('\n');

      for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        if (!ID_FIELD_PATTERN.test(line)) continue;

        const window = lines.slice(Math.max(0, i - 5), i + 6).join('\n');
        if (!RESOLVE_PATTERN.test(window)) {
          violations.push(`${path.basename(file)}:${i + 1}: ${line.trim()}`);
        }
      }
    }

    expect(violations).toEqual([]);
  });

  it('payloadHelpers exports resolvePayloadId for legacy string support', () => {
    const helpers = fs.readFileSync(
      path.join(HANDLER_DIR, 'payloadHelpers.ts'),
      'utf8'
    );
    expect(helpers).toContain('resolvePayloadId');
    expect(helpers).toContain("typeof payload === 'string'");
  });
});
