namespace MyOffice.Web.Controllers;

using System.Security.Claims;
using Data.Repositories.Users;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OpenIddict.Server.AspNetCore;
using OpenIddict.Validation.AspNetCore;
using static OpenIddict.Abstractions.OpenIddictConstants;

[ApiController]
public sealed class AuthorizationController : ControllerBase
{
	private readonly IUserRepository _userRepository;

	public AuthorizationController(IUserRepository userRepository)
	{
		_userRepository = userRepository;
	}

	[Authorize(AuthenticationSchemes = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)]
	[HttpGet("~/connect/authorize")]
	[HttpPost("~/connect/authorize")]
	public async Task<IActionResult> Authorize()
	{
		var result = await HttpContext.AuthenticateAsync(
			OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
		if (!result.Succeeded)
		{
			return Forbid(
				authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
				properties: new AuthenticationProperties(new Dictionary<string, string?>
				{
					[OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired,
					[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] =
						"The user is not authenticated."
				}));
		}

		return SignIn(result.Principal!, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
	}

	[Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
	[HttpGet("~/connect/userinfo")]
	[HttpPost("~/connect/userinfo")]
	[Produces("application/json")]
	public async Task<IActionResult> Userinfo()
	{
		var userIdValue = User.FindFirstValue(Claims.Subject);
		if (!Guid.TryParse(userIdValue, out var userId))
			return Challenge(authenticationSchemes: OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);

		var user = await _userRepository.GetUserAsync(userId);
		if (user is null)
			return Challenge(authenticationSchemes: OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);

		return Ok(new
		{
			sub = userIdValue,
			id = userIdValue,
			email = user.Email,
			name = user.FullName ?? user.UserName,
			firstName = user.FirstName,
			lastName = user.LastName,
			fullName = user.FullName,
			phone = user.Phone
		});
	}
}
