// Nya versionen av MenuService med Entity Framework
using Aberwyn.Models;
using Microsoft.EntityFrameworkCore;
using System.Globalization;


namespace Aberwyn.Data
{
public class MenuService
{
    private readonly ApplicationDbContext _context;

    // Detta är DI-konstruktorn – används som vanligt i controllers
    public MenuService(ApplicationDbContext context)
    {
        _context = context;
    }

    // Detta är en alternativ konstruktör – används manuellt vid t.ex. import
    public static MenuService CreateWithConfig(IConfiguration config, IHostEnvironment env, bool useProdDb = false)
    {
        var builder = new DbContextOptionsBuilder<ApplicationDbContext>();

        var connStr = useProdDb
            ? config.GetConnectionString("ProdConnection")
            : config.GetConnectionString("DefaultConnection");

        builder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
        var context = new ApplicationDbContext(builder.Options);

        return new MenuService(context);
    }
        public void UpdateWeeklyMenu(MenuViewModel model)
        {
            var existing = _context.WeeklyMenus
                .Where(w => w.WeekNumber == model.WeekNumber && w.Year == model.Year)
                .ToList();

            _context.WeeklyMenus.RemoveRange(existing);
            _context.WeeklyMenus.AddRange(model.WeeklyMenus);
            _context.SaveChanges();
        }
        public int AddMeal(Meal meal)
        {
            SaveMeal(meal);
            return meal.Id;
        }




        public void SaveMeal(Meal meal)
        {
            if (string.IsNullOrWhiteSpace(meal?.Name)) return;

            meal.Name = meal.Name.Trim();
            meal.CreatedAt = meal.CreatedAt == default ? DateTime.Now : meal.CreatedAt;

            if (meal.Id == 0)
                _context.Meals.Add(meal);
            else
                _context.Meals.Update(meal);

            _context.SaveChanges();
        }

public List<WeeklyMenu> GetAllWeeklyMenus()
{
    var menus = _context.WeeklyMenus.ToList();

    var allMeals = _context.Meals.ToDictionary(m => m.Id, m => m.Name);

    foreach (var wm in menus)
    {
        wm.BreakfastMealName = wm.BreakfastMealId.HasValue && allMeals.TryGetValue(wm.BreakfastMealId.Value, out var breakfast)
            ? breakfast
            : null;

        wm.LunchMealName = wm.LunchMealId.HasValue && allMeals.TryGetValue(wm.LunchMealId.Value, out var lunch)
            ? lunch
            : null;

        wm.DinnerMealName = wm.DinnerMealId.HasValue && allMeals.TryGetValue(wm.DinnerMealId.Value, out var dinner)
            ? dinner
            : null;
    }

    return menus;
}


        public List<Ingredient> GetIngredientsForMeal(int mealId)
        {
            return _context.Ingredients
                .Where(i => i.MealId == mealId)
                .ToList();
        }

        public void SaveIngredients(int mealId, List<Ingredient> ingredients)
        {
            var existing = _context.Ingredients.Where(i => i.MealId == mealId);
            _context.Ingredients.RemoveRange(existing);
            _context.Ingredients.AddRange(ingredients);
            _context.SaveChanges();
        }

        public List<Meal> GetMeals()
        {
            return _context.Meals.ToList();
        }

        public List<Meal> GetMealsDetailed()
        {
            return _context.Meals
                .OrderByDescending(m => m.CreatedAt)
                .ToList();
        }

        public Meal GetMealById(int id)
        {
            var meal = _context.Meals
                .Include(m => m.Ingredients)
                .FirstOrDefault(m => m.Id == id);
            return meal;
        }

        public void DeleteMeal(int id)
        {
            var meal = _context.Meals.Find(id);
            if (meal != null)
            {
                _context.Meals.Remove(meal);
                _context.SaveChanges();
            }
        }

        public void SaveOrUpdateMeal(Meal meal)
        {
            SaveMeal(meal);
        }

        public void SaveOrUpdateMealWithIngredients(Meal meal)
        {
            SaveMeal(meal);

            if (meal.Ingredients != null && meal.Ingredients.Count > 0)
            {
                SaveIngredients(meal.Id, meal.Ingredients);
            }
        }

        public List<Meal> GetMealsByCategory(string category)
        {
            return _context.Meals
                .Where(m => m.Category == category)
                .Include(m => m.Ingredients)
                .OrderBy(m => m.Name)
                .ToList();
        }
        public List<WeeklyMenu> GetWeeklyMenu(int weekNumber, int year)
        {
            var menus = _context.WeeklyMenus
                .Where(m => m.WeekNumber == weekNumber && m.Year == year)
                .ToList();

            var allMeals = _context.Meals.ToDictionary(m => m.Id, m => m.Name);

            foreach (var wm in menus)
            {
                wm.BreakfastMealName = wm.BreakfastMealId.HasValue && allMeals.TryGetValue(wm.BreakfastMealId.Value, out var breakfast)
                    ? breakfast
                    : null;

                wm.LunchMealName = wm.LunchMealId.HasValue && allMeals.TryGetValue(wm.LunchMealId.Value, out var lunch)
                    ? lunch
                    : null;

                wm.DinnerMealName = wm.DinnerMealId.HasValue && allMeals.TryGetValue(wm.DinnerMealId.Value, out var dinner)
                    ? dinner
                    : null;
            }

            return menus;
        }


        public List<WeeklyMenu> GetMenuEntriesByDateRange(DateTime startDate, DateTime endDate)
        {
            var results = new List<WeeklyMenu>();
            int startWeek = ISOWeek.GetWeekOfYear(startDate);
            int endWeek = ISOWeek.GetWeekOfYear(endDate);
            int startYear = startDate.Year;
            int endYear = endDate.Year;

            for (int y = startYear; y <= endYear; y++)
            {
                int fromWeek = y == startYear ? startWeek : 1;
                int toWeek = y == endYear ? endWeek : ISOWeek.GetWeeksInYear(y);

                for (int w = fromWeek; w <= toWeek; w++)
                {
                    var menus = GetWeeklyMenu(w, y);
                    foreach (var menu in menus)
                    {
                        var dow = (DayOfWeek)(menu.DayOfWeek % 7);
                        var date = ISOWeek.ToDateTime(menu.Year, menu.WeekNumber, dow);
                        if (date.Date >= startDate.Date && date.Date <= endDate.Date)
                        {
                            menu.CreatedAt = date;
                            results.Add(menu);
                        }
                    }
                }
            }
            return results;
        }
    }
}
