using Lada.Framework.Data.Domains.Categories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Categories;
using Ladaer.BackEnd.Infrastructures.Services.Categories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Ladaer.BackEnd.Controllers.Systems
{
    /// <summary>
    /// Controller xử lý các hoạt động liên quan đến menu.
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class MenuController : ControllerBase
    {
        private readonly IMenuService _menuService;

        /// <summary>
        /// Khởi tạo một instance mới của lớp <see cref="MenuController"/>.
        /// </summary>
        /// <param name="menuService">Dịch vụ xử lý menu.</param>
        public MenuController(IMenuService menuService)
        {
            _menuService = menuService;
        }

        #region Search

        /// <summary>
        /// Tìm kiếm các menu dựa trên các tham số được cung cấp.
        /// </summary>
        /// <param name="param">Các tham số tìm kiếm.</param>
        /// <returns>Kết quả tìm kiếm.</returns>
        [HttpPost("Search")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> Search([FromBody] SmartTableParam param)
        {
            var apps = await _menuService.Search(param);
            return Ok(apps);
        }

        #endregion

        #region GET menu for Apps and Roles

        /// <summary>
        /// Lấy danh sách menu cho ứng dụng và vai trò.
        /// </summary>
        /// <param name="appType">Loại ứng dụng.</param>
        /// <returns>Danh sách menu.</returns>
        [HttpGet("GetMenuList")]
        public async Task<IActionResult> GetMenuList(AppType appType)
        {
            var currentUser = User.GetCurrentUser();
            string roleName = "";
            if (currentUser.Roles != null && currentUser.Roles.Any())
            {
                roleName = currentUser.Roles.First();
            }
            var result = await _menuService.GetMenuList(currentUser.UserId, appType);
            return Ok(result);
        }

        #endregion

        #region Get Tree

        /// <summary>
        /// Lấy cây menu cho quản trị viên.
        /// </summary>
        /// <returns>Cây menu.</returns>
        [HttpGet("GetAdminTree")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> GetAdminTree()
        {
            var result = await _menuService.GetTree(AppType.Admin, "");
            return Ok(result);
        }

        /// <summary>
        /// Lấy cây menu dựa trên loại ứng dụng và từ khóa tìm kiếm.
        /// </summary>
        /// <param name="app">Loại ứng dụng.</param>
        /// <param name="keyword">Từ khóa tìm kiếm.</param>
        /// <returns>Cây menu.</returns>
        [HttpGet("GetTree")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> GetTree(AppType app, string keyword)
        {
            var result = await _menuService.GetTree(app, keyword);
            return Ok(result);
        }

        #endregion

        #region LOCK / UNLOCK

        /// <summary>
        /// Khóa một menu.
        /// </summary>
        /// <param name="model">Model chứa thông tin menu cần khóa.</param>
        /// <returns>Kết quả của hoạt động khóa.</returns>
        [HttpPut("Lock")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> Lock([FromBody] MenuStatusModel model)
        {
            var currentUser = User.GetCurrentUser();
            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            var result = await _menuService.UpdateStatus(model, MenuStatus.InActive);
            return Ok(result);
        }

        /// <summary>
        /// Mở khóa một menu.
        /// </summary>
        /// <param name="model">Model chứa thông tin menu cần mở khóa.</param>
        /// <returns>Kết quả của hoạt động mở khóa.</returns>
        [HttpPut("UnLock")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> UnLock([FromBody] MenuStatusModel model)
        {
            var currentUser = User.GetCurrentUser();
            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            var result = await _menuService.UpdateStatus(model, MenuStatus.Active);
            return Ok(result);
        }

        #endregion

        #region CRUD

        /// <summary>
        /// Tạo hoặc cập nhật thông tin menu.
        /// </summary>
        /// <param name="menuModel">Model chứa thông tin menu.</param>
        /// <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        [HttpPost("CreateOrUpdate")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> CreateOrUpdate([FromBody] MenuModel menuModel)
        {
            var result = new MenuResult();
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var currentUser = User.GetCurrentUser();
            menuModel.UpdatedBy = currentUser.UserId;
            menuModel.UpdatedByUserName = currentUser.UserName;

            if (menuModel.UpdatedBy <= 0 || string.IsNullOrEmpty(menuModel.UpdatedByUserName))
            {
                result.Result = Lada.Framework.DTO.Result.Failed;
                result.Message = $"Kh�ng x�c d?nh du?c ngu?i d�ng {currentUser.UserId} - {currentUser.UserName} ";

                return Ok(result);
            }
            menuModel.AppType = AppType.Admin;
            result = await _menuService.CreateOrUpdate(menuModel);
            return Ok(result);
        }

        /// <summary>
        /// Lấy thông tin chi tiết của một menu dựa trên ID.
        /// </summary>
        /// <param name="id">ID của menu.</param>
        /// <returns>Thông tin chi tiết của menu.</returns>
        [HttpGet("GetById")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> GetById(int id)
        {
            var result = await _menuService.GetById(id);
            return Ok(result);
        }

        /// <summary>
        /// Xóa một menu dựa trên ID.
        /// </summary>
        /// <param name="id">ID của menu.</param>
        /// <returns>Kết quả của hoạt động xóa.</returns>
        [HttpDelete("Delete")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> Delete(int id)
        {
            var result = await _menuService.Delete(id);
            return Ok(result);
        }

        #endregion

        #region Others

        /// <summary>
        /// Lấy danh sách các ứng dụng.
        /// </summary>
        /// <returns>Danh sách các ứng dụng.</returns>
        [HttpGet("GetAppList")]
        [Authorize(Roles = "Founder")]
        public async Task<IActionResult> GetAppList()
        {
            var appList = new List<BaseCategoryItem>();
            appList.Add(new BaseCategoryItem()
            {
                Id = (int)AppType.Admin,
                Name = AppType.Admin.GetDescription()
            });
            appList.Add(new BaseCategoryItem()
            {
                Id = (int)AppType.Learning,
                Name = AppType.Learning.GetDescription()
            });
            appList.Add(new BaseCategoryItem()
            {
                Id = (int)AppType.User,
                Name = AppType.User.GetDescription()
            });
            return Ok(appList);
        }

        #endregion
    }
}
