using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Aberwyn.Models;
using Aberwyn.Data;
using System;
using System.Globalization;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Authorization;

namespace Aberwyn.Controllers
{
    public class FoodMenuController : Controller
    {
        private readonly IConfiguration _configuration;
        private readonly IHostEnvironment _env;
        private readonly MenuService _menuService;
        private readonly ApplicationDbContext _context;

        public FoodMenuController(MenuService menuService, IConfiguration configuration, IHostEnvironment env, ApplicationDbContext context)
        {
            _menuService = menuService;
            
            _configuration = configuration;
            _env = env;
            _context = context;
        }

        [HttpGet]
        public IActionResult PizzaOrder()
        {
            var pizzas = _menuService.GetMealsByCategory("Pizza")
                .Where(p => p.IsAvailable)
                .ToList();

            ViewBag.Pizzas = pizzas;
            ViewBag.RestaurantIsOpen = GetRestaurantStatus(); 

            int? lastId = HttpContext.Session.GetInt32("LastPizzaOrderId");
            if (lastId.HasValue)
            {
                var previousOrder = _context.PizzaOrders.FirstOrDefault(o => o.Id == lastId.Value);
                if (previousOrder != null)
                {
                    ViewBag.PreviousOrder = previousOrder;
                }
            }

            return View();
        }


        [HttpGet]
        public IActionResult EditPizzaOrder(int id)
        {
            var order = _context.PizzaOrders.FirstOrDefault(o => o.Id == id);
            if (order == null)
            {
                return RedirectToAction("PizzaOrder");
            }

            // S�tt session s� vi vet att det �r en uppdatering
            HttpContext.Session.SetInt32("LastPizzaOrderId", order.Id);

            // Visa formul�ret
            TempData["ForceShowForm"] = "true";

            return RedirectToAction("PizzaOrder");
        }



        [HttpPost]
        public IActionResult ClearPizzaSession()
        {
            HttpContext.Session.Remove("LastPizzaOrderId");
            return RedirectToAction("PizzaOrder");
        }


        [HttpPost]
        public IActionResult PizzaOrder(string customerName, string pizzaName, string ingredients, int? orderId)
        {
            if (string.IsNullOrWhiteSpace(customerName) || string.IsNullOrWhiteSpace(pizzaName))
            {
                TempData["Error"] = "Fyll i b�de namn och pizza!";
                return RedirectToAction("PizzaOrder");
            }

            int? lastId = orderId ?? HttpContext.Session.GetInt32("LastPizzaOrderId");
            PizzaOrder order;

            if (lastId.HasValue)
            {
                // Uppdatera befintlig order
                order = _context.PizzaOrders.FirstOrDefault(o => o.Id == lastId.Value);
                if (order != null)
                {
                    order.CustomerName = customerName.Trim();
                    order.PizzaName = pizzaName.Trim();
                    order.IngredientsJson = ingredients;
                    order.Status = "Unconfirmed";// �terst�ll status om du vill
                    _context.SaveChanges();

                    TempData["Success"] = $"Din best�llning har uppdaterats!";
                    return RedirectToAction("PizzaOrder");
                }
            }

            // Annars skapa ny
            order = new PizzaOrder
            {
                CustomerName = customerName.Trim(),
                PizzaName = pizzaName.Trim(),
                IngredientsJson = ingredients,
                Status = "Unconfirmed",
                OrderedAt = DateTime.Now
            };

            _context.PizzaOrders.Add(order);
            _context.SaveChanges();
            TempData["ForceShowForm"] = "true";


            HttpContext.Session.SetInt32("LastPizzaOrderId", order.Id);

            TempData["Success"] = $"Tack {order.CustomerName}! Din pizza �r best�lld!";
            return RedirectToAction("PizzaOrder");
        }



        [Authorize(Roles = "Chef")]
        public IActionResult PizzaAdmin(DateTime? date)
        {
            var selectedDate = date ?? DateTime.Today;
            var nextDay = selectedDate.AddDays(1);

            var allOrders = _context.PizzaOrders
                .Where(o => o.OrderedAt >= selectedDate && o.OrderedAt < nextDay)
                .OrderBy(o => o.OrderedAt)
                .ToList();

            var viewModel = new PizzaAdminViewModel
            {
                ActiveOrders = allOrders.Where(o => o.Status != "Finished").ToList(),
                CompletedOrders = allOrders.Where(o => o.Status == "Finished").ToList()
            };

            var allMeals = _menuService.GetMeals();

            viewModel.AvailablePizzas = allMeals
            .Where(m => m.Category == "Pizza")
            .OrderBy(m => m.Name)
            .ToList();

            ViewBag.RestaurantIsOpen = GetRestaurantStatus();

            return View(viewModel);
        }




        [HttpPost]
        [Authorize(Roles = "Chef")]
        public IActionResult UpdatePizzaOrder(int id, string status, string ingredientsJson)
        {
            var order = _context.PizzaOrders.FirstOrDefault(p => p.Id == id);
            if (order != null)
            {
                order.Status = status;
                order.IngredientsJson = ingredientsJson;
                _context.SaveChanges();
            }

            return RedirectToAction("PizzaAdmin");
        }

        [Authorize(Roles = "Chef")]
        public IActionResult Veckomeny(int? week, int? year)
        {
            var menuService = _menuService;

            var today = DateTime.Today;
            int resolvedWeek = week ?? ISOWeek.GetWeekOfYear(today);
            int resolvedYear = year ?? today.Year;

            var menus = menuService.GetWeeklyMenu(resolvedWeek, resolvedYear);

            var vm = new WeeklyMenuViewModel
            {
                WeekNumber = resolvedWeek,
                Year = resolvedYear,
                WeeklyMenus = menus,
            };

            var recent = menuService
                .GetMenuEntriesByDateRange(DateTime.Now.AddDays(-28), DateTime.Now)
                .Select(x => new WeeklyMenuViewModel.RecentMenuEntry
                {
                    Date = x.CreatedAt,
                    BreakfastMealName = x.BreakfastMealName,
                    LunchMealName = x.LunchMealName,
                    DinnerMealName = x.DinnerMealName
                })
                .ToList();

            vm.RecentEntries = recent;
            ViewBag.AvailableMeals = menuService.GetMeals();

            return View(vm);
        }

        [HttpPost]
        public IActionResult AddMealAjax([FromBody] Meal meal)
        {
            if (meal == null || string.IsNullOrWhiteSpace(meal.Name))
                return BadRequest("Ogiltigt m�ltidsobjekt.");

            var service = _menuService;

            // Kontrollera om en m�ltid med samma namn redan finns
            var existing = service.GetMeals()
                .FirstOrDefault(m => m.Name.Equals(meal.Name, StringComparison.OrdinalIgnoreCase));

            if (existing == null)
            {
                // Fyll i CreatedAt om det inte s�tts automatiskt i databasen
                meal.CreatedAt = DateTime.Now;
                service.SaveOrUpdateMeal(meal);
                existing = meal;
            }
            else
            {
                // Om m�ltiden finns men saknar data (t.ex. �r bara ett namn) kan vi uppdatera den
                existing.Description = meal.Description;
                existing.ProteinType = meal.ProteinType;
                existing.CarbType = meal.CarbType;
                existing.RecipeUrl = meal.RecipeUrl;
                existing.ImageUrl = meal.ImageUrl;
                service.SaveOrUpdateMeal(existing);
            }

            return Json(new
            {
                Id = existing.Id,
                Name = existing.Name,
                Description = existing.Description,
                ProteinType = existing.ProteinType,
                CarbType = existing.CarbType,
                RecipeUrl = existing.RecipeUrl
            });
        }

        public IActionResult MealAdmin()
        {
            var service = _menuService;
            var meals = service.GetMealsDetailed();
            return View("MealAdmin", meals);
        }

        [HttpGet]
        public JsonResult SearchMeals(string term)
        {
            if (string.IsNullOrWhiteSpace(term))
                return Json(new List<string>());

            var menuService = _menuService;
            var meals = menuService.GetMeals();

            var result = meals
                .Where(m => m.Name != null && m.Name.Contains(term, StringComparison.OrdinalIgnoreCase))
                .Select(m => m.Name)
                .Distinct()
                .Take(10)
                .ToList();

            return Json(result);
        }

        [HttpPost]
        public IActionResult SaveVeckomeny(IFormCollection form, int week, int year)
        {
            var menuService = _menuService;
            var allMeals = menuService.GetMeals();

            var model = new MenuViewModel
            {
                WeekNumber = week,
                Year = year,
                WeeklyMenus = new List<WeeklyMenu>()
            };

            var entriesByDay = new Dictionary<int, WeeklyMenu>();

            foreach (var key in form.Keys.Where(k => k.StartsWith("Meal[", StringComparison.OrdinalIgnoreCase)))
            {
                var match = Regex.Match(key, @"Meal\[(\d+)\]\[(\w+)\]");
                if (!match.Success) continue;

                int day = int.Parse(match.Groups[1].Value);
                string mealType = match.Groups[2].Value;
                string mealName = form[key];
                string cook = form[$"Cook[{day}]"];

                if (!entriesByDay.TryGetValue(day, out var entry))
                {
                    entry = new WeeklyMenu
                    {
                        WeekNumber = week,
                        Year = year,
                        DayOfWeek = day + 1
                    };
                    entriesByDay[day] = entry;
                }

                entry.Cook = cook;

                if (string.IsNullOrWhiteSpace(mealName))
                {
                    switch (mealType.ToLower())
                    {
                        case "lunch":
                            entry.LunchMealId = null;
                            entry.LunchMealName = null;
                            break;
                        case "middag":
                            entry.DinnerMealId = null;
                            entry.DinnerMealName = null;
                            break;
                        case "frukost":
                            entry.BreakfastMealId = null;
                            entry.BreakfastMealName = null;
                            break;
                    }
                    continue;
                }

                var meal = allMeals.FirstOrDefault(m => m.Name.Equals(mealName, StringComparison.OrdinalIgnoreCase))
                           ?? new Meal { Name = mealName };

                if (meal.Id == 0)
                    menuService.SaveOrUpdateMeal(meal);

                switch (mealType.ToLower())
                {
                    case "lunch":
                        entry.LunchMealId = meal.Id;
                        entry.LunchMealName = meal.Name;
                        break;
                    case "middag":
                        entry.DinnerMealId = meal.Id;
                        entry.DinnerMealName = meal.Name;
                        break;
                    case "frukost":
                        entry.BreakfastMealId = meal.Id;
                        entry.BreakfastMealName = meal.Name;
                        break;
                }
            }

            model.WeeklyMenus = entriesByDay.Values.ToList();
            menuService.UpdateWeeklyMenu(model);

            return RedirectToAction("Veckomeny", new { week, year });
        }
        
        private bool GetRestaurantStatus()
        {
            var value = _context.AppSettings.FirstOrDefault(s => s.Key == "RestaurantIsOpen")?.Value;
            return bool.TryParse(value, out var isOpen) && isOpen;
        }


        private void SetRestaurantStatus(bool isOpen)
        {
            var setting = _context.AppSettings.FirstOrDefault(s => s.Key == "RestaurantIsOpen");
            if (setting == null)
            {
                setting = new AppSetting { Key = "RestaurantIsOpen", Value = isOpen.ToString().ToLower() };
                _context.AppSettings.Add(setting);
            }
            else
            {
                setting.Value = isOpen.ToString().ToLower();
                _context.AppSettings.Update(setting);
            }
            _context.SaveChanges();
        }
        [HttpPost]
        [Authorize(Roles = "Chef")]
        public IActionResult ToggleRestaurant(bool isOpen)
        {
            var existing = _context.AppSettings.FirstOrDefault(s => s.Key == "RestaurantIsOpen");
            if (existing != null)
            {
                existing.Value = isOpen.ToString();
            }
            else
            {
                _context.AppSettings.Add(new AppSetting { Key = "RestaurantIsOpen", Value = isOpen.ToString() });
            }
            _context.SaveChanges();

            return RedirectToAction("PizzaAdmin");
        }
        [Authorize(Roles = "Chef")]
        public IActionResult PizzaAdminPartial()
        {
            var today = DateTime.Today;
            var tomorrow = today.AddDays(1);

            var allOrders = _context.PizzaOrders
                .Where(o => o.OrderedAt >= today && o.OrderedAt < tomorrow)
                .OrderBy(o => o.OrderedAt)
                .ToList();

            var allMeals = _menuService.GetMealsByCategory("Pizza");

            var vm = new PizzaAdminViewModel
            {
                ActiveOrders = allOrders.Where(o => o.Status != "Finished").ToList(),
                CompletedOrders = allOrders.Where(o => o.Status == "Finished").ToList(),
                AvailablePizzas = allMeals,
                RestaurantIsOpen = GetRestaurantStatus()
            };

            return PartialView("_PizzaAdminPartial", vm);
        }


        [HttpPost]
        [Authorize(Roles = "Chef")]
        public IActionResult UpdatePizzaAvailability(List<int> availableIds)
        {
            availableIds ??= new List<int>(); // Om null, ers�tt med tom lista

            var allPizzas = _menuService.GetMealsByCategory("Pizza");

            foreach (var meal in allPizzas)
            {
                var isAvailable = availableIds.Contains(meal.Id);
                if (meal.IsAvailable != isAvailable)
                {
                    meal.IsAvailable = isAvailable;
                    _menuService.SaveOrUpdateMeal(meal);
                }
            }

            return RedirectToAction("PizzaAdmin");
        }

    }

}
