using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SolarPower.Models;
using SolarPower.Models.Role;
using SolarPower.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SolarPower.Controllers
{
    public class RoleController : MyBaseController<RoleController>
    {
        private readonly IRoleRepository roleRepository;
        public RoleController(IRoleRepository roleRepository) : base()
        {
            this.roleRepository = roleRepository;
        }
        public IActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 取得下拉式公司選單，須為Deleted: 0
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<List<RoleSelectItemList>>> GetRoleSelectOptionListAsync(int companyId)
        {
            ApiResult<List<RoleSelectItemList>> apiResult = new ApiResult<List<RoleSelectItemList>>();

            try
            {
                var roleSelectItemLists = await roleRepository.GetRoleSelectOptionListAsync(companyId);

                apiResult.Code = "0000";
                apiResult.Data = roleSelectItemLists;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            apiResult.Msg = errorCode.GetString(apiResult.Code);
            return apiResult;
        }

        /// <summary>
        /// 角色管理列表
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> RoleList(PostRoleFilter post)
        {
            ApiResult<List<RoleDateTable>> apiResult = new ApiResult<List<RoleDateTable>>();

            int totalRecords = 0; //總資料筆數
            int recFilter = 0; //過濾後資料筆數

            List<RoleDateTable> roles = null;

            try
            {
                roles = await roleRepository.GetAllByFilterAsync(post);
                totalRecords = roles.Count();
                recFilter = roles.Count();

                foreach(var role in roles)
                {
                    if(role.Layer == (int)RoleLayerEnum.PlatformAdmin || role.Layer == (int)RoleLayerEnum.CompanyAdmin)
                    {   //管理階層的角色無法被刪除
                        role.Function = "<button class='btn btn-primary edit-btn'>修改</button>";
                    }
                    else
                    {
                        role.Function = @"<button class='btn btn-primary edit-btn'>修改</button>
                                          <button class='btn btn-danger del-btn'>刪除</button>";
                    }
                }

                apiResult.Code = "0000";
                apiResult.Data = roles;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                string json = System.Text.Json.JsonSerializer.Serialize(post);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }


            apiResult.Msg = errorCode.GetString(apiResult.Code);
            var result = Json(new
            {
                recordsTotal = totalRecords,
                recordsFiltered = recFilter,
                data = apiResult
            });

            return result;
        }

        /// <summary>
        /// 取得單一公司角色
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<Role>> GetOneRole(int id)
        {
            ApiResult<Role> apiResult = new ApiResult<Role>();

            Role role = null;

            try
            {
                role = await roleRepository.GetOneRoleAsync(id);

                if (role == null)
                {
                    apiResult.Code = "9994";
                    apiResult.Msg = errorCode.GetString(apiResult.Code);
                    return apiResult;
                }

                apiResult.Code = "0000";
                apiResult.Data = role;

            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Id=" + id);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            apiResult.Msg = errorCode.GetString(apiResult.Code);
            return apiResult;
        }

        /// <summary>
        /// 新增 / 修改 公司角色
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> SaveRole(PostRole post)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            Role role = null;

            try
            {
                role = await roleRepository.GetOneRoleAsync(post.Id);

                if (role == null)
                {

                    if (post.Id != 0)
                    {
                        apiResult.Code = "9994";
                        apiResult.Msg = errorCode.GetString(apiResult.Code);
                        return apiResult;
                    }


                    if(!IsPlatformLayer(myUser.Role.Layer) && myUser.CompanyId != post.SelectedCompanyId)
                    {   //非平台人員，就只能新增自己公司的角色
                        apiResult.Code = "9993";
                        apiResult.Msg = errorCode.GetString(apiResult.Code);
                        return apiResult;
                    }

                    #region 新增公司角色
                    role = new Role()
                    {
                        CompanyId = post.SelectedCompanyId,
                        Name = post.Name,
                        CreatedBy = myUser.Id,
                    };

                    if (IsPlatformLayer(myUser.Role.Layer))
                    {   //平台新增角色 Layer，為平台使用者階層
                        role.Layer = 1;
                    }
                    else
                    {   //公司新增角色 Layer，為公司使用者階層
                        role.Layer = 3;
                    }

                    List<string> properties = new List<string>()
                    {
                        "CompanyId",
                        "Name",
                        "Layer",
                        "CreatedBy",
                    };

                    await roleRepository.AddAsync(role, properties);

                    apiResult.Code = "0000";
                    apiResult.Msg = "儲存成功";
                    #endregion
                }
                else
                {
                    #region 修改公司角色

                    if (!IsPlatformLayer(myUser.Role.Layer) && myUser.CompanyId != post.SelectedCompanyId)
                    {   //非平台人員，就只能修改自己公司的角色
                        apiResult.Code = "9993";
                        apiResult.Msg = errorCode.GetString(apiResult.Code);
                        return apiResult;
                    }

                    UpdateRole update = new UpdateRole()
                    {
                        Id = post.Id,
                        Name = post.Name,
                        UpdatedBy = myUser.Id,
                    };

                    List<string> properties = new List<string>()
                    {
                        "Id",
                        "Name",
                        "UpdatedBy",
                    };

                    await roleRepository.UpdateRoleAsync(update, properties);

                    apiResult.Code = "0000";
                    apiResult.Msg = "儲存成功";
                    #endregion
                }
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = errorCode.GetString(apiResult.Code);
                string json = System.Text.Json.JsonSerializer.Serialize(post);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

        /// <summary>
        /// 軟刪除單一公司角色
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> DeleteOneRole(int id)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            Role role = null;

            try
            {
                role = await roleRepository.GetOneRoleAsync(id);

                if (role == null)
                {
                    apiResult.Code = "9994";
                    apiResult.Msg = errorCode.GetString(apiResult.Code);
                    return apiResult;
                }

                await roleRepository.DeleteOne(role.Id);

                apiResult.Code = "0000";
                apiResult.Msg = "刪除成功";
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = errorCode.GetString(apiResult.Code);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Id=" + id);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

        /// <summary>
        /// 取得公司擁有的權限池
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> GetCompanyAuthPageList(int companyId)
        {
            ApiResult<List<CompanyAuthPage>> apiResult = new ApiResult<List<CompanyAuthPage>>();

            int totalRecords = 0; //總資料筆數
            int recFilter = 0; //過濾後資料筆數

            List<CompanyAuthPage> companyAuthPages = null;

            try
            {
                companyAuthPages = await roleRepository.GetAllCompanyAuthPageAsync(companyId);
                totalRecords = companyAuthPages.Count();
                recFilter = companyAuthPages.Count();

                apiResult.Code = "0000";
                apiResult.Data = companyAuthPages;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Id=" + companyId);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            apiResult.Msg = errorCode.GetString(apiResult.Code);
            var result = Json(new
            {
                recordsTotal = totalRecords,
                recordsFiltered = recFilter,
                data = apiResult
            });

            return result;
        }


        /// <summary>
        /// 角色權限管理列表
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> RoleAuthList(PostRoleAuthFilter post)
        {
            ApiResult<List<RoleAuthDataTable>> apiResult = new ApiResult<List<RoleAuthDataTable>>();

            int totalRecords = 0; //總資料筆數
            int recFilter = 0; //過濾後資料筆數

            List<RoleAuthDataTable> roleAuths = null;

            try
            {
                roleAuths = await roleRepository.GetAllAuthByRoleIdAsync(post.SelectedRoleId);
                totalRecords = roleAuths.Count();
                recFilter = roleAuths.Count();

                apiResult.Code = "0000";
                apiResult.Data = roleAuths;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                string json = System.Text.Json.JsonSerializer.Serialize(post);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }


            apiResult.Msg = errorCode.GetString(apiResult.Code);
            var result = Json(new
            {
                recordsTotal = totalRecords,
                recordsFiltered = recFilter,
                data = apiResult
            });

            return result;
        }

        /// <summary>
        /// 取得該公司角色尚未加入的權限
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetRoleNotAuthPageList(PostRoleAuthFilter post)
        {
            ApiResult<List<AuthPage>> apiResult = new ApiResult<List<AuthPage>>();

            int totalRecords = 0; //總資料筆數
            int recFilter = 0; //過濾後資料筆數

            List<AuthPage> roleAuths = null;

            try
            {
                roleAuths = await roleRepository.GetRoleNotAuthPageAsync(post);
                totalRecords = roleAuths.Count();
                recFilter = roleAuths.Count();

                apiResult.Code = "0000";
                apiResult.Data = roleAuths;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                string json = System.Text.Json.JsonSerializer.Serialize(post);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }


            apiResult.Msg = errorCode.GetString(apiResult.Code);
            var result = Json(new
            {
                recordsTotal = totalRecords,
                recordsFiltered = recFilter,
                data = apiResult
            });

            return result;
        }

        /// <summary>
        /// 儲存公司角色的權限
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> SaveRoleAuth(PostRoleAuth post)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            Role role = null;

            try
            {
                role = await roleRepository.GetOneRoleAsync(post.SelectedRoleId);

                if (role == null)
                {
                    apiResult.Code = "9994";
                    apiResult.Msg = errorCode.GetString(apiResult.Code);
                    return apiResult;
                }

                List<RoleAuth> roleAuths = new List<RoleAuth>();

                foreach (var checkAuth in post.CheckAuths)
                {
                    RoleAuth roleAuth = new RoleAuth();
                    roleAuth.Id = role.Id;
                    roleAuth.AuthCode = checkAuth;
                    roleAuth.CreatedBy = myUser.Id;

                    roleAuths.Add(roleAuth);
                }

                List<string> properties = new List<string>()
                {
                    "Id",
                    "AuthCode",
                    "CreatedBy",
                };

                await roleRepository.AddRoleAuthAsync(roleAuths, properties);

                apiResult.Code = "0000";
                apiResult.Msg = "儲存成功";

            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = errorCode.GetString(apiResult.Code);
                string json = System.Text.Json.JsonSerializer.Serialize(post);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

        [HttpPost]
        public async Task<ApiResult<string>> DeleteOneRoleAuth(PostDeleteRoleAuth post)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            Role role = null;

            try
            {
                role = await roleRepository.GetOneRoleAsync(post.RoleId);

                if (role == null)
                {
                    apiResult.Code = "9994";
                    apiResult.Msg = errorCode.GetString(apiResult.Code);
                    return apiResult;
                }

                await roleRepository.PurgeOneRoleAuthAsync(post.RoleId, post.AuthCode);

                apiResult.Code = "0000";
                apiResult.Msg = "刪除成功";

            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = errorCode.GetString(apiResult.Code);
                string json = System.Text.Json.JsonSerializer.Serialize(post);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }
    }
}
