import type { ActivityLevel, DailyTargets, GoalType, Sex } from "@app/shared-types";

/**
 * Energiberäkning enligt Mifflin–St Jeor. Detta är vägledning baserad på
 * officiella rekommendationer – Appen är inte medicinsk rådgivning (spec §6, §21).
 */

export interface EnergyProfile {
  sex: Sex;
  age: number;
  heightCm: number;
  weightKg: number;
  activityLevel: ActivityLevel;
  primaryGoal?: GoalType | undefined;
}

const ACTIVITY_FACTORS: Record<ActivityLevel, number> = {
  sedentary: 1.2,
  light: 1.375,
  moderate: 1.55,
  active: 1.725,
  very_active: 1.9,
};

/** Justering per mål (kcal/dag). Konservativa, väldokumenterade nivåer. */
const GOAL_ADJUSTMENTS: Partial<Record<GoalType, number>> = {
  lose_weight: -500,
  gain_weight: 400,
  build_muscle: 250,
  maintain_weight: 0,
};

/** Lägsta rekommenderade energiintag – under detta kapas aldrig målet (säkerhetsgolv). */
const MIN_KCAL = 1200;

export function bmrMifflinStJeor(
  p: Pick<EnergyProfile, "sex" | "age" | "heightCm" | "weightKg">,
): number {
  const base = 10 * p.weightKg + 6.25 * p.heightCm - 5 * p.age;
  if (p.sex === "male") return base + 5;
  if (p.sex === "female") return base - 161;
  // Ospecificerat: medelvärde av formlerna, transparent redovisat i UI.
  return base - 78;
}

export function tdee(p: EnergyProfile): number {
  return bmrMifflinStJeor(p) * ACTIVITY_FACTORS[p.activityLevel];
}

export interface DailyTargetsResult {
  targets: DailyTargets;
  basis: {
    bmrKcal: number;
    tdeeKcal: number;
    goalAdjustmentKcal: number;
    activityLevel: ActivityLevel;
  };
}

/**
 * Dagsmål: energi via TDEE + måljustering; protein per kg kroppsvikt;
 * fett som andel av energi; kolhydrater = resten; fiber 3 g/MJ (nordisk rekommendation);
 * salt max 6 g/dag.
 */
export function computeDailyTargets(p: EnergyProfile): DailyTargetsResult {
  const bmr = bmrMifflinStJeor(p);
  const maintenance = tdee(p);
  const adjustment = GOAL_ADJUSTMENTS[p.primaryGoal ?? "maintain_weight"] ?? 0;
  const kcal = Math.max(MIN_KCAL, Math.round(maintenance + adjustment));

  const proteinPerKg =
    p.primaryGoal === "build_muscle" || p.primaryGoal === "more_protein"
      ? 1.8
      : p.primaryGoal === "lose_weight"
        ? 1.6
        : 1.2;
  const proteinG = Math.round(p.weightKg * proteinPerKg);

  const fatShare = p.primaryGoal === "less_fat" ? 0.25 : 0.3;
  const fatG = Math.round((kcal * fatShare) / 9);

  const carbsKcal = Math.max(0, kcal - proteinG * 4 - fatG * 9);
  const carbsG = Math.round(carbsKcal / 4);

  // 3 g fiber per MJ (1 MJ ≈ 239 kcal)
  const fiberG = Math.round((kcal / 239) * 3);

  return {
    targets: { kcal, proteinG, carbsG, fatG, fiberG, saltMaxG: 6 },
    basis: {
      bmrKcal: Math.round(bmr),
      tdeeKcal: Math.round(maintenance),
      goalAdjustmentKcal: adjustment,
      activityLevel: p.activityLevel,
    },
  };
}

/** Standardmål när profil saknas (visas tydligt som schablon i appen). */
export const DEFAULT_TARGETS: DailyTargets = {
  kcal: 2000,
  proteinG: 80,
  carbsG: 220,
  fatG: 67,
  fiberG: 25,
  saltMaxG: 6,
};
