using System.Diagnostics;
using bitforum.Models;
using bitforum.Models.User;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using bitforum.Models.Views;

namespace bitforum.Controllers.Director
{
    [Authorize]
    [Route("Director")]
    public class UserController : Controller
    {
        private readonly ILogger<UserController> _logger;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly RoleManager<IdentityRole> _roleManager;

        public UserController(ILogger<UserController> logger, UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
        {
            _logger = logger;
            _userManager = userManager;
            _roleManager = roleManager;
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }

        [HttpGet("User")]
        public async Task<IActionResult> Index()
        {
            var currentUser = await _userManager.GetUserAsync(User);
            var allUsers = await _userManager.Users.ToListAsync();

            // 사용자와 역할 정보를 매핑
            var userViewModels = new List<UserViewModel>();

            foreach (var user in allUsers)
            {
                var roles = await _userManager.GetRolesAsync(user); // 역할 조회
                userViewModels.Add(new UserViewModel
                {
                    ID = user.Id,
                    Name = user.FullName,
                    Email = user.Email,
                    Roles = roles.ToList()
                });
            }

            return View("~/Views/Director/User/Index.cshtml", userViewModels);
        }

        [HttpGet("User/{userID}")]
        public async Task<IActionResult> Edit(string userID)
        {
            var user = new ApplicationUser();

            try
            {
                if (string.IsNullOrEmpty(userID))
                {
                    throw new Exception("유효하지 않은 사용자 ID입니다.");
                }

                user = await _userManager.FindByIdAsync(userID);

                if (user is null)
                {
                    throw new Exception("사용자 정보를 찾을 수 없습니다.");
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
                TempData["ErrorMessages"] = e.Message;
                return RedirectToAction(nameof(Index));
            }

            var viewModel = new UserViewModel{
                ID = user.Id,
                Name = user.UserName,
                Email = user.Email,
                Phone = user.PhoneNumber
            };

            return View("~/Views/Director/User/Edit.cshtml", viewModel);
        }

        [HttpPost("User")]
        public async Task<IActionResult> Update(UserViewModel request)
        {
            var user = new ApplicationUser();

            try
            {
                if (!ModelState.IsValid)
                {
                    throw new Exception("유효성 검사에 실패하였습니다.");
                }

                user = await _userManager.FindByIdAsync(request.ID);

                if (user is null)
                {
                    throw new Exception("사용자 정보를 찾을 수 없습니다.");
                }

                // 중복확인
                if (await _userManager.Users.AnyAsync(u => u.Email == request.Email && u.Id != request.ID))
                {
                    throw new Exception("이미 존재하는 이메일 주소입니다.");
                }

                // 사용자 정보 업데이트
                user.FullName = request.Name;
                user.Email = request.Email;
                user.NormalizedEmail = request.Email;
                user.PhoneNumber = request.Phone;

                var result = await _userManager.UpdateAsync(user);

                if (!result.Succeeded)
                {
                    foreach (var error in result.Errors)
                    {
                        ModelState.AddModelError(string.Empty, error.Description);
                    }

                    throw new Exception("사용자 정보를 업데이트하는 중 오류가 발생했습니다.");
                }

                TempData["SuccessMessage"] = "사용자 정보가 정상적으로 수정되었습니다.";
                return RedirectToAction(nameof(Edit), new { userID = request.ID });
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
                TempData["ErrorMessages"] = e.Message;
                return RedirectToAction(nameof(Edit), new { userID = request.ID });
            }
        }
    }
}
