using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using ReAct_PME.Application;

namespace ReAct_PME.Api.Controllers
{
    [ApiController]
    [Route("api/[controller]")]

    public partial class AuthController : ControllerBase
    {
        private readonly IAuthService _authService;
        private readonly IConfiguration _config;

        public AuthController(IConfiguration config, IAuthService authService)
        {
            _authService = authService;
            _config = config;
        }

        [HttpPost("login")]
        [AllowAnonymous]
        public IActionResult Login([FromBody] LoginRequest request)
        {
            try
            {
                (bool isConnOK, var item, var lstRoles) = _authService.Connexion(request.Username, request.Password);

                if(isConnOK && item != null)
                {
                    string id = "";
                    string firstname = "";
                    string lastname = "";
                    string email = "";

                    firstname = item.FIRST_NAME;
                    lastname = item.LAST_NAME;
                    email = item.EMAIL;
                    id = item.ID_WORK_FORCE.ToString();

                    var roles = Array.Empty<string>();
                    if (lstRoles != null && lstRoles.Count > 0) 
                    { 
                        roles = lstRoles.ToArray();
                    }

                    var token = GenerateJwtToken(request.Username, firstname, lastname, email, id, roles);

                    return Ok(new LoginResponse { Token = token });
                }
                return Unauthorized();
            }

            catch (Exception ex)
            {
                Console.WriteLine($"Erreur lors du login : {ex.Message}");
                return StatusCode(500, new { error = ex.Message });
            }
        }


        // GET: api/Auth/info/5/True
        [HttpGet("info/{ID_USER}/{IsManager}")]
        [Authorize(Roles = "Admin,Manager,User")]
        public async Task<ActionResult> GetAllInfoById(Guid ID_USER, bool IsManager)
        {
            var info = await _authService.GetAllInfoById(ID_USER, IsManager);
            return Ok(info);
        }

        // GET: api/Auth/info/5/True
        [HttpGet("info/test/{ID_WORK_SORCE}/{IsManager}")]
        [Authorize(Roles = "Admin,Manager,User")]
        public async Task<ActionResult> GetAllInfoById_Test(Guid ID_WORK_SORCE, bool IsManager)
        {
            await Task.Delay(1);
            var info = "";// await _authService.GetAllInfoById(ID_WORK_SORCE, IsManager);
            return Ok(info);
        }

        private string GenerateJwtToken(string username, string firstname, string lastname, string email, string id, string[] roles)
        {
            var claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, username),
                new Claim("FirstName", firstname),
                new Claim("LastName", lastname),
                new Claim("Email", email),
                new Claim("ID", id),

                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            };

            foreach (var role in roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:SecretKey"]!));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: _config["Jwt:Issuer"],
                audience: _config["Jwt:Audience"],
                claims: claims,
                expires: DateTime.UtcNow.AddMinutes(int.Parse(_config["Jwt:ExpireMinutes"]!)),
                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        public class LoginRequest
        {
            public string Username { get; set; } = "";
            public string Password { get; set; } = "";
        }

    }

    public class LoginResponse
    {
        public string Token { get; set; } = string.Empty;
    }
}

