using API.Helpers;
using BusinessLayer.IRepository;
using DataAccess.DTOs;
using DataAccess.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace API.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private IUserRepository _userRepository;
        private readonly AppSettings _appSettings;

        public UserController(IUserRepository userRepository, IOptionsMonitor<AppSettings> optionsMonitor)
        {
            _userRepository = userRepository;
            _appSettings = optionsMonitor.CurrentValue;
        }

        [HttpGet]
        [EnableQuery]
        [Authorize(AuthenticationSchemes = "Bearer")]
        public IActionResult Get()
        {
           return Ok(_userRepository.GetAll());
        }

        [HttpGet("Login")]
        public IActionResult Get(string email, string pwd) 
        { 
            var user = _userRepository.Get(email, pwd);
            if (user == null)
            {
                return Ok(new RespondMessage
                {
                    Success = false,
                    Message = "Invalid Email or Password"
                });
            }
            else
            {
                return Ok(new RespondMessage
                {
                    Success = true,
                    Message = "Authenticate success",
                    Data = GenerateToken(user)
                });
            }
        }

        [HttpPost]
        public void Post([FromBody] UserDTO userDTO)
        {
            _userRepository.Add(userDTO);
        }

        [HttpPut]
        public void Put([FromBody] UserDTO userDTO)
        { 
            _userRepository.Update(userDTO);
        }

        [HttpDelete]
        [Authorize(AuthenticationSchemes = "Bearer", Roles = "0")]
        public void Delete([FromBody] UserDTO userDTO)
        {
            _userRepository.Delete(userDTO);
        }

        [HttpGet("{token}")]
        public IActionResult Validate(string token)
        {
            try
            {
                var jwtTokenHandler = new JwtSecurityTokenHandler();
                var secretKeyBytes = Encoding.UTF8.GetBytes(_appSettings.SecretKey);

                var validationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(secretKeyBytes),
                    ValidateIssuer = false, // You can set this to true if you have an issuer
                    ValidateAudience = false // You can set this to true if you have a specific audience
                };

                // Try to validate the token
                SecurityToken validatedToken;
                var principal = jwtTokenHandler.ValidateToken(token, validationParameters, out validatedToken);

                return Ok("Valid token");
            }
            catch (Exception)
            {
                // Token validation failed
                return BadRequest("Invalid token");
            }
        }

        private string GenerateToken(UserDTO user)
        {
            var jwtTokenHandle = new JwtSecurityTokenHandler();

            var secretKeyBytes = Encoding.UTF8.GetBytes(_appSettings.SecretKey);
            var tokenDes = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Email, user.Email),

                    //role
                    new Claim(ClaimTypes.Role, user.Role.ToString()),
                    new Claim("TokenId", Guid.NewGuid().ToString())
                }),
                Expires = DateTime.UtcNow.AddMinutes(30),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secretKeyBytes), SecurityAlgorithms.HmacSha256Signature)

            };

            var token = jwtTokenHandle.CreateToken(tokenDes);
            return jwtTokenHandle.WriteToken(token);
        }
    }
}
