using Backend.Models;

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

namespace Backend.Controllers
{
    public class UserInfoController : MybaseController<UserInfoController>
    {
        private readonly ILogger<UserInfoController> _logger;
        private readonly IBackendRepository backendRepository;

        public UserInfoController(ILogger<UserInfoController> logger, IBackendRepository backendRepository)
        {
            _logger = logger;
            this.backendRepository = backendRepository;
        }
        public IActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 帳號管理列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<List<UserManagerList>>> UserManagerList()
        {
            ApiResult<List<UserManagerList>> apiResult = new ApiResult<List<UserManagerList>>();
            List<UserManagerList> userManagerList = new List<UserManagerList>();

            try
            {
                var sqlString = @$"SELECT A.userinfo_guid, A.full_name, B.full_name AS 'Role_full_name', A.email, A.phone, A.created_at,A.Account ,B.layer
                                   FROM userinfo A
                                   LEFT JOIN role B ON A.role_guid=B.role_guid AND B.deleted='0' 
                                   WHERE A.deleted = 0
                                   ORDER BY A.created_at DESC";
                userManagerList = await backendRepository.GetAllAsync<UserManagerList>(sqlString);

                apiResult.Code = "0000";
                apiResult.Data = userManagerList;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

        /// <summary>
        /// 角色管理列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<List<RoleManagerList>>> RoleManagerList(int post) //是否判斷layer 0:否 1:是
        {
            ApiResult<List<RoleManagerList>> apiResult = new ApiResult<List<RoleManagerList>>();
            List<RoleManagerList> roleList = new List<RoleManagerList>();

            try
            {
                var layersql = "";
                if(post == 1)
                {
                    layersql = "and A.layer = 1 ";
                }
                var sqlString = @$"SELECT *
                                   FROM role A
                                   WHERE A.deleted = 0 {layersql}
                                   ORDER BY A.created_at DESC";
                roleList = await backendRepository.GetAllAsync<RoleManagerList>(sqlString);

                apiResult.Code = "0000";
                apiResult.Data = roleList;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

        /// <summary>
        /// 新增 / 修改 使用者
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> SaveUser(SaveUserManager post)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            UserInfo userInfo = null;

            try
            {
                userInfo = await backendRepository.GetOneAsync<UserInfo>("userinfo", $"userinfo_guid='{post.Id.ToString()}'");

                if (userInfo == null)
                {

                    if (post.Id != "0")
                    {
                        apiResult.Code = "9998";
                        apiResult.Msg = "查無該使用者。";
                        return apiResult;
                    }

                    #region 新增使用者
                    //判斷帳號 是否已存在
                    var exist = await backendRepository.HasExistsWithGuid(post.Account, "userinfo", "account");
                    if (exist)
                    {
                        apiResult.Code = "9986";
                        apiResult.Msg = "該帳號已被註冊,請重新輸入";
                        return apiResult;
                    }

                    EDFunction edFunction = new EDFunction();

                    //隨機產生亂數密碼
                    Random random = new Random((int)DateTime.Now.Ticks);
                    const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
                    string random_password = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(chars.Length)]).ToArray());

                    var newPassword = edFunction.GetSHA256Encryption(random_password);

                    //產生一組GUID
                    var guid = Guid.NewGuid();  //使用者GUID

                    Dictionary<string, object> userinfo = new Dictionary<string, object>();
                    userinfo = new Dictionary<string, object>()
                                {
                                    { "@userinfo_guid", guid},
                                    { "@Full_name", post.Name},
                                    { "@Email", post.Email},
                                    { "@Account", post.Account},
                                    { "@Password", newPassword},
                                    { "@Role_guid", post.RoleId},
                                    { "@Phone", post.Phone},
                                    { "@created_by", myUserInfo.Userinfo_guid}
                                };

                    await backendRepository.AddOneByCustomTable(userinfo, "userinfo");

                    var sWhere = "system_type = 'website_config' AND system_key = 'website_url'";
                    var website_url = await backendRepository.GetOneAsync<Variable>("variable", sWhere);


                    var sendSubject = "新增帳號成功";
                    var sendContent = $@"您的新密碼為:{random_password}
                                        <br>立即前往:<a href='{website_url.system_value}' target='_blank'>{website_url.system_value}</a>";

                    Dictionary<string, object> insertNotify = new Dictionary<string, object>() 
                    {
                        { "@task_type", 0},
                        { "@recipient_name", post.Name},
                        { "@recipient_phone", post.Phone},
                        { "@recipient_email", post.Email},
                        { "@message_content", sendContent}
                    };

                    //await backendRepository.AddOneByCustomTable(insertNotify, "background_service_message_notification_task");

                    apiResult.Code = "0000";
                    apiResult.Msg = "儲存成功";
                    #endregion
                }
                else
                {
                    #region 修改使用者
                    Dictionary<string, object> userinfo = new Dictionary<string, object>();
                    var role = await backendRepository.GetOneAsync<byte>(@$"select layer from role where role_guid = '{post.RoleId}'");
                    var infoguid = await backendRepository.GetAllAsync<string>($@"select r.full_name from userinfo u
                    left join role r on u.role_guid = r.role_guid
                    where r.layer = 0 and u.userinfo_guid != '{post.Id}'");
                    if(infoguid.Count == 0 && role == 1)
                    {
                        apiResult.Code = "9998";
                        var getrolename = await backendRepository.GetOneAsync<string>("select r.full_name from role r where r.layer = 0");
                        apiResult.Msg = getrolename + "-僅剩一位<br>故無法儲存";
                    }
                    else
                    {
                        userinfo = new Dictionary<string, object>()
                        {
                            { "@Full_name", post.Name},
                            { "@Email", post.Email},
                            { "@Role_guid", post.RoleId},
                            { "@Phone", post.Phone},
                            { "@updated_by", myUserInfo.Userinfo_guid},
                            { "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
                        };
                        await backendRepository.UpdateOneByCustomTable(userinfo, "userinfo", $"userinfo_guid='{post.Id}'");

                        apiResult.Code = "0000";
                        apiResult.Msg = "儲存成功";
                    }
                    #endregion
                }
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                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="guid"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<SimpleUser>> GetOneUser(string guid)
        {
            ApiResult<SimpleUser> apiResult = new ApiResult<SimpleUser>();

            SimpleUser simpleUser = null;

            try
            {
                simpleUser = await backendRepository.GetOneAsync<SimpleUser>("userinfo", $"userinfo_guid='{guid}'");

                if (simpleUser == null)
                {
                    apiResult.Code = "9998";
                    apiResult.Msg = "查無該使用者。";
                    return apiResult;
                }

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

            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }
            return apiResult;
        }

        /// <summary>
        /// 軟刪除單一使用者
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> DeleteOneUser(string guid)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            SimpleUser simpleUser = null;

            try
            {
                simpleUser = await backendRepository.GetOneAsync<SimpleUser>("userinfo", $"userinfo_guid='{guid}'");

                if (simpleUser == null)
                {
                    apiResult.Code = "9998";
                    apiResult.Msg = "查無該使用者。";
                    return apiResult;
                }

                await backendRepository.DeleteOne(guid, "userinfo", "userinfo_guid");

                apiResult.Code = "0000";
                apiResult.Msg = "刪除成功";
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            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>();

            RoleManagerList roleManager = null;

            try
            {
                roleManager = await backendRepository.GetOneAsync<RoleManagerList>("role", $"role_guid='{post.Id.ToString()}'");

                if (roleManager == null)
                {

                    if (post.Id != "0")
                    {
                        apiResult.Code = "9994";
                        apiResult.Msg = "查無該角色";
                        return apiResult;
                    }

                    #region 新增角色
                    //產生一組GUID
                    var guid = Guid.NewGuid();  //角色GUID
                    Dictionary<string, object> role = new Dictionary<string, object>();
                    role = new Dictionary<string, object>()
                            {
                                { "@role_guid", guid},
                                { "@Full_name", post.Name},
                                { "@created_by", myUserInfo.Userinfo_guid}
                            };

                    await backendRepository.AddOneByCustomTable(role, "role");

                    apiResult.Code = "0000";
                    apiResult.Msg = "儲存成功";
                    #endregion
                }
                else
                {
                    #region 修改角色
                    Dictionary<string, object> role = new Dictionary<string, object>();
                    role = new Dictionary<string, object>()
                            {
                                { "@Full_name", post.Name},
                                { "@updated_by", myUserInfo.Userinfo_guid},
                                { "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
                            };
                    await backendRepository.UpdateOneByCustomTable(role, "role", $"role_guid='{post.Id}'");


                    apiResult.Code = "0000";
                    apiResult.Msg = "儲存成功";
                    #endregion
                }
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                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<SimpleRole>> GetOneRole(string guid)
        {
            ApiResult<SimpleRole> apiResult = new ApiResult<SimpleRole>();

            SimpleRole simpleRole = null;

            try
            {
                simpleRole = await backendRepository.GetOneAsync<SimpleRole>("role", $"role_guid='{guid}'");

                if (simpleRole == null)
                {
                    apiResult.Code = "9994";
                    apiResult.Msg = "查無該角色";
                    return apiResult;
                }

                apiResult.Code = "0000";
                apiResult.Data = simpleRole;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }
            return apiResult;
        }

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

            SimpleRole simpleRole = null;

            try
            {
                simpleRole = await backendRepository.GetOneAsync<SimpleRole>("role", $"role_guid='{guid}'");

                if (simpleRole == null)
                {
                    apiResult.Code = "9998";
                    apiResult.Msg = "查無該角色";
                    return apiResult;
                }

                //檢查是否有使用者為該角色
                var sWhere = $@"deleted = 0 AND role_guid = @Guid";
                var userInfos = await backendRepository.GetAllAsync<UserInfo>("userinfo", sWhere, new { Guid = guid });
                if (userInfos.Count > 0)
                {
                    apiResult.Code = "9997";
                    apiResult.Msg = "帳號管理中尚有帳號正在使用該角色,故無法刪除";
                    return apiResult;
                }


                await backendRepository.DeleteOne(guid, "role", "role_guid");

                apiResult.Code = "0000";
                apiResult.Msg = "刪除成功";
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

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

            try
            {
                var sqlString = @$"SELECT A.role_guid, A.AuthCode, B.full_name AS 'Role_full_name', C.AuthType, C.MainName, C.SubName, D.full_name AS 'Building_full_name', A.created_at
                                   FROM role_auth A
                                   LEFT JOIN role B ON A.role_guid=B.role_guid AND B.deleted=0
                                   INNER JOIN auth_page C ON A.AuthCode=C.AuthCode
                                   LEFT JOIN building D ON C.building_guid=D.building_guid AND D.deleted=0
                                   WHERE A.role_guid='{post.SelectedRoleId}'
                                   ORDER BY A.created_at DESC";
                roleAuthList = await backendRepository.GetAllAsync<RoleAuthList>(sqlString);

                apiResult.Code = "0000";
                apiResult.Data = roleAuthList;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

        /// <summary>
        /// 取得此角色未選擇的權限
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        public async Task<ApiResult<List<AuthPage>>> GetRoleNotAuthPageList(PostRoleAuthFilter post)
        {
            ApiResult<List<AuthPage>> apiResult = new ApiResult<List<AuthPage>>();
            List<AuthPage> authPage = new List<AuthPage>();

            try
            {
                if (!string.IsNullOrEmpty(post.SelectedRoleId))
                {
                    var buildingGuid = "";
                    if (post.SelectedBuild != "0")
                    {
                        buildingGuid = $" AND ap.building_guid = '{post.SelectedBuild}'";
                    }
                    var sqlString = @$" SELECT ap.AuthCode, ap.MainName, ap.SubName FROM auth_page ap
                                    WHERE ap.AuthType='{post.SelectedAuthType}' 
                                    {buildingGuid}
                                    AND ap.AuthCode NOT IN ( 
	                                    SELECT ra.AuthCode FROM role_auth ra
	                                    LEFT JOIN auth_page ap ON ra.AuthCode = ap.AuthCode
	                                    WHERE ra.role_guid = '{post.SelectedRoleId}'
	                                    {buildingGuid}
	                                    AND ap.AuthType='{post.SelectedAuthType}'
                                     )";
                    authPage = await backendRepository.GetAllAsync<AuthPage>(sqlString);
                }
                apiResult.Code = "0000";
                apiResult.Data = authPage;
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }

        /// <summary>
        /// 新增 權限
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> SaveRoleAuth(PostSaveRoleAuth post)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            RoleManagerList roleManager = null;

            try
            {
                roleManager = await backendRepository.GetOneAsync<RoleManagerList>("role", $"role_guid='{post.SelectedRoleId}'");

                if (roleManager == null)
                {
                    apiResult.Code = "9994";
                    apiResult.Msg = "查無該角色";
                    return apiResult;
                }
                else
                {
                    if(post.SaveCheckAuth.Count > 0)
                    {
                        foreach (var item in post.SaveCheckAuth)
                        {
                            #region 新增權限
                            Dictionary<string, object> roleAuth = new Dictionary<string, object>();
                            roleAuth = new Dictionary<string, object>()
                                {
                                    { "@role_guid", post.SelectedRoleId},
                                    { "@AuthCode", item},
                                    { "@created_by", myUserInfo.Userinfo_guid}
                                };

                            await backendRepository.AddOneByCustomTable(roleAuth, "role_auth");

                            
                            #endregion
                        }
                    }
                    apiResult.Code = "0000";
                    apiResult.Msg = "儲存成功";
                }
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                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="post"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> DeleteOneRoleAuth(PostDeleteRoleAuth post)
        {
            ApiResult<string> apiResult = new ApiResult<string>();

            RoleManagerList roleManager = null;

            try
            {
                roleManager = await backendRepository.GetOneAsync<RoleManagerList>("role", $"role_guid='{post.RoleId}'");

                if (roleManager == null)
                {
                    apiResult.Code = "9994";
                    apiResult.Msg = "查無該角色";
                    return apiResult;
                }

                await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("role_auth", $"role_guid='{post.RoleId}' AND AuthCode='{post.AuthCode}'");

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

            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
                string json = System.Text.Json.JsonSerializer.Serialize(post);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }

            return apiResult;
        }
    }
}