
using AntDesign;
using Atomx.Admin.Client.Models;
using Atomx.Admin.Client.Validators;
using Atomx.Admin.Services;
using Atomx.Common.Constant;
using Atomx.Common.Entities;
using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using Atomx.Utils.Json;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;

namespace Atomx.Admin.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class RoleController : ControllerBase
    {
        readonly ILogger<RoleController> _logger;
        readonly IdentityService _identityService;
        readonly IIdCreatorService _idCreator;
        readonly IMapper _mapper;
        readonly DataContext _dbContext;
        readonly ICacheService _cacheService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="identityService"></param>
        /// <param name="idCreator"></param>
        /// <param name="mapper"></param>
        /// <param name="userService"></param>
        public RoleController(ILogger<RoleController> logger, IdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext, ICacheService cacheService)
        {
            _logger = logger;
            _identityService = identityService;
            _idCreator = idCreator;
            _mapper = mapper;
            _dbContext = dataContext;
            _cacheService = cacheService;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="search"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [HttpPost("search")]
        public IActionResult Search(RoleSearch search, int page, int size = 20)
        {
            var result = new ApiResult<PagingList<Role>>();
            try
            {
                var pager = new PagingList<Role>() { Size = size, Index = page < 1 ? 1 : page };
                var query = from p in _dbContext.Roles
                            select p;
                if (!string.IsNullOrEmpty(search.Name))
                {
                    query = from p in query
                            where p.Name == search.Name
                            select p;
                }
                pager.Count = query.Count();
                var list = query.OrderByDescending(p => p.UpdateTime).Skip((pager.Index - 1) * size).Take(size).ToList();
                pager.Items = list;

                result = result.IsSuccess(pager);
            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
            }
            return new JsonResult(result);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id:long}")]
        public IActionResult Get(long id)
        {
            var result = new ApiResult<Role>();
            try
            {
                var data = _dbContext.Roles.Where(p => p.Id == id).SingleOrDefault();
                result = result.IsSuccess(data);
            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
            }
            return new JsonResult(result);
        }

        /// <summary>
        /// 添加版本信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task<IActionResult> Add(RoleModel model)
        {
            var result = new ApiResult<string>();
            var validator = new RoleModelValidator();
            var validation = validator.Validate(model);
            if (!validation.IsValid)
            {
                var message = validation.Errors.FirstOrDefault()?.ErrorMessage;
                result = result.IsFail(message ?? string.Empty, null);
                return new JsonResult(result);
            }
            try
            {
                var role = _dbContext.Roles.SingleOrDefault(p => p.Name == model.Name);
                if (role != null)
                {
                    result = result.IsFail("角色名称已经被使用，请更换角色名称");
                    return new JsonResult(result);
                }
                role = _mapper.Map<Role>(model);
                role.CreateTime = DateTime.UtcNow;

                _dbContext.Roles.Add(role);
                var count = _dbContext.SaveChanges();

                result = result.IsSuccess(count.ToString());

            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
            }
            return new JsonResult(result);
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("edit")]
        public async Task<IActionResult> EditAsync(RoleModel model)
        {
            var result = new ApiResult<string>();
            var validator = new RoleModelValidator();
            var validation = validator.Validate(model);
            if (!validation.IsValid)
            {
                var message = validation.Errors.FirstOrDefault()?.ErrorMessage;
                result = result.IsFail(message ?? string.Empty, null);
                return new JsonResult(result);
            }

            var data = _dbContext.Roles.SingleOrDefault(p => p.Id != model.Id && p.Name == model.Name);
            if (data != null)
            {
                result = result.IsFail("角色名称已经被使用，请更换角色名称");
                return new JsonResult(result);
            }

            data = _dbContext.Roles.SingleOrDefault(p => p.Id == model.Id);
            if (data == null)
            {
                result = result.IsFail("数据不存在");
                return new JsonResult(result);
            }

            data = _mapper.Map(model, data);
            data.UpdateTime = DateTime.UtcNow;

            try
            {
                int count = _dbContext.SaveChanges();
                result = result.IsSuccess(count.ToString());
            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
                Console.WriteLine(ex.Message);
            }
            return new JsonResult(result);
        }

        /// <summary>
        /// 根据ID删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("delete/{id:long}")]
        public IActionResult Delete(long id)
        {
            var result = new ApiResult<string>();


            var role = _dbContext.Roles.SingleOrDefault(p => p.Id == id);
            if (role != null)
            {
                if (role.IsSystemRole)
                {
                    result = result.IsFail("系统预设角色不允许删除");
                    return new JsonResult(result);
                }
                else
                {
                    _dbContext.Remove(role);
                    var count = _dbContext.SaveChanges();
                    result = result.IsSuccess(count.ToString());
                }
            }
            return new JsonResult(result);
        }

        /// <summary>
        /// 获取系统全部权限
        /// </summary>
        /// <returns></returns>
        [HttpGet("permission/{roleId}")]
        public async Task<IActionResult> GetAllPermission(int roleId)
        {
            var result = new ApiResult<List<RolePermissionGroup>>();

            var role = _dbContext.Roles.SingleOrDefault(p => p.Id == roleId);
            if (role == null)
            {
                result = result.IsFail("角色不存在");
                return new JsonResult(result);
            }

            var rolePermission = role.Permission.Split(',', StringSplitOptions.RemoveEmptyEntries).ToHashSet();

            var data = await _cacheService.GetAllPermissions();
            if (data == null)
            {
                data = await _cacheService.GetAllPermissions(true);
            }

            var group = data.GroupBy(p => p.Category).Select(g => new RolePermissionGroup
            {
                Category = g.Key,
                CategoryName = Permissions.GetPermissionDescription(g.Key),
                PermissionItems = g.Select(p => new RolePermissionItem
                {
                    Name = p.Name,
                    Description = Permissions.GetPermissionDescription(p.Name),
                    IsSelected = rolePermission.Contains(p.Name)
                }).ToList()
            }).ToList();

            result = result.IsSuccess(group);
            return new JsonResult(result);
        }


    }
}
