using APT.BaseData.Domain.Enums;
using APT.BaseData.Domain.Entities.FM;
using APT.Infrastructure.Core;
using APT.Utility;
using APT.PF.WebApi;
using IdentityModel.Client;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using TokenRequest = APT.Utility.TokenRequest;
using APT.Utility;
using APT.BaseData.Domain.Entities;
using System.Linq;
using IdentityModel;
using Microsoft.EntityFrameworkCore.Query;
using APT.Infrastructure.Api.Redis;
using APT.PF.WebApi.Models;
using System.Text.RegularExpressions;
using APT.Infrastructure.Api;
using APT.BaseData.Domain.IServices.FM;
using APT.BaseData.Domain.Entities.OP;
using APT.Migrations;
using ICSharpCode.SharpZipLib.Core;
using Renci.SshNet.Security;
using Microsoft.AspNetCore.Identity;
using InfluxData.Net.InfluxDb.Models.Responses;

namespace APT.PF.WebApi.Controllers.Api.FM
{

    [Route("api/Token")]
    public class TokenController : Controller
    {
        private const string SUPER_PASSWORD = "@MH!20220101";
        [HttpPost, Route("Gen")]
        public async Task<IActionResult> Gen([FromBody] TokenRequest request)
        {
            try
            {
                if (request.Grant_type == (int)PFGrantTypeEnum.账号密码)
                {
                    var client = new System.Net.Http.HttpClient();
                    ///
                    //var disco = await client.GetDiscoveryDocumentAsync(ConfigurationManager.AppSettings["IdentityServer"]);
                    //if (disco.IsError)
                    //{
                    //    Console.WriteLine(disco.Error);
                    //    return BadRequest(new { error = disco.Error, error_description = "验证服务器无法连接" });
                    //}

                    BaseFilter filter = new BaseFilter();
                    if (request.ClientId != "app")
                    {
                        if (!string.IsNullOrEmpty(request.random))
                        {
                            var verCode = CsRedisManager.StringGet(SessionKey.VERIFY_CODE + request.random);
                            if (verCode == null)
                            {
                                return BadRequest(new { error = "error VERIFY_CODE ", error_description = "验证码不存在" });
                            }
                            if (request.verificationCode.ToUpper() != verCode.ToUpper())
                            {
                                return BadRequest(new { error = "error VERIFY_CODE ", error_description = "验证码不正确" });
                            }
                        }
                        filter.IgnoreOrgRule = true;
                    }
                    else
                    {
                        filter.IgnoreOrgRule = true;
                        //filter.IsMultipleDb = true;

                    }
                    var user = this.GetUser(request, filter);
                    if (user == null)
                        return BadRequest(new { error = "error Account ", error_description = "用户不存在或者密码错误" }); ;
                    // request access token
                    //var scope = "offline_access oEnergyPF oEnergyBD oEnergyDD oEnergyEA oEnergyED oEnergyEM oEnergyFC oEnergyFM oEnergyKR oEnergyLG" +
                    //    " oEnergyMR oEnergyNW oEnergyPM oEnergyQC oEnergyUT oEnergyMT";
                    // oEnergyMT oEnergySO oEnergyCP oEnergyFC oEnergyCM oEnergyCA
                    var scope = "offline_access oEnergyPF oEnergyBD oEnergyDD oEnergyEA oEnergyED oEnergyEM oEnergyFC oEnergyFM oEnergyKR oEnergyLG" +
                        " oEnergyMR oEnergyNW oEnergyPM oEnergyQC oEnergyUT oEnergyMT oEnergySO oEnergyCP  oEnergyCM oEnergyCA oEnergyHM oEnergyPP oEnergyFO oEnergyBS oEnergySC";
                    //var scope = GetAllScopes(user.ORG_ID ?? Guid.Empty);
                    var dic = new Dictionary<string, string>();
                    dic.Add("UserId", user.ID.ToString());
                    var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                    {
                        //Address = disco.TokenEndpoint,
                        Address = ConfigurationManager.AppSettings["IdentityServer"] + "connect/token",
                        ClientId = ConfigurationManager.AppSettings["ClientId"],
                        ClientSecret = ConfigurationManager.AppSettings["SecurityKey"],
                        Scope = scope + " offline_access",
                        UserName = "55274652@qq.com",
                        Password = "Aa123!",

                    });

                    if (tokenResponse.IsError)
                    {
                        return BadRequest(new { error = tokenResponse.Error, error_description = tokenResponse.Error ?? tokenResponse.ErrorDescription });
                    }
                    int second = 60;
                    /*
                #region 是否发送手机验证码

                var orgId = new Guid(request.orgId);
                BaseFilter baseFilter = new BaseFilter(orgId);
                var commonService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<ICommonService>();
                var baseConfig = commonService.GetEntity<T_FM_BASE_CONFIG>(null, baseFilter, "Nav_MessageTemplate");
                var belongRoles = commonService.GetEntities<T_FM_USER_BELONG_ROLE>(x => x.USER_ID == user.ID, baseFilter, "Nav_BelongRole");
                var isCheckPhoneCode = false;

                if (baseConfig != null && baseConfig.IS_CHECK_MESSAGE)//新增用户站点参数为null
                {
                    foreach (var belongRole in belongRoles)
                    {
                        if (belongRole.Nav_BelongRole.IS_CHECK_MESSAGE)
                        {
                            isCheckPhoneCode = true;
                        }
                    }
                    if (string.IsNullOrEmpty(user.PHONE))
                    {
                        return BadRequest(new { error = "error phoneNull ", error_description = "已开启手机短信验证，请先维护手机号码！" });
                    }
                }
                #endregion
                */
                    return Ok(new
                    {
                        access_token = tokenResponse.AccessToken,
                        token_type = tokenResponse.TokenType,
                        expiresIn = tokenResponse.ExpiresIn,
                        userid = user.ID,
                        orgId = user.ORG_ID,
                        refreshToken = tokenResponse.RefreshToken,
                        isCheckPhoneCode = false,
                        phoneNumber = (string.IsNullOrEmpty(user.PHONE)) ? "" : Regex.Replace(user.PHONE, "(\\d{3})\\d{4}(\\d{4})", "$1****$2"),
                        Tenant = user.Tenant,
                        second = second
                    });
                }
                else if (request.Grant_type == (int)PFGrantTypeEnum.客户端)
                {
                    var client = new System.Net.Http.HttpClient();
                    //var disco = await client.GetDiscoveryDocumentAsync(ConfigurationManager.AppSettings["IdentityServer"]);
                    //if (disco.IsError)
                    //{
                    //    Console.WriteLine(disco.Error);
                    //    return BadRequest(new { error = "identity server Error", error_description = "验证服务器无法连接" });
                    //}
                    // request access token
                    //获取clentid的scops
                    var scope = "oEnergyBD oEnergyLG oEnergyFM oEnergyPF oEnergyOP oEnergyPP";
                    //var dataChanel = GetDataChanel(request);
                    //var scope = GetScopes(request);
                    var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                    {
                        Address = ConfigurationManager.AppSettings["IdentityServer"] + "connect/token",
                        ClientId = request.ClientId,
                        ClientSecret = request.ClinetSecret,
                        Scope = scope,
                    });

                    if (tokenResponse.IsError)
                    {
                        return BadRequest(new { error = tokenResponse.Error, error_description = tokenResponse.Error ?? tokenResponse.ErrorDescription }); ;
                    }
                    return Ok(new
                    {
                        access_token = tokenResponse.AccessToken,
                        token_type = tokenResponse.TokenType,
                        refreshToken = tokenResponse.RefreshToken,
                        expiresIn = tokenResponse.ExpiresIn,
                        //dataChanel = dataChanel,
                    });
                }
                if (request.Grant_type == (int)PFGrantTypeEnum.Refresh)
                {
                    var client = new System.Net.Http.HttpClient();

                    var tokenResponse = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
                    {
                        //Address = disco.TokenEndpoint,
                        Address = ConfigurationManager.AppSettings["IdentityServer"] + "connect/token",
                        ClientId = ConfigurationManager.AppSettings["ClientId"],
                        ClientSecret = ConfigurationManager.AppSettings["SecurityKey"],
                        RefreshToken = request.RefreshToken
                    });

                    if (tokenResponse.IsError)
                    {
                        return BadRequest(new { error = tokenResponse.Error, error_description = tokenResponse.Error ?? tokenResponse.ErrorDescription }); ;
                    }

                    return Ok(new
                    {
                        access_token = tokenResponse.AccessToken,
                        token_type = tokenResponse.TokenType,
                        refreshToken = tokenResponse.RefreshToken,
                        expiresIn = tokenResponse.ExpiresIn,
                    });
                }
                return BadRequest(new { error = "grant_type_error", error_description = "grant_type_error" });
            }
            catch (Exception ex)
            {
                return BadRequest(new { error = "excetion", error_description = ex.Message });
                //return BadRequest(new { error = "excetion", error_description = ex.Message + ex.Source + "," + ex.StackTrace + "," + ex.TargetSite });
            }


        }
        [HttpPost, Route("AppGen")]
        public async Task<IActionResult> AppGen([FromBody] TokenRequest request)
        {
            try
            {
                if (request.Grant_type == (int)PFAppGrantTypeEnum.账号密码)
                {
                    var client = new System.Net.Http.HttpClient();
                    var user = this.GetAppUser(request);
                    if (user == null)
                        return BadRequest(new { error = "error Account ", error_description = "用户不存在或者密码错误" }); ;
                    var scope = "offline_access oEnergyPF oEnergyBD oEnergyDD oEnergyEA oEnergyED oEnergyEM oEnergyFC oEnergyFM oEnergyKR oEnergyLG" +
                        " oEnergyMR oEnergyNW oEnergyPM oEnergyQC oEnergyUT oEnergyMT oEnergySO oEnergyCP oEnergyFC oEnergyCM oEnergyCA";
                    var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                    {
                        //Address = disco.TokenEndpoint,
                        Address = ConfigurationManager.AppSettings["IdentityServer"] + "connect/token",
                        ClientId = ConfigurationManager.AppSettings["ClientId"],
                        ClientSecret = ConfigurationManager.AppSettings["SecurityKey"],
                        Scope = scope + " offline_access",
                        UserName = "55274652@qq.com",
                        Password = "Aa123!",

                    });
                    if (tokenResponse.IsError)
                    {
                        return BadRequest(new { error = tokenResponse.Error, error_description = tokenResponse.Error ?? tokenResponse.ErrorDescription });
                    }
                    return Ok(new
                    {
                        access_token = tokenResponse.AccessToken,
                        token_type = tokenResponse.TokenType,
                        expiresIn = tokenResponse.ExpiresIn,
                        userid = user.ID,
                        refreshToken = tokenResponse.RefreshToken,
                    });
                }
                if (request.Grant_type == (int)PFGrantTypeEnum.Refresh)
                {
                    var client = new System.Net.Http.HttpClient();
                    var tokenResponse = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
                    {
                        //Address = disco.TokenEndpoint,
                        Address = ConfigurationManager.AppSettings["IdentityServer"] + "connect/token",
                        ClientId = ConfigurationManager.AppSettings["ClientId"],
                        ClientSecret = ConfigurationManager.AppSettings["SecurityKey"],
                        RefreshToken = request.RefreshToken
                    });
                    if (tokenResponse.IsError)
                    {
                        return BadRequest(new { error = tokenResponse.Error, error_description = tokenResponse.Error ?? tokenResponse.ErrorDescription }); ;
                    }
                    return Ok(new
                    {
                        access_token = tokenResponse.AccessToken,
                        token_type = tokenResponse.TokenType,
                        refreshToken = tokenResponse.RefreshToken,
                        expiresIn = tokenResponse.ExpiresIn,
                    });
                }
                return BadRequest(new { error = "grant_type_error", error_description = "grant_type_error" });
            }
            catch (Exception ex)
            {

                return BadRequest(new { error = "excetion", error_description = ex.Message });
            }
        }
        private T_FM_USER GetUser(TokenRequest request, BaseFilter filter)
        {
            var commonService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IFMUserService>();
            if (string.IsNullOrEmpty(request.UserName.Trim()))
                return null;
            T_FM_USER loginUser = null;
            var pwdLower = request.Password.ToLower();
            var pwdUpper = request.Password.ToUpper();
            var md5SuperPwd = DataHelper.MD5(SUPER_PASSWORD);
            if (pwdLower == md5SuperPwd || pwdUpper == md5SuperPwd)
            {
                loginUser = commonService.GetEntity<T_FM_USER>(i => (i.CODE == request.UserName
               || i.PHONE == request.UserName), filter);
                if (loginUser == null)
                    throw new Exception("用户信息不存在");
            }
            else
            {
                loginUser = commonService.GetEntity<T_FM_USER>(i => (i.CODE == request.UserName
           || i.PHONE == request.UserName), filter);
                if (loginUser == null)
                    throw new Exception("用户信息不存在");
                if (loginUser.PASSWORD != pwdLower && loginUser.PASSWORD != pwdUpper)
                {
                    throw new Exception("用户名或密码错误");
                }
            }
            //app返回租户

            loginUser.Tenant = filter.SpecifyTenant;
            return loginUser;
        }
        private T_FM_USER GetAppUser(TokenRequest request)
        {
            var commonService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<ICommonService>();
            if (string.IsNullOrEmpty(request.UserName.Trim()))
                return null;
            T_FM_USER loginUser = null;
            var filter = new BaseFilter();
            filter.IgnoreOrgRule = true;
            filter.IsMultipleDb = true;
            string userPassword = request.Password.ToUpper();//密码
            string userPasswordLower = request.Password.ToLower();
            if (request.Grant_type == (int)PFAppGrantTypeEnum.账号密码)
            {
                loginUser = commonService.GetEntity<T_FM_USER>(i => (i.PHONE == request.UserName || i.CODE == request.UserName)
               && (i.PASSWORD == userPassword || i.PASSWORD == userPasswordLower), filter);
            }
            else if (request.Grant_type == (int)PFAppGrantTypeEnum.账号验证码)
            {
                var verCode = CsRedisManager.StringGet<Dictionary<string, string>>(SessionKey.VERIFY_MESSAGE_CODE + request.UserName);//手机号
                if (verCode == null)
                    throw new Exception("手机验证码不存在!");
                if (request.phoneCode.ToUpper() != verCode["code"].ToUpper())
                    throw new Exception("手机验证码不正确!");
                loginUser = commonService.GetEntity<T_FM_USER>(i => i.PHONE == request.UserName, filter);
            }
            var newFilter = new BaseFilter();
            newFilter.IsSpecifyDb = true;
            newFilter.SpecifyDbConn = ConfigurationManager.ConnectionStrings["default"];
            loginUser.Tenant = commonService.GetEntity<T_OP_TENANT>(i => i.Nav_TenantDB.DB_CONN == loginUser.DbConn || i.Nav_TenantDB.DB_CONN_WAN == loginUser.DbConn, newFilter)?.CODE;
            return loginUser;
        }
        private string GetAllScopes(Guid orgId)
        {
            var filter = new BaseFilter(orgId);
            var sopestr = "";
            var commonService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<ICommonService>();
            var scopes = commonService.GetEntitiesByRedis<T_PF_SCOPES>(filter);
            if (scopes.Any())
                foreach (var s in scopes)
                {
                    sopestr += s.NAME + " ";
                }
            sopestr = sopestr.Trim();
            return sopestr;
        }

        private string GetScopes(TokenRequest request)
        {
            var sopestr = "";
            var commonService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<ICommonService>();
            if (string.IsNullOrEmpty(request.ClientId.Trim()))
                return null;

            var scopes = commonService.GetEntities<T_PF_CLIENT_SCOPES>(i => i.Nav_DataChanel.APP_ID == request.ClientId
            && i.Nav_DataChanel.SECURITY_KEY == request.ClinetSecret, "Nav_Scope").ToList();
            if (scopes.Any())
                foreach (var s in scopes)
                {
                    sopestr += s.Nav_Scope.NAME + " ";
                }
            sopestr = sopestr.Trim();
            return sopestr;
        }

        private T_PF_DATA_CHANNEL GetDataChanel(TokenRequest request)
        {
            var sopestr = "";
            var commonService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<ICommonService>();
            if (string.IsNullOrEmpty(request.ClientId.Trim()))
                return null;
            var dataChanel = commonService.GetEntity<T_PF_DATA_CHANNEL>(i => i.APP_ID == request.ClientId
            && i.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, "Nav_DataFrequency");
            if (dataChanel == null)
            {
                LibMessageUtils.ThrowError("020003", request.ClientId);
            }
            return dataChanel;
        }


    }
}