#!/usr/bin/env node
/**
 * Fetches kinds.json from the nostr library and generates TypeScript definitions
 * Run: node scripts/fetch-kinds.js
 */

import { writeFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const KINDS_URL = 'https://git.mleku.dev/mleku/nostr/raw/branch/main/encoders/kind/kinds.json';

async function fetchKinds() {
  console.log(`Fetching kinds from ${KINDS_URL}...`);

  const response = await fetch(KINDS_URL);
  if (!response.ok) {
    throw new Error(`Failed to fetch kinds.json: ${response.status} ${response.statusText}`);
  }

  const data = await response.json();
  console.log(`Fetched ${Object.keys(data.kinds).length} kinds (version: ${data.version})`);

  return data;
}

function generateTypeScript(data) {
  const kinds = [];

  for (const [kindNum, info] of Object.entries(data.kinds)) {
    const k = parseInt(kindNum, 10);

    // Determine classification
    let classification = 'regular';
    if (info.classification) {
      classification = info.classification;
    } else if (k === 0 || k === 3 || (k >= data.ranges.replaceable.start && k < data.ranges.replaceable.end)) {
      classification = 'replaceable';
    } else if (k >= data.ranges.parameterized.start && k <= data.ranges.parameterized.end) {
      classification = 'parameterized';
    } else if (k >= data.ranges.ephemeral.start && k < data.ranges.ephemeral.end) {
      classification = 'ephemeral';
    }

    kinds.push({
      kind: k,
      name: info.name,
      description: info.description,
      nip: info.nip || null,
      classification,
      deprecated: info.deprecated || false,
      spec: info.spec || null
    });
  }

  // Sort by kind number
  kinds.sort((a, b) => a.kind - b.kind);

  return `/**
 * Nostr Event Kinds Database
 * Auto-generated from ${KINDS_URL}
 * Version: ${data.version}
 * Source: ${data.source}
 *
 * DO NOT EDIT - This file is auto-generated by scripts/fetch-kinds.js
 */

export interface KindInfo {
  kind: number;
  name: string;
  description: string;
  nip: string | null;
  classification: 'regular' | 'replaceable' | 'ephemeral' | 'parameterized';
  deprecated: boolean;
  spec: string | null;
}

export interface KindRanges {
  regular: { start: number; end: number; description: string };
  replaceable: { start: number; end: number; description: string };
  ephemeral: { start: number; end: number; description: string };
  parameterized: { start: number; end: number; description: string };
}

export const EVENT_KINDS: KindInfo[] = ${JSON.stringify(kinds, null, 2)};

export const KIND_RANGES: KindRanges = ${JSON.stringify(data.ranges, null, 2)};

export const PRIVILEGED_KINDS: number[] = ${JSON.stringify(data.privileged)};

export const DIRECTORY_KINDS: number[] = ${JSON.stringify(data.directory)};

export const KIND_ALIASES: Record<string, number> = ${JSON.stringify(data.aliases, null, 2)};

// Lookup map for fast access
const kindMap = new Map<number, KindInfo>(EVENT_KINDS.map(k => [k.kind, k]));

export function getKindInfo(kind: number): KindInfo | undefined {
  return kindMap.get(kind);
}

export function getKindName(kind: number): string {
  const info = kindMap.get(kind);
  return info ? info.name : \`Kind \${kind}\`;
}

export function isReplaceable(kind: number): boolean {
  if (kind === 0 || kind === 3) return true;
  return kind >= KIND_RANGES.replaceable.start && kind < KIND_RANGES.replaceable.end;
}

export function isEphemeral(kind: number): boolean {
  return kind >= KIND_RANGES.ephemeral.start && kind < KIND_RANGES.ephemeral.end;
}

export function isParameterized(kind: number): boolean {
  return kind >= KIND_RANGES.parameterized.start && kind <= KIND_RANGES.parameterized.end;
}

export function isPrivileged(kind: number): boolean {
  return PRIVILEGED_KINDS.includes(kind);
}

export function isDirectoryKind(kind: number): boolean {
  return DIRECTORY_KINDS.includes(kind);
}
`;
}

async function main() {
  try {
    const data = await fetchKinds();
    const ts = generateTypeScript(data);

    // Write to common library
    const outPath = join(__dirname, '..', 'projects', 'common', 'src', 'lib', 'constants', 'event-kinds.ts');

    writeFileSync(outPath, ts);
    console.log(`Generated ${outPath} with ${Object.keys(data.kinds).length} kinds`);
  } catch (error) {
    console.error('Error:', error.message);
    process.exit(1);
  }
}

main();
