using BusinessLogic.BusinessLogic;
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.Exceptions;
using Contracts.SearchModels;
using Microsoft.AspNetCore.Mvc;

namespace RestAPI.Controllers
{
	[Route("[controller]/[action]")]
	[ApiController]
	public class UserController
	{
		private readonly ILogger _logger;
		private readonly IUserLogic _userLogic;

		public UserController(ILogger<UserController> logger, IUserLogic userLogic)
		{
			_userLogic = userLogic;
			_logger = logger;
		}

		[HttpPost]
		public IResult Login([FromBody] UserBindingModel model)
		{
			try
			{
				var res = _userLogic.Login(model);
				return Results.Ok(res);
			}
			catch (ElementNotFoundException ex)
			{
				_logger.LogInformation(ex, "User not found");
				return Results.NoContent();
			}
			catch (AccountException ex)
			{
				_logger.LogWarning(ex, "Wrong login data");
				return Results.BadRequest(ex.Message);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Error get user");
				return Results.Problem(ex.Message);
			}
		}

		[HttpPost]
		public IResult Registration([FromBody] UserBindingModel model)
		{
			try
			{
				var res = _userLogic.Login(model);
				return Results.Ok(res);
			}
			catch (AccountException ex)
			{
				_logger.LogWarning(ex, "Wrong registration data");
				return Results.BadRequest(ex.Message);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Error create user");
				return Results.Problem(ex.Message);
			}
		}

		[HttpGet]
		public IResult Get([FromQuery] UserSearchModel model)
		{
			try
			{
				var res = _userLogic.ReadElement(model);
				return Results.Ok(res);
			}
			catch (ElementNotFoundException ex)
			{
				_logger.LogInformation(ex, "User not found");
				return Results.NoContent();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Error get user");
				return Results.Problem(ex.Message);
			}
		}

		[HttpPatch]
		public IResult Update([FromBody] UserBindingModel model)
		{
			try
			{
				var res = _userLogic.Update(model);
				return Results.Ok(res);
			}
			catch (AccountException ex)
			{
				_logger.LogWarning(ex, "Wrong update data");
				return Results.BadRequest(ex.Message);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Error update user");
				return Results.Problem(ex.Message);
			}
		}

		[HttpDelete]
		public IResult Delete(Guid id)
		{
			try
			{
				var res = _userLogic.Delete(new() { Id = id });
				return Results.Ok(res);
			}
			catch (ElementNotFoundException ex)
			{
				_logger.LogInformation(ex, "User not found");
				return Results.NoContent();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Error delete user");
				return Results.Problem(ex.Message);
			}
		}
	}
}