using AlsimHolidaysAPI.Models;
using Azure.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace AlsimHolidaysAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private  IConfiguration _configuration;
        private readonly ApplicationDbContext _context; // Injected database context


        public AuthController(IConfiguration configuration, ApplicationDbContext context)
        {
            _configuration = configuration;
            _context = context;
        }


        





        [AllowAnonymous]
        [HttpGet("check-auth")]
        [Route("check-auth")]
        public IActionResult CheckAuth()
        {
            // Check if the authToken cookie exists
            if (Request.Cookies.TryGetValue("authToken", out var token))
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes(_configuration["Jwt:Key"]);

                try
                {
                    // Validate the token
                    tokenHandler.ValidateToken(token, new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = _configuration["Jwt:Issuer"],
                        ValidAudience = _configuration["Jwt:Audience"],
                        IssuerSigningKey = new SymmetricSecurityKey(key),
                        ValidateLifetime = true
                    }, out SecurityToken validatedToken);


                    var jwtToken = validatedToken as JwtSecurityToken;

                    // Token is valid
                    //return Ok(new { authenticated = true });

                    return Ok(new
                    {
                        authenticated = true, // Indicate that the user is authenticated
                        token = token // Return the original token from the cookie
                    });

                }
                catch
                {
                    // Token is invalid or expired
                    return Unauthorized(new { authenticated = false });
                }
            }

            // No authToken found
            return Unauthorized(new { authenticated = false });
        }





        [HttpPost("logout")]
        [Route("logout")]
        public IActionResult Logout()
        {
            // Clear the cookie by setting the expiration date to a past date
            var cookieOptions = new CookieOptions
            {
                HttpOnly = true,
                Secure = true,
                SameSite = SameSiteMode.Strict,
                Expires = DateTime.UtcNow.AddDays(-1) // Expire immediately
            };

            Response.Cookies.Append("authToken", string.Empty, cookieOptions);

            return Ok(new { message = "Logout successful" });
        }





        [AllowAnonymous]
        [HttpPost("login")]
        [Route("login")]
        public IActionResult Login([FromBody] UserInfo _userData)
        {


            if (_userData == null || string.IsNullOrWhiteSpace(_userData.Email))
            {
                return BadRequest("User data cannot be null and email cannot be empty.");
            }


            try
            {
                var user = _context.UserInfos.FirstOrDefault(u => u.Email == _userData.Email);

                if (user == null)
                {
                    return Unauthorized("Invalid credentials");
                }


                // if (user == null || user.Password != _userData.Password)
                // {
                //    return Unauthorized("Invalid credentials");
                //}


                // Verify the password using the PasswordHasher

                var passwordHasher = new PasswordHasher();
                var verificationResult = passwordHasher.VerifyHashedPassword(null, user.Password, _userData.Password);

                //If the password doesn't match
                if (verificationResult != PasswordVerificationResult.Success)
                {
                    return Unauthorized("Invalid credentials");
                }


  

                // Generate JWT token
                var token = GenerateJwtToken(_userData.Email, user);

                // Set JWT in an HttpOnly cookie
                var cookieOptions = new CookieOptions
                {
                    HttpOnly = true,
                    Secure = true,
                    SameSite = SameSiteMode.None,
                    Expires = DateTime.UtcNow.AddHours(10)
                    //Expires = DateTime.UtcNow.AddMinutes(1)
                };
                Response.Cookies.Append("authToken", token, cookieOptions);

                return Ok(new { token });

            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error occurred: {ex.Message}");
                return StatusCode(500, "Internal server error!!" + ex.Message);
            }

        }



        private string GenerateJwtToken(string email,UserInfo userstuff)
        {
            var key = Encoding.ASCII.GetBytes(_configuration["Jwt:Key"]);
            var tokenHandler = new JwtSecurityTokenHandler();


            var claims = new List
            {
                new Claim(ClaimTypes.Email, email),
                new Claim("DisplayName",userstuff.DisplayName),
                new Claim("UserID",userstuff.UserId.ToString()),
                new Claim("IsAdmin",userstuff.IsAdmin.ToString()),
                new Claim("IsApprover",userstuff.IsApprover.ToString())
            };

            if (userstuff.IsAdmin == 1)
            {
                claims.Add(new Claim(ClaimTypes.Role, "Admin"));
            }
            if (userstuff.IsApprover == 1)
            {
                claims.Add(new Claim(ClaimTypes.Role, "Approver"));
            }




            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.UtcNow.AddHours(10),
               // Expires = DateTime.UtcNow.AddMinutes(1),
                Issuer = _configuration["Jwt:Issuer"],
                Audience = _configuration["Jwt:Audience"],
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)                
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);

   

            return tokenString;
        }
    }






}