using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Modules.User.Application;
using Modules.User.Application.Commands;
using Modules.User.Application.Queries;
using Modules.User.WebApi.Models;
using System.Net;

namespace Modules.User.WebApi.Controllers;

[ApiController]
[Route("[controller]")]
[ProducesResponseType(400, StatusCode = 400, Type = typeof(ProblemDetails))]
[ProducesResponseType(401, StatusCode = 401, Type = typeof(UnauthorizedResult))]
[Authorize]
public class AccountController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly UserContext _userContext;
    private readonly ILogger<AccountController> _logger;


    public AccountController(UserContext userContext, IMediator mediator, ILogger<AccountController> logger)
    {
        _userContext = userContext;
        _mediator = mediator;
        _logger = logger;
    }

    [HttpGet("Sessions")]

    [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(List<Session>))]
    public async Task<IActionResult> GetSessions()
    {
        var user = await _userContext.GetUserInfo();
        if (user?.AccountId == null) return Ok(new List<Session>());
        var sessions = await _mediator.Send(new GetAccountSessionsQuery { AccountId = user.AccountId.Value });
        return Ok(sessions.Select(q => new Session
        {
            Id = q.Id,
            Country = q.ClientInfo.Location.Country,
            Region = q.ClientInfo.Location.Region,
            //Latitude = q.ClientInfo.Location.Latitude,
            //Longitude = q.ClientInfo.Location.Longutude,
            UserAgent = q.ClientInfo.UserAgent,
            ExpiredDate = q.ExpiredDate,
        }));
    }

    [HttpPost("Sessions/Delete")]

    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<IActionResult> DeleteSession(DeleteSessionModel model)
    {
        var user = await _userContext.GetUserInfo();
        if (user?.AccountId == null) return Unauthorized();
        await _mediator.Send(new DeleteSessionCommand
        {
            AccountId = user.AccountId.Value,
            SessionId = model.SessionId,
        });
        return Ok();
    }

    [HttpPost("Sessions/DeleteCurrent")]
    public async Task<IActionResult> DeleteCurrentSession()
    {
        var user = await _userContext.GetUserInfo();
        if (user?.AccountId == null) return Ok(new List<Session>());
        return Ok(await _mediator.Send(new DeleteCurrentSessionCommand()));
    }

    [HttpPost("Sessions/DeleteAll")]
    public async Task<IActionResult> DeleteAllSessions()
    {
        var user = await _userContext.GetUserInfo();
        if (user?.AccountId == null) return Ok(new List<Session>());
        return Ok(await _mediator.Send(new DeleteAllSessionsCommand
        {
            AccountId = user.AccountId.Value,
        }));
    }
    
    [HttpPost("Login")]
    [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(AuthenticationResultModel))]
    [AllowAnonymous]
    public async Task<IActionResult> Login(LoginModel model)
    {
        var loginResult = await _mediator.Send(new LoginCommand
            {
                Email = model.Login,
                Password = model.Password,
                IsAdmin = false,

                Ip = model.Ip,

                Response = Response,
                //CookiePath = "Account/Refresh",
                CookiePath = "/",
            });
        return Ok(new AuthenticationResultModel
        {
            AccessToken = loginResult.AccessToken,
            SessionExpireDate = loginResult.SessionExpireDate.ToString("O"),
        });
    }
    
    [HttpPost("Refresh")]
    [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(AuthenticationResultModel))]
    [AllowAnonymous]
    public async Task<IActionResult> Refresh(RefreshModel model)
    {
        var refreshResult = await _mediator.Send(new RefreshTokensCommand
            {
                Ip = model.Ip,

                Response = Response,
                //CookiePath = "Account/Refresh",
                CookiePath = "/",
        });
        //if (tokens != null)
        //{
        //    return Ok(tokens.Value.AccessToken);
        //}
        //else
        //{
        //    return Unauthorized();
        //}
        return refreshResult == null ? Unauthorized() : Ok(new AuthenticationResultModel
        {
            AccessToken = refreshResult.AccessToken,
            SessionExpireDate = refreshResult.SessionExpireDate.ToString("O"),
        });

        //return tokens == null ? Unauthorized() : Ok(new TokensModel
        //{
        //    AccessToken = tokens.Value.AccessToken,
        //    RefreshToken = tokens.Value.RefreshToken,
        //});
    }


    [HttpPost("Register")]
    [AllowAnonymous]
    public async Task Register(RegisterModel model)
    {
        var token = await _mediator.Send(new CreateUserCommand
            {
                Nickname = model.Nickname,
                Email = model.Login,
                Password = model.Password,
                //IsAdmin = false,
            });
    }
}
