namespace MyOffice.Web.Controllers;

using Data.Repositories.Account;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Models.Motion;
using MyOffice.Core.Extensions;
using MyOffice.Core;
using MyOffice.Data.Repositories.Motion;
using MyOffice.Services.Account;
using MyOffice.Services.Account.Domain;
using Services.Motion;
using MyOffice.Data.Models.Motions;
using Services.Motion.Domain;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class SettingsMotionController : BaseApiController
{
	private MotionService _motionService;

	public SettingsMotionController(
		MotionService motionService
	)
	{
		_motionService = motionService;
	}

	[HttpGet("~/api/settings/motion-categories")]
	public object MotionCategories()
	{
		var list = _motionService.GetAllCategories(UserId);

		return list.Select(x => x.ToModel()).OrderByDescending(x => x.SortOrder);
	}

	[HttpPost("~/api/settings/motion-categories")]
	public object MotionCategoriesAdd(MotionCategoryViewModel request)
	{
		var exec = _motionService.CategoryAdd(UserId, new MotionCategory { Name = request.Name! });
		switch (exec.Status)
		{
			case GeneralExecStatus.success:
				return exec.Result!;

			case GeneralExecStatus.failure:
			case GeneralExecStatus.not_found:
				return ProblemBadRequest("Adding motion category failed.");

			default:
				throw new NotSupportedException(exec.Status.ToString());
		}
	}

	[HttpPut("~/api/settings/motion-categories/{id}")]
	public object MotionCategoriesEdit(string id, MotionCategoryViewModel request)
	{
		var exec = _motionService.CategoryUpdate(UserId, id.AsGuid(), new MotionCategory { Name = request.Name! });
		switch (exec.Status)
		{
			case GeneralExecStatus.success:
				return exec.Result!;

			case GeneralExecStatus.failure:
			case GeneralExecStatus.not_found:
				return ProblemBadRequest("Update account category failed.");

			default:
				throw new NotSupportedException(exec.Status.ToString());
		}
	}

	[HttpDelete("~/api/settings/motion-categories/{id}")]
	public object MotionCategoriesDelete(string id)
	{
		var exec = _motionService.CategoryRemove(UserId, id.AsGuid());
		switch (exec.Status)
		{
			case MotionCategoryRemoveResult.success:
				return exec.Result!;

			case MotionCategoryRemoveResult.failure:
				return ProblemBadRequest("Remove motion category failed.");
			case MotionCategoryRemoveResult.not_found:
				return ProblemBadRequest("Account motion not found.");
			case MotionCategoryRemoveResult.accounts_exists:
				return ProblemBadRequest("Account motion have accounts.");

			default:
				throw new NotSupportedException(exec.Status.ToString());
		}
	}

	[HttpGet("~/api/settings/motions")]
	public object Motions(string? category)
	{
		var list = category.IsMissing()
			? _motionService.GetAll(UserId)
			: _motionService.GetByCategory(UserId, category.AsGuid());

		return list.Select(x => x.ToModel());
	}

	[HttpPut("~/api/settings/motions/{id}")]
	public object Motions(string id, MotionEditModel request)
	{
		var exec = _motionService.Update(UserId, id.AsGuid(), request.Category.AsGuid());
		switch (exec.Status)
		{
			case GeneralExecStatus.not_found:
				return ProblemBadRequest("Motion not found.");
			case GeneralExecStatus.failure:
				return ProblemBadRequest("Motion update failed.");
			case GeneralExecStatus.success:
				return Ok(exec.Result!.ToModel());

			default:
				throw new NotSupportedException(exec.Status.ToString());
		}
	}
}