namespace MyOffice.Web.Controllers;

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

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class SettingsItemController : BaseApiController
{
	private ILogger<SettingsItemController> _logger;

	private ItemService _itemService;

	public SettingsItemController(
		ILogger<SettingsItemController> logger,
		ItemService itemService
	)
	{
		_itemService = itemService;
		_logger = logger;
	}

	[HttpGet("~/api/settings/item-categories")]
	public object ItemsCategories()
	{
		var list = _itemService.GetAllCategories(UserId);

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

	[HttpPost("~/api/settings/item-categories")]
	public object ItemCategoriesAdd(ItemCategoryViewModel request)
	{
		var exec = _itemService.CategoryAdd(UserId, request.FromModel());

		switch (exec.Status)
		{
			case GeneralExecStatus.success:
				return exec.Result!.ToModel();

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

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

	[HttpPut("~/api/settings/item-categories/{id}")]
	public object ItemCategoriesEdit(string id, ItemCategoryViewModel request)
	{
		var exec = _itemService.CategoryUpdate(UserId, id.AsGuid(), request.FromModel());

		switch (exec.Status)
		{
			case GeneralExecStatus.success:
				return exec.Result!.ToModel();

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

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

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

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

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

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

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

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

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