import { readFileSync, readdirSync } from 'fs';
import { resolve } from 'path';

function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function pickRandom(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

function generateValue(varDef) {
  if (varDef.type === 'range') {
    return randomInt(varDef.min, varDef.max);
  }
  if (varDef.type === 'set') {
    return pickRandom(varDef.values);
  }
  throw new Error(`Unknown variable type: ${varDef.type}`);
}

function formatProblem(template, values) {
  return template.replace(/\{(\w+)\}/g, (_, key) => {
    if (key in values) return values[key];
    return `{${key}}`;
  });
}

function getIcons(iconDir) {
  if (!iconDir) return [];
  try {
    const resolved = resolve(iconDir);
    return readdirSync(resolved)
      .filter(f => /\.(png|jpg|jpeg|svg|webp)$/i.test(f))
      .map(f => resolve(resolved, f));
  } catch {
    return [];
  }
}

export function generateProblems(taskConfig) {
  const { template, variables, problemCount = 20, theme = {} } = taskConfig;
  const icons = getIcons(theme.icons);
  const backgroundPath = theme.background ? resolve(theme.background) : null;
  const iconReward = theme.iconReward || 1;

  const problems = [];
  const seen = new Set();
  let attempts = 0;
  const maxAttempts = problemCount * 10;

  while (problems.length < problemCount && attempts < maxAttempts) {
    attempts++;
    const values = {};
    for (const [name, def] of Object.entries(variables)) {
      values[name] = generateValue(def);
    }

    const key = Object.values(values).join(',');
    if (seen.has(key)) continue;
    seen.add(key);

    const text = formatProblem(template, values);
    const problemIndex = problems.length;
    const icon = icons.length > 0 && (problemIndex + 1) % iconReward === 0
      ? pickRandom(icons)
      : null;

    problems.push({ text, values, icon });
  }

  return {
    id: taskConfig.id,
    title: taskConfig.title,
    labels: taskConfig.labels || {},
    layout: taskConfig.layout || { columns: 2, problemsPerPage: 20 },
    background: backgroundPath,
    problems,
  };
}

const taskFile = process.argv[2];
if (taskFile) {
  const config = JSON.parse(readFileSync(resolve(taskFile), 'utf-8'));
  const result = generateProblems(config);
  console.log(JSON.stringify(result, null, 2));
}
