const DEFAULT_MAIN_PATTERN = [0, 1, 0, 2, 0, 1, 0, 1, 2, 0];

const clampToAllowed = (value, allowed, fallback) =>
  allowed.includes(value) ? value : fallback;

const getIntensity = (gapScore) => {
  if (gapScore >= 0.7) return 'hoch';
  if (gapScore >= 0.4) return 'mittel';
  return 'leicht';
};

const buildWarmupTask = () => ({
  type: 'warmup',
  title: 'Warm-up',
  durationMin: 10,
  instructions: 'Lockere Stoßserie, Fokus auf saubere Ansprechposition und Rhythmus.'
});

const buildMainTask = (exerciseName, intensity) => {
  const repetitionsByIntensity = {
    hoch: 24,
    mittel: 18,
    leicht: 12
  };

  return {
    type: 'main',
    title: `Hauptblock: ${exerciseName}`,
    durationMin: intensity === 'hoch' ? 35 : 28,
    repetitions: repetitionsByIntensity[intensity],
    intensity,
    instructions: 'Dokumentiere Trefferquote pro Serie und halte Pausen kurz (30-45 Sek.).'
  };
};

const buildSecondaryTask = (exerciseName, order) => ({
  type: 'secondary',
  title: `Nebenblock ${order}: ${exerciseName}`,
  durationMin: 18,
  repetitions: 10,
  intensity: 'mittel',
  instructions: 'Konstanter Ablauf, Fokus auf Präzision statt Tempo.'
});

const buildCooldownTask = () => ({
  type: 'cooldown',
  title: 'Cool-down',
  durationMin: 8,
  instructions: 'Kurze Reflexion: 2 Dinge die gut liefen, 1 Punkt für den nächsten Tag.'
});

const pickMainExercise = (index, topWeaknesses) => {
  if (!topWeaknesses.length) {
    return { name: 'Generelle Basistechnik', gapScore: 0.3, priorityScore: 0.3 };
  }

  const patternIndex = DEFAULT_MAIN_PATTERN[index % DEFAULT_MAIN_PATTERN.length];
  const safeIndex = patternIndex % topWeaknesses.length;
  return topWeaknesses[safeIndex];
};

const pickSecondaryExercises = (mainExerciseName, topWeaknesses, topStrengths) => {
  const pool = [
    ...topWeaknesses.map((item) => item?.name),
    ...topStrengths.map((item) => item?.name)
  ].filter(Boolean);

  const uniquePool = [...new Set(pool)].filter((name) => name !== mainExerciseName);

  if (uniquePool.length >= 2) return uniquePool.slice(0, 2);
  if (uniquePool.length === 1) return [uniquePool[0], 'Positionsspiel Basis'];
  return ['Positionsspiel Basis', 'Stoßroutine Stabilisierung'];
};

export const generateTrainingPlan = ({
  topWeaknesses = [],
  topStrengths = [],
  durationWeeks = 4,
  sessionsPerWeek = 3,
  sessionMix = '1-main-2-secondary'
} = {}) => {
  const safeDurationWeeks = clampToAllowed(Number(durationWeeks), [2, 4, 6], 4);
  const safeSessionsPerWeek = clampToAllowed(Number(sessionsPerWeek), [2, 3, 4], 3);

  const totalSessions = safeDurationWeeks * safeSessionsPerWeek;

  const sessions = Array.from({ length: totalSessions }, (_, index) => {
    const weekNo = Math.floor(index / safeSessionsPerWeek) + 1;
    const sessionNo = (index % safeSessionsPerWeek) + 1;

    const mainExercise = pickMainExercise(index, topWeaknesses);
    const intensity = getIntensity(Number(mainExercise?.gapScore || 0));
    const secondaryExercises = pickSecondaryExercises(mainExercise?.name, topWeaknesses, topStrengths);

    const tasks = [
      buildWarmupTask(),
      buildMainTask(mainExercise?.name || 'Basistechnik', intensity),
      buildSecondaryTask(secondaryExercises[0], 1),
      buildSecondaryTask(secondaryExercises[1], 2),
      buildCooldownTask()
    ];

    return {
      weekNo,
      sessionNo,
      mainExercise: mainExercise?.name || 'Basistechnik',
      secondaryExercises,
      sessionMix,
      intensity,
      state: 'open',
      notes: '',
      tasks,
      meta: {
        gapScore: Number(mainExercise?.gapScore || 0),
        priorityScore: Number(mainExercise?.priorityScore || 0)
      }
    };
  });

  return {
    durationWeeks: safeDurationWeeks,
    sessionsPerWeek: safeSessionsPerWeek,
    sessions
  };
};

export default generateTrainingPlan;
