using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using wispro.sp.api.Job;
using wispro.sp.entity;
using wispro.sp.share;
using wispro.sp.share.webViewObject;

namespace wispro.sp.api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : ControllerBase
    {
        private static List<Staff> CacheList = new List<Staff>();
        public IConfiguration Configuration { get; }
        spDbContext dbContext;

        public AccountController(IConfiguration configuration,spDbContext _dbContext)
        {
            Configuration = configuration;
            dbContext = _dbContext;
        }
        
        [HttpGet,HttpPost,Route("Login")]
        public userToken Login(loginDto loginUser)
        {
            //添加验证代码
            
            Staff staff = dbContext.Staffs.Where<Staff>(s => s.Account == loginUser.Name ).FirstOrDefault(); //

           
            if (staff != null && staff.Password == utility.MD5Utility.GetMD5(loginUser.Password))
            {
                return GetToken(staff);
            }
            else
            {
                return new userToken() { 
                    StatusCode = System.Net.HttpStatusCode.NotFound,
                    Name = null, 
                    Token = null 
                };
            }
            
        }

        [Authorize]
        [HttpGet, HttpPost, Route("ChangePassword")]
        public bool ChangePassword(changePasswordDto dto)
        {
            Staff staff = dbContext.Staffs.Where<Staff>(s => s.Id  == dto.UserId  && s.Password == utility.MD5Utility.GetMD5(dto.oldPassword)).FirstOrDefault();

            if (staff != null)
            {
                staff.Password = utility.MD5Utility.GetMD5(dto.newPassword);
                dbContext.SaveChanges();
                return true;
            }
            else
            {
                return false;
            }
        }

        [HttpGet, HttpPost, Route("ResetPassword")]
        public ApiSaveResponse ResetPassword(string accountName,string mail)
        {
            ApiSaveResponse ret = new ApiSaveResponse();
            ret.Success = true;
            Staff staff = dbContext.Staffs.Where<Staff>(s => s.Account  == accountName  && s.Mail == mail).FirstOrDefault();

            if(staff != null)
            {
                string strPassword = "";
                Random random = new Random(); 
                for (int i = 0; i < 8; i++) 
                {
                    strPassword = $"{strPassword}{random.Next(0,9)}";
                    
                }
                staff.Password = utility.MD5Utility.GetMD5(strPassword);
                dbContext.SaveChanges();

                string strBody = $"<div style=\"position:absolute;width:800;height:300;margin-top:50px;margin-left:200px;margin-right:200px;box-shadow:0px 0px 3px 3px #ccc \"><div style= \"margin-top: 20px; margin-left:20px;;font-size:14px; \">{staff.Name},你好！</div><div style= \"margin-top: 25px; margin-left:20px;font-size:14px; \"><div>系统已为您重置密码，密码为：{strPassword}，请检查并补充缺失数据！</div><div style= \"margin-top: 100px;margin-right:15px; padding-bottom: 20px; font-size:14px;color:#888888;float:right; \">小美集团绩效管理系统</div></div>";
                _ = QuartzUtil.AddMailJob("重置密码通知", strBody, staff.Name, staff.Mail);
                return ret;
            }
            else
            {
                ret.Success = false;
                ret.ErrorMessage = "无效的用户名或邮箱";
                return ret;
            }

        }

        [HttpGet, HttpPost, Route("Modify")]
        public ApiSaveResponse Modify(string accountName,string status, string mail)
        {
            ApiSaveResponse ret = new ApiSaveResponse();
            ret.Success = true;
            Staff staff = dbContext.Staffs.Where<Staff>(s => s.Account == accountName).FirstOrDefault();

            if (staff != null)
            {
                staff.Status = status;
                staff.Mail = mail;
                
                dbContext.SaveChanges();
                
                return ret;
            }
            else
            {
                ret.Success = false;
                ret.ErrorMessage = "无效的用户名或邮箱";
                return ret;
            }
        }

        [Authorize]
        [HttpGet,Route("GetUser")]
        public userToken GetUser()
        {
            if (User.Identity.IsAuthenticated)//如果Token有效
            {
                var name = User.Claims.First(x => x.Type == ClaimTypes.Name).Value;//从Token中拿出用户ID
                                                                                   //模拟获得Token
                spDbContext dbContext = new spDbContext();
                Staff staff = dbContext.Staffs.Where<Staff>(s => s.Account == name).FirstOrDefault();

                if (staff != null)
                {
                    return GetToken(staff);
                }
                else
                {
                    return new userToken() {StatusCode=System.Net.HttpStatusCode.NotFound, Name = null, Token = null };
                }
            }
            else
            {
                return new userToken() {StatusCode= System.Net.HttpStatusCode.NotFound, Name = null, Token = null };
            }
        }


        private userToken GetToken(Staff staff)
        {
            

            var claims = new List<Claim>()
            {
                new Claim("Id",staff.Id.ToString()),
                new Claim(ClaimTypes.Name,staff.Name),
                new Claim(ClaimTypes.Email,(staff.Mail==null)?"":staff.Mail),
                
            };

            var positions = dbContext.DepartmentPositions.Where<DepartmentPosition>(dp => dp.StaffId == staff.Id).ToList();
            foreach (var p in positions)
            {
                claims.Add(new Claim(ClaimTypes.Role, $"[{p.departmentId}]-[{p.PositionId}]"));
            }

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["jwt:Key"]));
            var credential = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expireTime = DateTime.Now.AddHours(5);
            
            var token = new JwtSecurityToken(
                issuer: Configuration["jwt:Issuer"],
                audience: Configuration["jwt:Audience"],
                claims: claims.ToArray(),
                notBefore: DateTime.Now,
                expires: expireTime,                
                signingCredentials: credential);

            
            string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);

            //建立UserToken物件後回傳client
            userToken userToken = new userToken()
            {
                StatusCode = System.Net.HttpStatusCode.OK,
                UserId = staff.Id,
                Name = staff.Name,
                Token = jwtToken,
                ExpireTime = expireTime
            };

            return userToken;

        }

        [Authorize]
        [HttpGet, HttpPost, Route("GetRoles")]
        public List<string> GetRoles(string ResourceId)
        {
            var Authors = Configuration[$"Authorize:{ResourceId}"];

            if (string.IsNullOrEmpty(Authors))
            {
                return new List<string>();
            }

            var ret = Authors.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            return ret.ToList<string>();
        }
    }
    
}
