import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, map } from 'rxjs';
import {
  CommitDietPlanResult,
  DietGeneratorSession,
  DietUserProfile,
  MacroProposal,
} from '../models/generator.models';

@Injectable({ providedIn: 'root' })
export class DietGeneratorService {
  constructor(private readonly http: HttpClient) {}

  fetchProfile(): Observable<DietUserProfile | null> {
    return this.http.get<DietUserProfile>('/api/diet-generator/profile').pipe(
      map((data) => (data.heightCm ? data : null)),
    );
  }

  saveProfile(profile: DietUserProfile): Observable<DietUserProfile> {
    return this.http.put<DietUserProfile>('/api/diet-generator/profile', profile);
  }

  createSession(input: {
    planStartDate?: string;
    planDayCount?: number;
    calorieToleranceKcal?: number;
  }): Observable<DietGeneratorSession> {
    return this.http.post<DietGeneratorSession>('/api/diet-generator/sessions', input);
  }

  fetchSession(id: number): Observable<DietGeneratorSession> {
    return this.http.get<DietGeneratorSession>(`/api/diet-generator/sessions/${id}`);
  }

  proposeMacros(sessionId: number): Observable<DietGeneratorSession> {
    return this.http.post<DietGeneratorSession>(
      `/api/diet-generator/sessions/${sessionId}/propose-macros`,
      null,
    );
  }

  acceptMacros(sessionId: number, macros?: Partial<MacroProposal>): Observable<DietGeneratorSession> {
    return this.http.post<DietGeneratorSession>(
      `/api/diet-generator/sessions/${sessionId}/accept-macros`,
      {
        calories: macros?.calories,
        proteinG: macros?.proteinG,
        fatG: macros?.fatG,
        carbsG: macros?.carbsG,
      },
    );
  }

  generatePlan(sessionId: number): Observable<DietGeneratorSession> {
    return this.http.post<DietGeneratorSession>(
      `/api/diet-generator/sessions/${sessionId}/generate-plan`,
      null,
    );
  }

  regenerateMeal(
    sessionId: number,
    planDate: string,
    mealCategory: number,
  ): Observable<DietGeneratorSession> {
    return this.http.post<DietGeneratorSession>(
      `/api/diet-generator/sessions/${sessionId}/regenerate-meal`,
      { planDate, mealCategory },
    );
  }

  toggleMealLock(sessionId: number, mealId: number, isLocked: boolean): Observable<DietGeneratorSession> {
    return this.http.patch<DietGeneratorSession>(
      `/api/diet-generator/sessions/${sessionId}/meals/${mealId}`,
      { isLocked },
    );
  }

  commitPlan(sessionId: number): Observable<CommitDietPlanResult> {
    return this.http.post<CommitDietPlanResult>(
      `/api/diet-generator/sessions/${sessionId}/commit`,
      null,
    );
  }
}
