using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NLog;
using backstage.Helpers;
using backstage.Models;
using backstage.Models.Users;
using Newtonsoft.Json.Linq;

namespace backstage.Controllers
{
    public class UserController : Controller
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IConfiguration _config;
        private readonly ICallApi _callApi;

        private static Logger logger = LogManager.GetCurrentClassLogger();
        /// <summary>
        /// 讀取組態用
        /// </summary>

        public UserController(IConfiguration config, ICallApi callApi, IHttpContextAccessor httpContextAccessor)
        {
            _config = config;
            _callApi = callApi;
            _httpContextAccessor = httpContextAccessor;
        }

        [Authorize]
        [HttpGet]
        public IActionResult Register()
        {
            return View();
        }


        [HttpGet]
        public async Task<IActionResult> Login()
        {
            if (HttpContext.User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Index", "Home");
            }
            return View();

        }


        [HttpGet]
        public async Task<IActionResult> ListUsers()
        {
            var UserResponse = new UserResponse();

            // 確認使用者是否已經登入
            if (!User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Login");

            }

            // 取得使用者的 "token" Claim 值
            string token = User.FindFirstValue("token");
            #region user/list
            var url = _config["IP"] + "/user/list";
            var httpMethod = HttpMethod.Post;
            var types = new[] { "all" };
            var types_data = new { inc = types };
            var parameters = new Dictionary<string, string>
              {
                    { "token", token },
                    { "types", JsonConvert.SerializeObject(types_data)},
                { "email","1"},
                { "phone","1"}
                    //{ "types", "{\"inc\":[\"all\"]}"}

                };

            var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
            if (apiResult.IsSuccess)
            {
                UserResponse = JsonConvert.DeserializeObject<UserResponse>(apiResult.Data.ToString());

            }
            #endregion

            #region admin/list
            url = _config["IP"] + "/admin/list";
            httpMethod = HttpMethod.Post;
            types = new[] { "admin" };
            types_data = new { inc = types };

            parameters = new Dictionary<string, string>
              {
                    { "token", token },
                    { "types", JsonConvert.SerializeObject(types_data)},
                { "email","1"},
                { "phone","1"}
                    //{ "types", "{\"inc\":[\"all\"]}"}

                };

            apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
            var adminResponse = new UserResponse();
            if (apiResult.IsSuccess)
            {
                adminResponse = JsonConvert.DeserializeObject<UserResponse>(apiResult.Data.ToString());

            }
            #endregion

            if (adminResponse.r == 0)
            {
                if (adminResponse.userCount > 0)
                {
                    foreach (var a in adminResponse.Users)
                    {
                        foreach (var v in UserResponse.Users)
                        {
                            if (v.uid == 1)
                                v.isAdmin = true;
                            if (a.uid == v.uid)
                                v.isAdmin = true;

                        }
                    }
                }
            }
            ViewBag.adminCount = adminResponse.userCount;
            ViewBag.userCount = UserResponse.userCount;
            return View(UserResponse);




        }

        [HttpGet("/User/GetUser/{uid}")]
        public async Task<IActionResult> GetUser(int uid)
        {
            var url = _config["IP"] + "/user/get";
            // 確認使用者是否已經登入
            if (!User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Login");

            }


            var httpMethod = HttpMethod.Post;
            // 取得使用者的 "token" Claim 值
            string token = User.FindFirstValue("token");

            var types = new string[] { "merchant", "admin", "user" }; // 陣列中的不同 type 值
            var parameters = new Dictionary<string, string>
              {
                    { "token", token },
                { "type","merchant"},
                { "uid",uid.ToString()}

             };
            

          
            int maxRetries = types.Length; // 最大重試次數
            int currentRetry = 0; // 目前重試次數

            while (currentRetry < maxRetries)
            {
                var currentIndex = Array.IndexOf(types, parameters["type"]); // 取得當前 type 的索引
                var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
                if (apiResult.IsSuccess)
                {


                    try
                    {
                        var GetUserResponse = JsonConvert.DeserializeObject<GetUserResponse>(apiResult.Data.ToString());
                        if (GetUserResponse.r == 0)
                        {
                            if (!string.IsNullOrEmpty(GetUserResponse.user.username))
                            {
                                var user = new User();
                                user.name = GetUserResponse.user.name;
                                user.username = GetUserResponse.user.username;
                                if(GetUserResponse.email!=null)
                                    user.email =  GetUserResponse.email;
                                // 使用 JSON 解析工具將 JSON 字串轉換為物件
                                //var jsonObject = JsonConvert.DeserializeObject<Dictionary<string, string>>(apiResult.Data.ToString());

                           
                                
                                //user.created_date = DateTime.Parse(jsonObject["created_date"]);
                                return View(user);
                            }
                        }
                        else
                        {
                            TempData["IsSuccess"] = false;
                            TempData["msg"] = "使用者不存在";
                            return RedirectToAction("ListUsers");
                        }
                    }
                    catch (Exception e)
                    {
                        currentRetry++; // 增加重試次數
                                        // 如果 type 不是最後一個陣列元素，則將 type 更改為下一個值
                        if (currentIndex < types.Length - 1)
                        {
                            parameters["type"] = types[currentIndex + 1];
                        }
                    }
                }
            }



            return View();
        }



        [HttpGet]
        public async Task<IActionResult> CreateUser()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> CreateUser(User user)
        {
            var url = _config["IP"] + "/user/add";
            // 確認使用者是否已經登入
            if (!User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Login");

            }
            if (string.IsNullOrEmpty(user.password))
            {
                ModelState.AddModelError("Password", "密碼不能為空");
            }

            var httpMethod = HttpMethod.Post;
            // 取得使用者的 "token" Claim 值
            string token = User.FindFirstValue("token");


            var parameters = new Dictionary<string, string>
              {
                    { "token", token },
                { "data",JsonConvert.SerializeObject(user)}

                };
            var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
            if (apiResult.IsSuccess)
            {
                var userAddResponse = JsonConvert.DeserializeObject<UserAddResponse>(apiResult.Data.ToString());
                if (userAddResponse.r == 0)
                {
                    TempData["IsSuccess"] = true;
                    TempData["msg"] = "新增使用者成功";
                    return RedirectToAction("ListUsers");
                }
                else
                {
                    TempData["IsSuccess"] = false;
                    TempData["msg"] = JsonConvert.SerializeObject(userAddResponse.m);
                    return View(user);
                }


            }



            return View();
        }


        [HttpGet]
        public async Task<IActionResult> ListDepartments()
        {
            var DepartmentsResponse = new DepartmentsResponse();
            var url = _config["IP"] + "/merchant/list";
            // 確認使用者是否已經登入
            if (!User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Login");

            }


            var httpMethod = HttpMethod.Post;
            // 取得使用者的 "token" Claim 值
            string token = User.FindFirstValue("token");


            var parameters = new Dictionary<string, string>
              {
                    { "token", token }

                };

            var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
            if (apiResult.IsSuccess)
            {
                DepartmentsResponse = JsonConvert.DeserializeObject<DepartmentsResponse>(apiResult.Data.ToString());
                if (DepartmentsResponse.r == 0)
                {
                    return View(DepartmentsResponse);
                }

            }

            return Ok(apiResult.Data.ToString());


        }


        [HttpGet("/User/GetDepartment/{id}")]
        public async Task<IActionResult> GetDepartment(int id)
        {
            var url = _config["IP"] + "/merchant/get";
            // 確認使用者是否已經登入
            if (!User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Login");

            }


            var httpMethod = HttpMethod.Post;
            // 取得使用者的 "token" Claim 值
            string token = User.FindFirstValue("token");


            var parameters = new Dictionary<string, string>
              {
                    { "token", token },
                { "merchant_id",id.ToString()}

                };
            var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
            if (apiResult.IsSuccess)
            {
                var DepartmentsResponse = JsonConvert.DeserializeObject<DepartmentsResponse>(apiResult.Data.ToString());
                if (DepartmentsResponse.r == 0)
                {

                    return View(DepartmentsResponse.merchant);

                }
                else
                {
                    TempData["IsSuccess"] = false;
                    TempData["msg"] = "使用者不存在";
                    return RedirectToAction("ListUsers");
                }


            }



            return View();
        }


        [HttpGet]
        public async Task<IActionResult> CreateDepartment()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> CreateDepartment(DepartmentForCreate department)
        {
            var url = _config["IP"] + "/merchant/add";
            // 確認使用者是否已經登入
            if (!User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Login");

            }
            if (string.IsNullOrEmpty(department.name))
            {
                ModelState.AddModelError("name", "部門名稱不能為空");
            }
            if (string.IsNullOrEmpty(department.phone))
            {
                department.phone = "null";
            }

            var httpMethod = HttpMethod.Post;
            // 取得使用者的 "token" Claim 值
            string token = User.FindFirstValue("token");



            var parameters = new Dictionary<string, string>
              {
                    { "token", token },
                    { "data",JsonConvert.SerializeObject(department)}

                };
            var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
            if (apiResult.IsSuccess)
            {
                var userAddResponse = JsonConvert.DeserializeObject<UserAddResponse>(apiResult.Data.ToString());
                if (userAddResponse.r == 0)
                {
                    TempData["IsSuccess"] = true;
                    TempData["msg"] = "新增部門成功";
                    return RedirectToAction("ListDepartments");
                }
                else
                {
                    TempData["IsSuccess"] = false;
                    TempData["msg"] = JsonConvert.SerializeObject(userAddResponse.m);
                    return View(department);
                }


            }



            return View();
        }



        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Login(User user, string returnUrl)
        {

            if (!ModelState.IsValid)
            {
                return View(user);
            }



            //var u = await _UserRepository.Login(user);
            var u = new UserLogin();



            var url = _config["IP"];
            var parameters = new Dictionary<string, string>
              {
                    { "username", user.username },
                    { "pwd", user.pwd },
                    { "reqPermFlag[0]","admin-login"}
              };
            var httpMethod = HttpMethod.Post;

            try
            {
                var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);

                if (apiResult.IsSuccess)
                {
                    // API 呼叫成功，進行相應的處理

                    u = JsonConvert.DeserializeObject<UserLogin>(apiResult.Data.ToString());
                    if (u.r == 0 && !string.IsNullOrEmpty(u.token))
                    {
                        #region 寫入TOKEN
                        int LoginExpireMinute = Convert.ToInt32(_config["LoginExpireMinute"]);
                        string key = _config["TokenKey"];

                        var Cookieoptions = new CookieOptions();
                        ////時間一到就會把Token從Cookie洗掉,如果Expires沒比API的Expires長,則每次Token過期都須重新登入
                        Cookieoptions.Expires = DateTime.Now.AddMinutes(LoginExpireMinute);
                        //Cookieoptions.SameSite = SameSiteMode.Strict;
                        Cookieoptions.HttpOnly = true;

                        var userClaims = new ClaimsIdentity(new[]
                                {
                       new Claim("username", user.username),
                        new Claim("token", u.token),
                         }, CookieAuthenticationDefaults.AuthenticationScheme);

                        //將 ClaimsIdentity 設定給 ClaimsPrincipal (持有者) 
                        ClaimsPrincipal principal = new ClaimsPrincipal(userClaims);
                        //登入動作

                        try
                        {
                            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties()
                            {
                                //是否可以被刷新
                                AllowRefresh = true,
                                // 設置了一個 1 天 有效期的持久化 cookie
                                IsPersistent = true, //IsPersistent = false，瀏覽器關閉即刻登出
                                                     //用戶頁面停留太久，逾期時間，在此設定的話會覆蓋Startup.cs裡的逾期設定
                                ExpiresUtc = DateTime.Now.AddMinutes(LoginExpireMinute),


                            });
                        }
                        catch (Exception ex)
                        {
                            logger.Trace(ex.Message + ex.InnerException?.Message);
                        }
                        #endregion


                        return RedirectToAction("Index", "Home");
                    }
                    else
                    {
                        // API 呼叫失敗，進行相應的錯誤處理
                        return BadRequest(apiResult.Message);
                    }

                }
                else
                {
                    // API 呼叫失敗，進行相應的錯誤處理
                    return BadRequest(apiResult.Message);
                }
            }
            catch (Exception ex)
            {
                // 處理 API 呼叫發生的例外狀況
                return StatusCode(500, $"API 呼叫發生錯誤：{ex.Message}");
            }





        }


        [HttpGet]
        public async Task<IActionResult> Logout()
        {

            await HttpContext.SignOutAsync();
            foreach (var cookieKey in Request.Cookies.Keys)
                HttpContext.Response.Cookies.Delete(cookieKey);
            return RedirectToAction(nameof(Login));

        }


        public async Task<IActionResult> List()
        {


            //TempData["IsSuccess"] = result.IsSuccess;
            //TempData["msg"] = result.Message;
            //return View(viewModel);
            throw new NotImplementedException();
        }
        public async Task<ResultModel> Delete(int id)
        {
            throw new NotImplementedException();
        }

    }
}