import * as fs from 'node:fs';
import * as path from 'node:path';

export function installOpenMatrixCoreStub(projectDir: string): void {
  const pkgDir = path.join(projectDir, 'node_modules', '@open-matrix', 'core');
  fs.mkdirSync(pkgDir, { recursive: true });
  fs.writeFileSync(
    path.join(pkgDir, 'package.json'),
    JSON.stringify({
      name: '@open-matrix/core',
      type: 'module',
      types: './index.d.ts',
      exports: {
        '.': './index.js',
      },
    }, null, 2) + '\n',
    'utf8',
  );
  fs.writeFileSync(
    path.join(pkgDir, 'index.js'),
    [
      'export class MatrixActor {',
      '  static accepts = {};',
      '  static emits = {};',
      '}',
      '',
      'export class MatrixActorHtmlElement extends MatrixActor {}',
      '',
      'export class InMemoryBroker {}',
      '',
      'export class InMemoryTransport {',
      '  constructor(_broker, options = {}) {',
      '    this.root = options.root || options.name || null;',
      '  }',
      '}',
      '',
      'export class MatrixRuntime {',
      '  constructor(options = {}) {',
      '    this.transport = options.transport || { root: null };',
      '  }',
      '  async createSupervised(ActorClass, mount) {',
      '    const actor = new ActorClass();',
      '    actor.mount = mount;',
      '    return actor;',
      '  }',
      '}',
      '',
    ].join('\n'),
    'utf8',
  );
  fs.writeFileSync(
    path.join(pkgDir, 'index.d.ts'),
    [
      'export class MatrixActor {',
      '  static accepts: Record<string, unknown>;',
      '  static emits: Record<string, unknown>;',
      '}',
      '',
      'export class MatrixActorHtmlElement extends MatrixActor {}',
      '',
      'export class InMemoryBroker {}',
      '',
      'export class InMemoryTransport {',
      '  readonly root?: string | null;',
      '  constructor(broker: InMemoryBroker, options?: { name?: string; root?: string });',
      '}',
      '',
      'export class MatrixRuntime {',
      '  readonly transport: { readonly root?: string | null };',
      '  constructor(options?: { transport?: InMemoryTransport; logging?: boolean });',
      '  createSupervised<TActor>(ActorClass: new () => TActor, mount: string): Promise<TActor>;',
      '}',
      '',
    ].join('\n'),
    'utf8',
  );
}
