import type { Parameter } from '#types';

export type CodeNodeEngine = 'javascript' | 'python';

const PYTHON_RESERVED_WORDS = new Set([
  'False',
  'None',
  'True',
  'and',
  'as',
  'assert',
  'async',
  'await',
  'break',
  'class',
  'continue',
  'def',
  'del',
  'elif',
  'else',
  'except',
  'finally',
  'for',
  'from',
  'global',
  'if',
  'import',
  'in',
  'is',
  'lambda',
  'nonlocal',
  'not',
  'or',
  'pass',
  'raise',
  'return',
  'try',
  'while',
  'with',
  'yield',
]);

const JAVASCRIPT_RESERVED_WORDS = new Set([
  'await',
  'break',
  'case',
  'catch',
  'class',
  'const',
  'continue',
  'debugger',
  'default',
  'delete',
  'do',
  'else',
  'enum',
  'export',
  'extends',
  'false',
  'finally',
  'for',
  'function',
  'if',
  'implements',
  'import',
  'in',
  'instanceof',
  'interface',
  'let',
  'new',
  'null',
  'package',
  'private',
  'protected',
  'public',
  'return',
  'static',
  'super',
  'switch',
  'this',
  'throw',
  'true',
  'try',
  'typeof',
  'var',
  'void',
  'while',
  'with',
  'yield',
]);

/**
 * 将代码节点执行引擎别名归一化为编辑器使用的语言名称。
 */
export function normalizeCodeNodeEngine(rawEngine?: string): CodeNodeEngine {
  const normalized = (rawEngine || 'js').trim().toLowerCase();
  return normalized === 'python' || normalized === 'py'
    ? 'python'
    : 'javascript';
}

/**
 * 判断参数名称能否安全写入目标语言的函数签名。
 */
export function isValidCodeNodeParameterName(name: string, rawEngine?: string) {
  const engine = normalizeCodeNodeEngine(rawEngine);
  if (engine === 'python') {
    return /^[A-Za-z_]\w*$/.test(name) && !PYTHON_RESERVED_WORDS.has(name);
  }
  return (
    /^[A-Za-z_$][\w$]*$/.test(name) && !JAVASCRIPT_RESERVED_WORDS.has(name)
  );
}

/**
 * 按配置顺序提取可安全写入函数签名的唯一参数名称。
 */
export function getCodeNodeParameterNames(
  rawEngine: string | undefined,
  parameters: Array<Pick<Parameter, 'name'>>,
) {
  const engine = normalizeCodeNodeEngine(rawEngine);
  return [
    ...new Set(
      parameters
        .map((parameter) => String(parameter.name || '').trim())
        .filter((name) => isValidCodeNodeParameterName(name, engine)),
    ),
  ];
}

/**
 * 为新代码节点生成与当前运行时兼容的 main 脚手架。
 */
export function createCodeNodeScaffold(
  rawEngine?: string,
  parameters: Parameter[] = [],
  outputDefs: Parameter[] = [],
) {
  const engine = normalizeCodeNodeEngine(rawEngine);
  const parameterNames = getCodeNodeParameterNames(engine, parameters);
  const outputNames = [
    ...new Set(
      outputDefs
        .map((parameter) => String(parameter.name || '').trim())
        .filter(Boolean),
    ),
  ];
  const argumentsText = parameterNames.join(', ');

  if (engine === 'python') {
    const outputLines = outputNames.map(
      (name) => `        ${JSON.stringify(name)}: None,`,
    );
    return [
      `def main(${argumentsText}):`,
      '    return {',
      ...outputLines,
      '    }',
    ].join('\n');
  }

  const outputLines = outputNames.map(
    (name) => `    ${JSON.stringify(name)}: null,`,
  );
  return [
    `function main(${argumentsText}) {`,
    '  return {',
    ...outputLines,
    '  };',
    '}',
  ].join('\n');
}

export const DEFAULT_CODE_NODE_JAVASCRIPT = createCodeNodeScaffold('js');
