using VentaUniformesApplication.Exceptions;
using VentaUniformesApplication.Features;
using VentaUniformesApplication.Persistencia.user.commands.CreateUser;
using VentaUniformesApplication.Persistencia.user.commands.DeleteUser;
using VentaUniformesApplication.Persistencia.user.commands.UpdateUser;
using VentaUniformesApplication.Persistencia.user.Queries.GetAllUser;
using VentaUniformesApplication.Persistencia.user.Queries.GetUserById;
using VentaUniformesApplication.Persistencia.user.Queries.GetUserByPassAndName;
using FluentValidation;
using Microsoft.AspNetCore.Authorization;


//using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
//using System.Web.Http;

namespace VentaUniformesapi.Controllers
{
    [Authorize]
    [Route("api/v1/User")]
    [ApiController]
    [TypeFilter(typeof(ExceptionManager))]//captura errores de todo el controller 
    public class UserController : ControllerBase
    {
        /*public UserController()
        {

        }*/
        [AllowAnonymous]//no securizada
        [HttpGet("test")]
        public async Task<IActionResult> test()
        {
            //var n=int.Parse("h");
            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, "{}", "Ejecucion exitosa"));
        }
        [HttpGet]
        public async Task<IActionResult> GetAll(
            [FromServices] IGetAllUserQuery service
            )
        {
            var data = await service.Execute();
            if(data==null|| data.Count<=0)
                return StatusCode(StatusCodes.Status404NotFound, ResponseApiService.Response(StatusCodes.Status404NotFound, data));

            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, data));

        }
        [HttpGet("{userId}")]
        public async Task<IActionResult> Getuser(
            int userId,
            [FromServices] IGetUserByIdQuery service
            )
           {
            if (userId <= 0)
            {
                return StatusCode(StatusCodes.Status400BadRequest, ResponseApiService.Response(StatusCodes.Status400BadRequest));
            }
            var data = await service.Execute(userId);
            if (data == null)
                return StatusCode(StatusCodes.Status404NotFound, ResponseApiService.Response(StatusCodes.Status404NotFound, data));

            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, data));

        }
        [HttpGet("{userName}/{password}")]
        public async Task<IActionResult> Getuser(
           string userName,
           string password,

            [FromServices] IGetUserByPassAndNameQuery service,
            [FromServices] IValidator<(string, string)> validador
            )
        {
            var validacion = await validador.ValidateAsync(( userName, password));
            if (!validacion.IsValid)
                return StatusCode(StatusCodes.Status400BadRequest, ResponseApiService.Response(StatusCodes.Status400BadRequest, validacion.Errors));
            /*
            if (userName==null || userName.Length <= 0|| password == null || password.Length <= 0)
            {
                return StatusCode(StatusCodes.Status400BadRequest, ResponseApiService.Response(StatusCodes.Status400BadRequest));
            }*/
            var data = await service.Execute(password,userName);
            if (data == null)
                return StatusCode(StatusCodes.Status404NotFound, ResponseApiService.Response(StatusCodes.Status404NotFound, data));

            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, data));

        }


        [HttpGet("login")]//se pasa parametros con ?userName=nombre&password=pass
        public async Task<IActionResult> Getuser2(
            [FromQuery] string userName,
            [FromQuery] string password,

            [FromServices] IGetUserByPassAndNameQuery service,
            [FromServices] IValidator<(string, string)> validador
            )
        {
            var validacion = await validador.ValidateAsync((userName, password));
            if (!validacion.IsValid)
                return StatusCode(StatusCodes.Status400BadRequest, ResponseApiService.Response(StatusCodes.Status400BadRequest, validacion.Errors));

            var data = await service.Execute(password, userName);
            if (data == null)
                return StatusCode(StatusCodes.Status404NotFound, ResponseApiService.Response(StatusCodes.Status404NotFound, data));

            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, data));

        }
        [HttpPost]
        public async Task<IActionResult> Create(
            [FromBody] CreateUserModel model,
            [FromServices] IcreateUserCommand createUserCommand,
            [FromServices]  IValidator<CreateUserModel> validador
            )
        {
            var validacion = await validador.ValidateAsync(model);
            if(!validacion.IsValid)
                return StatusCode(StatusCodes.Status400BadRequest, ResponseApiService.Response(StatusCodes.Status400BadRequest, validacion.Errors));

            var data = await createUserCommand.Execute(model);


            //var n=int.Parse("h");
            return StatusCode(StatusCodes.Status201Created, ResponseApiService.Response(StatusCodes.Status201Created, data));
        }

        [HttpPut]
        public async Task<IActionResult> Update(
            [FromBody] UpdateUserModel model,
            [FromServices] IupdateUserCommand updateUserCommand,
            [FromServices] IValidator<UpdateUserModel> validador
            )
        {
            var validacion = await validador.ValidateAsync(model);
            if (!validacion.IsValid)
                return StatusCode(StatusCodes.Status400BadRequest, ResponseApiService.Response(StatusCodes.Status400BadRequest, validacion.Errors));

            var data = await updateUserCommand.Execute(model);


            //var n=int.Parse("h");
            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, data));
        }

        //falta hacerlo en servicio-------------------------
        [HttpPatch]
        public async Task<IActionResult> UpdateParcial(
            [FromBody] UpdateUserModel model,
            [FromServices] IupdateUserCommand updateUserCommand
            )
        {
            var data = await updateUserCommand.Execute(model);


            //var n=int.Parse("h");
            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, data));
        }


        [HttpDelete("{userId}")]//parametro por url
        public async Task<IActionResult> borrar(
         int userId,
        [FromServices] IDeleteUserCommand servicio
        )
        {
            //validacion---------------------
            if(userId<=0)
            {
                return StatusCode(StatusCodes.Status400BadRequest, ResponseApiService.Response(StatusCodes.Status400BadRequest));
            }
            var data = await servicio.Execute(userId);
            if(!data)
                return StatusCode(StatusCodes.Status404NotFound, ResponseApiService.Response(StatusCodes.Status404NotFound, data));
            //var n=int.Parse("h");
            return StatusCode(StatusCodes.Status200OK, ResponseApiService.Response(StatusCodes.Status200OK, data));
        }
    }
}
