using Google.Apis.Auth;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace DiunaBI.API.Controllers;

[ApiController]
[Route("api/[controller]")]
// [Authorize]
public class AuthController : Controller
{
    private readonly AppDbContext _db;
    private readonly IConfiguration _configuration;
    public AuthController(
        AppDbContext db, IConfiguration configuration)
    { _db = db; _configuration = configuration; }

    [HttpPost]
    [Route("apiToken")]
    public async Task<IActionResult> ApiToken([FromBody] string credential)
    {
        var settings = new GoogleJsonWebSignature.ValidationSettings
        {
            Audience = new List<string> { _configuration.GetValue<string>("GoogleClientId")! }
        };
        var payload = await GoogleJsonWebSignature.ValidateAsync(credential, settings);
        var user = _db.Users.AsNoTracking().FirstOrDefault(x => x.Email == payload.Email);
        return user != null ? (IActionResult)Ok(JwtGenerator(user)) : Unauthorized();
    }

    private dynamic JwtGenerator(User user)
    {
        var key = Encoding.ASCII.GetBytes(_configuration.GetValue<string>("Secret")!);
        var expirationTime = DateTime.UtcNow.AddMinutes(5);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new[]
            {
                new Claim("Id", Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
                new Claim(JwtRegisteredClaimNames.Jti,
                    Guid.NewGuid().ToString())
            }),
            Expires = expirationTime,
            SigningCredentials = new SigningCredentials
            (new SymmetricSecurityKey(key),
                SecurityAlgorithms.HmacSha512Signature)
        };
        var tokenHandler = new JwtSecurityTokenHandler();
        var token = tokenHandler.CreateToken(tokenDescriptor);
        var stringToken = tokenHandler.WriteToken(token);
        return new { token = stringToken, id = user.Id, expirationTime };
    }
}