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 UserController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly UserContext _userContext;
    private readonly ILogger<AccountController> _logger;


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

    [HttpGet]
    [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(UserInfo))]
    public async Task<IActionResult> GetUser()
    {
        var user = await _userContext.GetUserInfo();
        if (user.Id == null) return NotFound();
        return Ok(user == null ? null : new UserInfo
        {
            Id = user.Id,
            AccountId = user.AccountId,
            SessionId = user.SessionId,
            NickName = user.NickName,
            FirstName = user.FirstName,
            Patronymic = user.Patronymic,
            LastName = user.LastName,
            BirthDate = user.BirthDate,
            LanguageId = user.LanguageId,
            Email = user.Email,
            IsAuthenticated = user.IsAuthenticated,
        });
    }

    [HttpGet("Avatar")]
    [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(FileStreamResult))]
    public async Task<IActionResult> GetAvatar()
    {
        var avatar = await _mediator.Send(new GetUserAvatarQuery());
        if (avatar == null)
        {
            return NotFound();
        }
        else
        {
            return new FileStreamResult(avatar.Data, avatar.ContentType);
        }
    }

    [HttpPost("SetAvatar")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<IActionResult> SetAvatar(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("File is not selected or empty.");
        //using var ms = new MemoryStream();
        //await file.CopyToAsync(ms);
        //ms.Seek(0, SeekOrigin.Begin);
        using var stream = file.OpenReadStream();
        await _mediator.Send(new SetUserAvatarCommand
        {
            ContentType = file.ContentType,
            Extension = Path.GetExtension(file.FileName),
            Data = stream,
            //Data = ms,
        });
        return Ok();
    }

    [HttpGet("DeleteAvatar")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<IActionResult> DeleteAvatar()
    {
        await _mediator.Send(new DeleteUserAvatarCommand());
        return Ok();
    }

    /*
    public string? NickName { get; set; } = default!;
    public string? FirstName { get; set; }
    public string? Patronymic { get; set; }
    public string? LastName { get; set; }
    public Guid? LanguageId { get; set; }
    */


    [HttpPost("SetUserInformation")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<IActionResult> SetUserInformation(UserInformationEditModel model)
    {
        await _mediator.Send(new SetUserInformationCommand
        {
            FirstName = model.FirstName,
            Patronymic = model.Patronymic,
            LastName = model.LastName,
        });
        return Ok();
    }

    [HttpPost("SetBirthDate")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<IActionResult> SetBirthDate(BirthDateEditModel model)
    {
        await _mediator.Send(new SetUserBirthDateCommand
        {
            BirthDate = model.BirthDate,
        });
        return Ok();
    }


    [HttpPost("SetLanguage")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<IActionResult> SetLanguage(LanguageEditModel model)
    {
        await _mediator.Send(new SetUserLanguageCommand
        {
            LanguageId = model.LanguageId,
        });
        return Ok();
    }
}
