using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Aberwyn.Models;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;

namespace Aberwyn.Controllers
{

    [Authorize(Roles = "Admin")]
    public class AdminController : Controller
    {
        private readonly MenuService _menuService;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly RoleManager<IdentityRole> _roleManager;
        private readonly IConfiguration _configuration;
        private readonly IHostEnvironment _env;
        private readonly ApplicationDbContext _context;

        public AdminController(
            MenuService menuService,
            UserManager<ApplicationUser> userManager,
            RoleManager<IdentityRole> roleManager,
            IConfiguration configuration,
            IHostEnvironment env,
            ApplicationDbContext context)
        {
            _menuService = menuService;
            _userManager = userManager;
            _roleManager = roleManager;
            _configuration = configuration;
            _env = env;
            _context = context;
        }

        public async Task<IActionResult> Index()
        {
            var users = _userManager.Users.ToList();
            var model = new List<AdminUserViewModel>();

            foreach (var user in users)
            {
                var roles = await _userManager.GetRolesAsync(user);
                model.Add(new AdminUserViewModel
                {
                    UserId = user.Id,
                    Email = user.Email,
                    Roles = roles.ToList()
                });
            }
            var allRoles = _roleManager.Roles.Select(r => r.Name).ToList();
            ViewBag.AllRoles = allRoles;
            return View(model);
        }
        [HttpPost]
        public async Task<IActionResult> CreateUser(string email, string password)
        {
            var user = new ApplicationUser { UserName = email, Email = email };
            var result = await _userManager.CreateAsync(user, password);

            if (result.Succeeded)
            {
                TempData["Message"] = "Användare skapad!";
                return RedirectToAction("Index");
            }

            foreach (var error in result.Errors)
            {
                ModelState.AddModelError("", error.Description);
            }
            return RedirectToAction("Index");
        }

        [HttpPost]
        public async Task<IActionResult> AddToRole(string userId, string role)
        {
            var user = await _userManager.FindByIdAsync(userId);
            if (user != null && await _roleManager.RoleExistsAsync(role))
            {
                await _userManager.AddToRoleAsync(user, role);
            }
            return RedirectToAction("Index");
        }

        [HttpPost]
        public async Task<IActionResult> RemoveFromRole(string userId, string role)
        {
            var user = await _userManager.FindByIdAsync(userId);
            if (user != null && await _userManager.IsInRoleAsync(user, role))
            {
                await _userManager.RemoveFromRoleAsync(user, role);
            }
            return RedirectToAction("Index");
        }
        [HttpPost]
        public async Task<IActionResult> CreateRole(string roleName)
        {
            if (!string.IsNullOrWhiteSpace(roleName) && !await _roleManager.RoleExistsAsync(roleName))
            {
                await _roleManager.CreateAsync(new IdentityRole(roleName));
            }

            return RedirectToAction("Index");
        }
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public IActionResult ImportMenusFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
        {
            var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";
            var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
            optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));

            using var customContext = new ApplicationDbContext(optionsBuilder.Options);
            var sourceService = new MenuService(customContext);
            var devService = new MenuService(_context);

            var sourceMenus = sourceService.GetAllWeeklyMenus();
            var devMeals = devService.GetMeals();

            foreach (var menu in sourceMenus)
            {
                var newMenu = new WeeklyMenu
                {
                    DayOfWeek = menu.DayOfWeek,
                    WeekNumber = menu.WeekNumber,
                    Year = menu.Year,
                    Cook = menu.Cook,
                    BreakfastMealId = null,
                    LunchMealId = null,
                    DinnerMealId = null
                };

                if (!string.IsNullOrEmpty(menu.BreakfastMealName))
                    newMenu.BreakfastMealId = devMeals.FirstOrDefault(m => m.Name == menu.BreakfastMealName)?.Id;

                if (!string.IsNullOrEmpty(menu.LunchMealName))
                    newMenu.LunchMealId = devMeals.FirstOrDefault(m => m.Name == menu.LunchMealName)?.Id;

                if (!string.IsNullOrEmpty(menu.DinnerMealName))
                    newMenu.DinnerMealId = devMeals.FirstOrDefault(m => m.Name == menu.DinnerMealName)?.Id;

                _context.WeeklyMenus.Add(newMenu);
            }

            _context.SaveChanges();
            TempData["Message"] = $"✅ Import av veckomenyer från extern databas klar ({sourceMenus.Count}).";
            return RedirectToAction("Index");
        }
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public IActionResult GenerateThumbnails()
        {
            var count = _menuService.GenerateMissingThumbnails();
            return Ok($"{count} thumbnails skapades.");
        }


        [HttpPost]
        [Authorize(Roles = "Admin")]
        public IActionResult ImportMealsFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
        {
            var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";
            var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
            optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr), mySqlOptions => mySqlOptions.CommandTimeout(180));
            using var customContext = new ApplicationDbContext(optionsBuilder.Options);

            var customService = new MenuService(customContext);
            var devService = new MenuService(_context);

            try
            {
                var importedMeals = customService.GetMealsDetailed(); // Ska inkludera Ingredients
                foreach (var meal in importedMeals)
                {
                    var newMeal = new Meal
                    {
                        Id = meal.Id, // 👈 Viktigt!
                        Name = meal.Name,
                        Description = meal.Description,
                        ProteinType = meal.ProteinType,
                        Category = meal.Category,
                        CarbType = meal.CarbType,
                        RecipeUrl = meal.RecipeUrl,
                        ImageUrl = meal.ImageUrl,
                        IsAvailable = meal.IsAvailable,
                        CreatedAt = meal.CreatedAt,
                        Instructions = meal.Instructions,
                        ImageData = meal.ImageData,
                        ImageMimeType = meal.ImageMimeType,
                        Ingredients = meal.Ingredients.Select(i => new Ingredient
                        {
                            MealId = meal.Id, // 👈 Koppla till rätt måltid
                            Quantity = i.Quantity,
                            Item = i.Item
                        }).ToList()
                    };

                    devService.SaveOrUpdateMealWithIngredients(newMeal);
                }

                TempData["Message"] = $"✅ {importedMeals.Count} måltider importerade från extern databas.";
            }
            catch (Exception ex)
            {
                TempData["Message"] = $"❌ Fel vid import: {ex.Message}";
            }

            return RedirectToAction("Index");
        }



        [HttpPost]
        [Authorize(Roles = "Admin")]
        public IActionResult ImportBudgetFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
        {
            var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";
            var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
            optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));

            using var sourceContext = new ApplicationDbContext(optionsBuilder.Options);

            var categoryDefs = sourceContext.BudgetCategoryDefinitions.ToList();
            var itemDefs = sourceContext.BudgetItemDefinitions.ToList();

            foreach (var def in categoryDefs)
            {
                if (!_context.BudgetCategoryDefinitions.Any(d => d.Name == def.Name))
                {
                    _context.BudgetCategoryDefinitions.Add(new BudgetCategoryDefinition
                    {
                        Name = def.Name,
                        Color = def.Color ?? "#cccccc"
                    });
                }
            }

            foreach (var def in itemDefs)
            {
                if (!_context.BudgetItemDefinitions.Any(d => d.Name == def.Name))
                {
                    _context.BudgetItemDefinitions.Add(new BudgetItemDefinition { Name = def.Name });
                }
            }

            _context.SaveChanges();

            var devCategoryDefs = _context.BudgetCategoryDefinitions.ToList();
            var devItemDefs = _context.BudgetItemDefinitions.ToList();

            var periods = sourceContext.BudgetPeriods
                .Include(p => p.Categories)
                    .ThenInclude(c => c.Items)
                .ToList();

            foreach (var period in periods)
            {
                var exists = _context.BudgetPeriods
                    .Any(p => p.Year == period.Year && p.Month == period.Month);

                if (exists)
                    continue;

                var newPeriod = new BudgetPeriod
                {
                    Year = period.Year,
                    Month = period.Month,
                    Categories = period.Categories.Select(c => new BudgetCategory
                    {
                        Name = c.Name,
                        Color = string.IsNullOrWhiteSpace(c.Color) ? "#cccccc" : c.Color,
                        Order = c.Order,
                        BudgetCategoryDefinitionId = devCategoryDefs
                            .FirstOrDefault(d => d.Name == c.Definition?.Name)?.Id,
                        Items = c.Items.Select(i => new BudgetItem
                        {
                            Name = i.Name,
                            Amount = i.Amount,
                            IsExpense = i.IsExpense,
                            IncludeInSummary = i.IncludeInSummary,
                            Order = i.Order,
                            BudgetItemDefinitionId = devItemDefs
                                .FirstOrDefault(d => d.Name == i.BudgetItemDefinition?.Name)?.Id
                        }).ToList()
                    }).ToList()
                };

                _context.BudgetPeriods.Add(newPeriod);
            }

            _context.SaveChanges();
            TempData["Message"] = $"✅ Import av budgetdata från extern databas klar ({periods.Count} månader).";
            return RedirectToAction("Index");
        }




        //Todo

        [HttpGet]
        public IActionResult Todo()
        {
            return View();
        }


        [HttpGet]
        public IActionResult GetTodoTasks()
        {
            var tasks = _context.TodoTasks
                .OrderByDescending(t => t.CreatedAt)
                .ToList();
            return Json(tasks);
        }

        [HttpPost]
        public IActionResult AddTodoTask([FromBody] TodoTask task)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(task?.Title))
                    return BadRequest("Titel krävs");

                task.CreatedAt = DateTime.UtcNow;

                task.Status ??= "ideas";
                task.Tags ??= "";
                task.AssignedTo ??= null;
                task.Description ??= "";

                _context.TodoTasks.Add(task);
                _context.SaveChanges();

                return Json(task);
            }
            catch (Exception ex)
            {
                // 👇 Returnera hela stacktracen som JSON för felsökning
                return StatusCode(500, ex.ToString());
            }
        }


        [HttpPost]
        public IActionResult UpdateTodoTask([FromBody] TodoTask task)
        {
            var existing = _context.TodoTasks.FirstOrDefault(t => t.Id == task.Id);
            if (existing == null)
                return NotFound();

            existing.Title = task.Title;
            existing.Status = task.Status;
            existing.Priority = task.Priority;
            existing.Description = task.Description;
            existing.Tags = task.Tags;
            existing.AssignedTo = task.AssignedTo;
            existing.IsArchived = task.IsArchived;

            _context.SaveChanges();

            return Ok();
        }
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public IActionResult TestDbConnection(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
        {
            var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";

            try
            {
                var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
                builder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));

                using var context = new ApplicationDbContext(builder.Options);
                context.Database.OpenConnection();
                context.Database.CloseConnection();

                return Json(new { success = true, message = "✅ Anslutning lyckades!" });
            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = $"❌ Anslutning misslyckades: {ex.Message}" });
            }
        }
    }


    public class AdminUserViewModel
        {
            public string UserId { get; set; }
            public string Email { get; set; }
            public List<string> Roles { get; set; }
        }
}
