using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using ZhonTai.Admin.Core.Attributes;
using ZhonTai.Admin.Core.Consts;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services.Auth.Dto;
using ZhonTai.Admin.Services.DiTuiAPI.Dto;
using ZhonTai.Common.Helpers;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
using ZhonTai.Admin.Domain.Platform;
using ZhonTai.Admin.Core.Configs;
using ZhonTai.Admin.Domain.Tenant;
using System.Security.Claims;
using ZhonTai.Admin.Core.Auth;
using ZhonTai.Common.Extensions;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Http;
using ZhonTai.Admin.Domain.Org;

namespace ZhonTai.Admin.Services.DiTuiAPI
{
    /// <summary>
    /// 前端接口
    /// </summary>
    [DynamicApi(Area = AdminConsts.DiTuiName)]
    public class DiTuiAPIService : BaseService, IDiTuiAPIService, IDynamicApi
    {
        private readonly AppConfig _appConfig;
        private readonly IPlatformUserRepository _platformUserRepository;
        private readonly ITenantRepository _tenantRepository;
        private readonly IOrgRepository _orgRepository;
        private readonly IHttpContextAccessor _httpContextAccessor;
        public DiTuiAPIService(
            IPlatformUserRepository platformUserRepository,
            AppConfig appConfig,
            ITenantRepository tenantRepository,
            IHttpContextAccessor httpContextAccessor,
            IOrgRepository orgRepository
            )
        {
            _platformUserRepository = platformUserRepository;
            _appConfig = appConfig;
            _tenantRepository = tenantRepository;
            _httpContextAccessor = httpContextAccessor;
            _orgRepository = orgRepository;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        [AllowAnonymous]
        [NoOprationLog]
        public async Task<dynamic> LoginAsync(LoginInput input)
        {
            using (_platformUserRepository.DataFilter.DisableAll())
            {
                var sw = new Stopwatch();
                sw.Start();

                #region 验证码校验

                //if (_appConfig.VarifyCode.Enable)
                //{
                //    if (input.CaptchaId.IsNull() || input.CaptchaData.IsNull())
                //    {
                //        throw ResultOutput.Exception("请完成安全验证");
                //    }
                //    var validateResult = _captcha.Validate(input.CaptchaId, JsonConvert.DeserializeObject<SlideTrack>(input.CaptchaData));
                //    if (validateResult.Result != ValidateResultType.Success)
                //    {
                //        throw ResultOutput.Exception($"安全{validateResult.Message}，请重新登录");
                //    }
                //}

                #endregion

                #region 密码解密

                //if (input.PasswordKey.NotNull())
                //{
                //    var passwordEncryptKey = CacheKeys.PassWordEncrypt + input.PasswordKey;
                //    var existsPasswordKey = await Cache.ExistsAsync(passwordEncryptKey);
                //    if (existsPasswordKey)
                //    {
                //        var secretKey = await Cache.GetAsync(passwordEncryptKey);
                //        if (secretKey.IsNull())
                //        {
                //            throw ResultOutput.Exception("解密失败");
                //        }
                //        input.Password = DesEncrypt.Decrypt(input.Password, secretKey);
                //        await Cache.DelAsync(passwordEncryptKey);
                //    }
                //    else
                //    {
                //        throw ResultOutput.Exception("解密失败");
                //    }
                //}

                #endregion

                #region 登录
                var user = await _platformUserRepository.Select.Where(a => a.Phone == input.mobile).ToOneAsync();
                var valid = user?.Id > 0;
                if (valid)
                {
                    var password = MD5Encrypt.Encrypt32(input.pwd);
                    valid = user.Password == password;
                }

                if (!valid)
                {
                    throw ResultOutput.Exception("用户名或密码错误");
                }

                //if (!user.Enabled)
                //{
                //    throw ResultOutput.Exception("账号已停用，禁止登录");
                //}
                #endregion

                #region 获得token
                var authLoginOutput = Mapper.Map<AuthLoginOutput>(user);
                if (_appConfig.Tenant)
                {
                    var tenant = await _tenantRepository.Select.WhereDynamic(user.TenantId).ToOneAsync<AuthLoginTenantDto>();
                    if (!(tenant != null && tenant.Enabled))
                    {
                        throw ResultOutput.Exception("企业已停用，禁止登录");
                    }
                    authLoginOutput.Tenant = tenant;
                }
                authLoginOutput.UserName = authLoginOutput.Name;

                string token = GetToken(authLoginOutput);
                #endregion

                sw.Stop();

                #region 添加登录日志

                //var loginLogAddInput = new LoginLogAddInput
                //{
                //    TenantId = authLoginOutput.TenantId,
                //    Name = authLoginOutput.Name,
                //    ElapsedMilliseconds = sw.ElapsedMilliseconds,
                //    Status = true,
                //    CreatedUserId = authLoginOutput.Id,
                //    CreatedUserName = user.UserName,
                //};

                //await LazyGetRequiredService<ILoginLogService>().AddAsync(loginLogAddInput);

                #endregion 添加登录日志

                return new { token };
            }
            throw new NotImplementedException();
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        [NoOprationLog]
        [AdminTransaction]
        public virtual async Task<long> RegisterAsync(RegisterInput input)
        {
            var platform = _httpContextAccessor.HttpContext.Request.Headers["platform"];

            if (string.IsNullOrEmpty(input.InvitCode))
            {
                throw ResultOutput.Exception($"邀请码不可为空");
            }
            var org = await _orgRepository.Select.Where(a=> a.Code == platform).DisableGlobalFilter()
                .FirstAsync(a => new { a.Name, a.TenantId });

            Expression<Func<PlatformUserEntity, bool>> where = (a => a.Phone == input.Phone);
            where = where.Or(input.Phone.NotNull(), a => a.Phone == input.Phone)
                .Or(input.Name.NotNull(), a => a.Name == input.Name);

            var existsUser = await _platformUserRepository.Select.Where(where).DisableGlobalFilter().Where(a => a.TenantId == org.TenantId)
                .FirstAsync(a => new { a.Name, a.Phone, a.TenantId });

            
            //fsql.Select<TestAddEnum>().DisableGlobalFilter().ToList();
            var parentUser = await _platformUserRepository.Select.Where(a =>a.TenantId == org.TenantId && a.InviteCode == input.InvitCode).DisableGlobalFilter()
                .ToOneAsync();
                //.FirstAsync(a => new { a.Name, a.Phone, a.TenantId, a.Id,a.ParentId });

            if (parentUser == null)
            {
                throw ResultOutput.Exception($"未找到邀请人，请确认邀请码:not match");
            }

            if (existsUser != null)
            {
                // 可能会有重名用户
                //if (existsUser.Name == input.Name)
                //{
                //    throw ResultOutput.Exception($"账号已存在");
                //}

                if (input.Phone.NotNull() && existsUser.Phone == input.Phone)
                {
                    throw ResultOutput.Exception($"手机号已存在");
                }

                //if (input.Name.NotNull() && existsUser.Name == input.Name)
                //{
                //    throw ResultOutput.Exception($"姓名已存在");
                //}
            }

            // 用户信息
            if (input.Password.IsNull())
            {
                input.Password = _appConfig.DefaultPassword;
            }

            var entity = Mapper.Map<PlatformUserEntity>(input);
            //entity.Type = UserType.DefaultUser;
        
            entity.Password = MD5Encrypt.Encrypt32(input.Password);
            // 注册口注册用户皆为下级角色
            entity.Role = "2";
            entity.ParentId = parentUser.ParentId + parentUser.Id + "_";
            entity.TenantId = parentUser.TenantId;

            var user = await _platformUserRepository.InsertAsync(entity);
            var userId = user.Id;

            //用户角色
            //if (input.RoleIds != null && input.RoleIds.Any())
            //{
            //    var roles = input.RoleIds.Select(roleId => new UserRoleEntity
            //    {
            //        UserId = userId,
            //        RoleId = roleId
            //    }).ToList();
            //    await _userRoleRepository.InsertAsync(roles);
            //}

            // 员工信息
            //var staff = input.Staff == null ? new UserStaffEntity() : Mapper.Map<UserStaffEntity>(input.Staff);
            //staff.Id = userId;
            //await _staffRepository.InsertAsync(staff);

            ////所属部门
            //if (input.OrgIds != null && input.OrgIds.Any())
            //{
            //    var orgs = input.OrgIds.Select(orgId => new UserOrgEntity
            //    {
            //        UserId = userId,
            //        OrgId = orgId
            //    }).ToList();
            //    await _userOrgRepository.InsertAsync(orgs);
            //}

            return userId;
        }

        /// <summary>
        /// 获得token
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        private string GetToken(AuthLoginOutput user)
        {
            if (user == null)
            {
                return string.Empty;
            }

            var token = LazyGetRequiredService<IUserToken>().Create(new[]
            {
            new Claim(ClaimAttributes.UserId, user.Id.ToString(), ClaimValueTypes.Integer64),
            new Claim(ClaimAttributes.UserName, user.UserName),
            new Claim(ClaimAttributes.Name, user.Name),
            new Claim(ClaimAttributes.UserType, user.Type.ToInt().ToString(), ClaimValueTypes.Integer32),
            new Claim(ClaimAttributes.TenantId, user.TenantId.ToString(), ClaimValueTypes.Integer64),
            new Claim(ClaimAttributes.TenantType, user.Tenant?.TenantType.ToInt().ToString(), ClaimValueTypes.Integer32),
            new Claim(ClaimAttributes.DbKey, user.Tenant?.DbKey??"")
        });

            return token;
        }


    }
}
