import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, map } from 'rxjs';
import {
  CopyMealsResult,
  CreateDietReminderInput,
  DailySummary,
  DietReminder,
  DietSuggestion,
  DrinkCatalogItem,
  DueReminder,
  FavoriteCatalogItem,
  FavoriteRecipe,
  HistoryDay,
  LogDrinkInput,
  LogMealInput,
  MealConsumption,
  MealPreview,
  RecentMeal,
  UpdateDietReminderInput,
  UserDailyGoals,
  todayIso,
} from '../models/diet.models';
import { normalizeDailySummary } from '../utils/diet-normalize.util';

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

  getSummary(date = todayIso()): Observable<DailySummary> {
    return this.http
      .get<unknown>('/api/diet/summary', { params: { date } })
      .pipe(map(normalizeDailySummary));
  }

  getGoals(): Observable<UserDailyGoals> {
    return this.http.get<UserDailyGoals>('/api/diet/goals');
  }

  saveGoals(goals: UserDailyGoals): Observable<UserDailyGoals> {
    return this.http.put<UserDailyGoals>('/api/diet/goals', goals);
  }

  logMeal(input: LogMealInput): Observable<MealConsumption> {
    return this.http.post<MealConsumption>('/api/diet/meals', input);
  }

  previewMeal(input: LogMealInput, date = todayIso()): Observable<MealPreview> {
    return this.http.post<MealPreview>('/api/diet/meals/preview', input, { params: { date } });
  }

  getSuggestions(date = todayIso(), limit = 5): Observable<DietSuggestion[]> {
    return this.http.get<DietSuggestion[]>('/api/diet/suggestions', { params: { date, limit } });
  }

  deleteMeal(id: number): Observable<void> {
    return this.http.delete<void>(`/api/diet/meals/${id}`);
  }

  getDrinkCatalog(): Observable<DrinkCatalogItem[]> {
    return this.http.get<DrinkCatalogItem[]>('/api/diet/drinks/catalog');
  }

  logDrink(input: LogDrinkInput): Observable<void> {
    return this.http.post<void>('/api/diet/drinks', input);
  }

  deleteDrink(id: number): Observable<void> {
    return this.http.delete<void>(`/api/diet/drinks/${id}`);
  }

  getReminders(): Observable<DietReminder[]> {
    return this.http.get<DietReminder[]>('/api/diet/reminders');
  }

  getDueReminders(date = todayIso(), time?: string): Observable<DueReminder[]> {
    const params: Record<string, string> = { date };
    if (time) params['time'] = time;
    return this.http.get<DueReminder[]>('/api/diet/reminders/due', { params });
  }

  createReminder(input: CreateDietReminderInput): Observable<DietReminder> {
    return this.http.post<DietReminder>('/api/diet/reminders', input);
  }

  updateReminder(id: number, input: UpdateDietReminderInput): Observable<DietReminder> {
    return this.http.put<DietReminder>(`/api/diet/reminders/${id}`, input);
  }

  deleteReminder(id: number): Observable<void> {
    return this.http.delete<void>(`/api/diet/reminders/${id}`);
  }

  getHistory(from: string, to: string): Observable<HistoryDay[]> {
    return this.http.get<HistoryDay[]>('/api/diet/history', { params: { from, to } });
  }

  getRecentMeals(limit = 10): Observable<RecentMeal[]> {
    return this.http.get<RecentMeal[]>('/api/diet/meals/recent', { params: { limit } });
  }

  copyYesterdayMeals(date = todayIso()): Observable<CopyMealsResult> {
    return this.http.post<CopyMealsResult>('/api/diet/meals/copy-yesterday', null, { params: { date } });
  }

  getFavoriteRecipes(): Observable<FavoriteRecipe[]> {
    return this.http.get<FavoriteRecipe[]>('/api/diet/favorites/recipes');
  }

  addFavoriteRecipe(recipeId: number): Observable<FavoriteRecipe> {
    return this.http.post<FavoriteRecipe>(`/api/diet/favorites/recipes/${recipeId}`, null);
  }

  removeFavoriteRecipe(recipeId: number): Observable<void> {
    return this.http.delete<void>(`/api/diet/favorites/recipes/${recipeId}`);
  }

  getFavoriteCatalogItems(): Observable<FavoriteCatalogItem[]> {
    return this.http.get<FavoriteCatalogItem[]>('/api/diet/favorites/catalog');
  }

  addFavoriteCatalogItem(catalogItemId: number): Observable<FavoriteCatalogItem> {
    return this.http.post<FavoriteCatalogItem>(`/api/diet/favorites/catalog/${catalogItemId}`, null);
  }

  removeFavoriteCatalogItem(catalogItemId: number): Observable<void> {
    return this.http.delete<void>(`/api/diet/favorites/catalog/${catalogItemId}`);
  }
}
