import type { NutritionTargetRepository } from './nutrition-target.repository.js';
import type { SetNutritionTargetInput } from '@meshitrack/shared';

interface Deps {
  nutritionTargetRepository: NutritionTargetRepository;
}

export type PresetType = 'maintenance' | 'loss' | 'gain';

export class NutritionTargetService {
  private readonly nutritionTargetRepository: NutritionTargetRepository;

  public constructor({ nutritionTargetRepository }: Deps) {
    this.nutritionTargetRepository = nutritionTargetRepository;
  }

  public async getActiveByUser(userId: string, householdId: string) {
    return this.nutritionTargetRepository.findByUser(userId, householdId);
  }

  public async getAllByUser(userId: string, householdId: string) {
    return this.nutritionTargetRepository.findAllByUser(userId, householdId);
  }

  public async setTarget(userId: string, householdId: string, input: SetNutritionTargetInput) {
    // Maintain invariant: only one target is active per user per household
    if (input.isActive !== false) {
      await this.nutritionTargetRepository.deactivateAllForUser(userId, householdId);
    }

    return this.nutritionTargetRepository.create({
      ...input,
      userId,
      householdId,
    });
  }

  /**
   * Calculate macros based on calorie goal and strategy preset.
   * - Maintenance: 30% Protein, 40% Carbs, 30% Fat
   * - Loss: 40% Protein, 30% Carbs, 30% Fat
   * - Gain: 25% Protein, 50% Carbs, 25% Fat
   */
  public calculatePreset(calories: number, preset: PresetType): SetNutritionTargetInput {
    let proteinPct: number;
    let carbsPct: number;
    let fatPct: number;

    switch (preset) {
      case 'loss':
        proteinPct = 0.4;
        carbsPct = 0.3;
        fatPct = 0.3;
        break;
      case 'gain':
        proteinPct = 0.25;
        carbsPct = 0.5;
        fatPct = 0.25;
        break;
      case 'maintenance':
      default:
        proteinPct = 0.3;
        carbsPct = 0.4;
        fatPct = 0.3;
        break;
    }

    // 4 kcal per gram of protein/carb, 9 kcal per gram of fat
    const proteinG = Math.round((calories * proteinPct) / 4);
    const carbsG = Math.round((calories * carbsPct) / 4);
    const fatG = Math.round((calories * fatPct) / 9);

    return {
      dailyCalories: calories,
      proteinG,
      carbsG,
      fatG,
      isActive: true,
    };
  }
}
