using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using WebVentaCoche.Helpers;
using WebVentaCoche.Enums;
using WebVentaCoche.Models;
using WebVentaCoche.Services;
using WebVentaCoche.ViewModels;
using static System.Runtime.InteropServices.JavaScript.JSType;
using WebVentaCoche.DataBase;
using Microsoft.EntityFrameworkCore;

namespace WebVentaCoche.Controllers
{
    public class UserController : Controller
    {
        private readonly IUserHelper _userHelper;
        private readonly IConfiguration _configuration;
        private readonly EmailService _emailService;
        private readonly VerificationService _verificationService;
        private readonly ApplicationDbContext _context;

        public UserController(IUserHelper userHelper, IConfiguration configuration, EmailService emailService, VerificationService verificationService, ApplicationDbContext context)
        {
            _userHelper = userHelper;
            _configuration = configuration;
            _emailService = emailService;
            _verificationService = verificationService;
            _context = context;
        }

        private async Task SenConfirmationEmail(User user, string token, string confirmationLink)
        {
            await _emailService.SendEmailAsync(user.Email, "Verifica tu Email",
                       $"<p>¡Hola {user.Name}!</p>" +
                       $"<p>Gracias por registrarte en <strong>WebVentaCoche</strong>. Para completar tu registro, verifica tu correo electrónico haciendo clic en el siguiente enlace:</p>" +
                       $"<p><a href='{confirmationLink}' style='color: #007BFF; text-decoration: none; font-weight: bold;'>Verificar mi Correo</a></p>" +
                       $"<p>Si no has solicitado esto, puedes ignorar este mensaje.</p>" +
                       $"<p>¡Gracias!</p>");
        }

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

        [HttpPost]
        public async Task<IActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                User existingUser = await _userHelper.GetUserAsync(model.Email);
                if (existingUser != null)
                {
                    return BadRequest("El correo electrónico ya está en uso.");
                }
                var user = new User
                {
                    Name = model.Email,
                    Surname = model.Surname,
                    Email = model.Email,
                    PhoneNumber = model.PhoneNumber,
                    UserName = model.Email,
                    UserType = UserType.Usuario,
                };

                //Name = nombre,
                //    Surname = apellidos,
                //    Email = email,
                //    PhoneNumber = phoneNumber,
                //    Password = password,
                //    PasswordConfirm = passwordConfirm,
                //    UserName = email,
                //    UserType = UserType.Usuario
                var result = await _userHelper.AddUserAsync(user, model.Password);
                if (result.Succeeded)
                {
                    await _userHelper.AddUserRoleAsync(user, user.UserType.ToString());
                    //return Ok(BuildToken(user));

                    var token = await _userHelper.GenerateEmailConfirmationTokenAsync(user);

                    // Crea el enlace de verificación
                    var confirmationLink = Url.Action(
                        "VerifyEmail",
                        "User",
                        new { token, email = user.Email },
                        Request.Scheme);

                    SenConfirmationEmail(user, token, confirmationLink);



                    TempData["Message"] = "Registro exitoso. Revisa tu correo para confirmar tu email.";
                    return RedirectToAction("Login");
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            return View(model);
        }

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

        [HttpPost]
        public async Task<IActionResult> Login(LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await _userHelper.GetUserAsync(model.Email);

                if (user == null)
                {
                    TempData["Error"] = "Email o contraseña incorrectos.";
                    return View(model); // Redirige de nuevo al formulario de login con un mensaje de error
                }

                if (!await _userHelper.IsEmailConfirmedAsync(user))
                {

                    var token = await _userHelper.GenerateEmailConfirmationTokenAsync(user);

                    // Crea el enlace de verificación
                    var confirmationLink = Url.Action(
                        "VerifyEmail",
                        "User",
                        new { token, email = user.Email },
                        Request.Scheme);

                    SenConfirmationEmail(user, token, confirmationLink);
                    // Redirige al usuario a la página de verificación de email
                    TempData["Error"] = "Debes confirmar tu email antes de iniciar sesión.";

                    return RedirectToAction("Index", "Home");
                }

                var result = await _userHelper.LoginAsync(model);

                if (result.Succeeded)
                {
                    // Redirige al usuario al home o al lugar correspondiente
                    return RedirectToAction("Index", "Home");
                }

                TempData["Error"] = "Email o contraseña incorrectos.";
                return View(model);
            }

            return View(model);
        }

        [HttpPost]
        public async Task<IActionResult> Logout()
        {
            await _userHelper.LogoutAsync();
            return RedirectToAction("Login");
        }

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

        [HttpGet]
        public async Task<IActionResult> VerifyEmail(string token, string email)
        {
            if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(email))
            {
                TempData["Error"] = "El enlace de verificación no es válido.";
                return View();
            }

            var user = await _userHelper.GetUserAsync(email);
            if (user == null)
            {
                TempData["Error"] = "Usuario no encontrado.";
                return View();
            }

            var result = await _userHelper.ConfirmEmailAsync(user, token);
            if (result.Succeeded)
            {
                TempData["Message"] = "¡Tu correo ha sido verificado correctamente!";
            }
            else
            {
                TempData["Error"] = "El enlace de verificación es inválido o ha expirado.";
            }

            return View();
        }

        public async Task<IActionResult> Index()
        {
            var users = await _context.Users.ToListAsync();
            return View(users);
        }

        //GET:/Users/Edit/{id}
        [HttpGet]
        public async Task<IActionResult> Edit(string id)
        {
            if (string.IsNullOrEmpty(id))
                return NotFound();

            var user = await _context.Users.FindAsync(id);
            if (user == null)
                return NotFound();

            var vm = new UserViewModel
            {
                Id = user.Id,
                Name = user.Name,
                Surname = user.Surname,
                Email = user.Email,
                PhoneNumber = user.PhoneNumber,
                UserType = user.UserType
            };
            return View(vm);
        }

        //POST:/Users/Edit
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(UserViewModel vm)
        {
            if (!ModelState.IsValid)
                return View(vm);

            var user = await _context.Users.FindAsync(vm.Id);
            if (user == null)
                return NotFound();

            // Actualiza campos
            user.Name = vm.Name;
            user.Surname = vm.Surname;
            user.Email = vm.Email;
            user.UserName = vm.Email;         // si cambias email conviene actualizar UserName
            user.PhoneNumber = vm.PhoneNumber;
            user.UserType = vm.UserType;

            _context.Update(user);
            await _context.SaveChangesAsync();

            return RedirectToAction(nameof(Index));
        }

        //GET:/Users/Create
        public IActionResult Create()
        {
            return View();
        }

        //POST:/Users/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(RegisterViewModel model)
        {
            if (!ModelState.IsValid) return View(model);

            // Valida y crea el usuario
            var user = new User
            {
                Name = model.Name,
                Surname = model.Surname,
                Email = model.Email,
                PhoneNumber = model.PhoneNumber,
                UserName = model.Email,
                UserType = Enums.UserType.Usuario
            };
            var result = await _userHelper.AddUserAsync(user, model.Password);
            if (result.Succeeded)
                return RedirectToAction(nameof(Index));

            // Si hay errores, los mostramos
            foreach (var e in result.Errors)
                ModelState.AddModelError("", e.Description);
            return View(model);
        }

        private TokenAuth BuildToken(User user)
        {
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, user.Email!),
                new Claim(ClaimTypes.Role, user.UserType.ToString()),
                new Claim("Nombre", user.Name),
                new Claim("Apellido", user.Surname),
            };
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:SecretToken"]!));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expiration = DateTime.UtcNow.AddDays(15);
            var token = new JwtSecurityToken(
                issuer: null,
                audience: null,
                claims: claims,
                expires: expiration,
                signingCredentials: credentials
            );

            return new TokenAuth
            {
                Token = new JwtSecurityTokenHandler().WriteToken(token),
                Expiration = expiration
            };

        }

        

    }
}
