using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using OpenIddict.Abstractions;
using Pepegov.Identity.BL.Services.Interfaces;
using Pepegov.Identity.DAL.Domain;
using Pepegov.Identity.DAL.Models.Identity;
using Pepegov.MicroserviceFramework.Infrastructure.Helpers;
using Serilog;

namespace Pepegov.Identity.PL.Pages.Connect;

public class LoginModel : PageModel
{
    private readonly IAccountService _accountService;
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly UserManager<ApplicationUser> _userManager;

    public LoginModel(
        IAccountService accountService,
        SignInManager<ApplicationUser> signInManager,
        UserManager<ApplicationUser> userManager)
    {
        _accountService = accountService;
        _signInManager = signInManager;
        _userManager = userManager;
    }

    [BindProperty(SupportsGet = true)]
    public string ReturnUrl { get; set; }

    [BindProperty]
    public LoginViewModel Input { get; set; }

    public List<string> CurrentUserRoles { get; set; } = new List<string>();

    public void OnGet()
    {
        if (HttpContext.User.Identity is not null)
        {
            CurrentUserRoles = ClaimsHelper.GetValues<string>((ClaimsIdentity)HttpContext.User.Identity, OpenIddictConstants.Claims.Role);
        }
        
        Input = new LoginViewModel
        {
            ReturnUrl = ReturnUrl
        };
    }

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        var user = await _userManager.FindByNameAsync(Input.UserName);
        if (user is null)
        {
            ModelState.AddModelError("UserName", "User not found");
            return Page();
        }

        var signInResult = await _signInManager.PasswordSignInAsync(user, Input.Password, true, false);
        if (signInResult.Succeeded)
        {
            var principal = await _accountService.GetPrincipalByIdAsync(user.Id.ToString());
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
                
            if (Url.IsLocalUrl(ReturnUrl))
            {
                return Redirect(ReturnUrl);
            }
            return RedirectToPage("/swagger");
        }

        ModelState.AddModelError("UserName", "Invalid username or password");
        return Page();
    }
}