using DataSharing.RawData;
using IdentityModel;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using XF.Domain.Authentications;
using XF.Domain.Dependency;
using XF.Domain.Exceptions;
using XF.Domain.Options;
using XF.Domain.Repository;

namespace DataSharing.Application.Identity;

public class IdentityAppService : IIdentityAppService, IScopeDependency
{
    private readonly IRepository<DsUserTokenInfo> _accountRepository;
    private readonly IJwtSecurity _jwtSecurity;
    private readonly IOptionsSnapshot<IdentityConfiguration> _identityOptionsAccessor;

    public IdentityAppService(
        IRepository<DsUserTokenInfo> accountRepository,
        IJwtSecurity jwtSecurity,
        IOptionsSnapshot<IdentityConfiguration> identityOptionsAccessor
        )
    {
        _accountRepository = accountRepository;
        _jwtSecurity = jwtSecurity;
        _identityOptionsAccessor = identityOptionsAccessor;
    }

    public async Task<string> LoginAsync(LoginDto dto, CancellationToken cancellationToken)
    {
        var account = await _accountRepository.Queryable()
            .FirstAsync(d => d.AccountId == dto.Username && d.AccountSecret == dto.Password, cancellationToken);
        if (account == null)
            throw UserFriendlyException.SameMessage("用户名或密码错误！");

        if (account.State != "1")
            throw UserFriendlyException.SameMessage("账号被锁定！");

        ////限制系统类型账户频繁获取token的行为
        ////todo


        var jwtOptions = _identityOptionsAccessor.Value.Jwt;
        var claims = new List<Claim>
        {
            //new(JwtClaimTypes.Id, account.Id),
            new(JwtClaimTypes.Subject, account.Id),
            new(JwtClaimTypes.Scope, jwtOptions.Scope),
            new(AppClaimTypes.AccountId, account.AccountId),
            new(AppClaimTypes.PlatformSource, account.PlatformSource),
            new(AppClaimTypes.PlatformSourceName, account.PlatformSourceName),
        };

        var token = _jwtSecurity.EncodeJwtToken(claims);
        return token;
    }

    public async Task<GetTokenRequest> LoginTokenAsync(LoginDto dto, CancellationToken cancellationToken)
    {
        GetTokenRequest tokenRequest = new() { IsSuccess = false };

        if (true == string.IsNullOrWhiteSpace(dto.Username) || true == string.IsNullOrWhiteSpace(dto.Password))
        {
            tokenRequest.Message = "账号或密码不为空";
            return tokenRequest;
        }

        var account = await _accountRepository.Queryable().FirstAsync(d => d.AccountId == dto.Username && d.AccountSecret == dto.Password, cancellationToken);

        if (account == null)
        {
            tokenRequest.Message = "账号或密码错误！";
            return tokenRequest;
        }

        if (account.State != "1")
        {
            tokenRequest.Message = "账号被限制！";
            return tokenRequest;
        }

        ////限制系统类型账户频繁获取token的行为
        ////todo


        var jwtOptions = _identityOptionsAccessor.Value.Jwt;
        var claims = new List<Claim>
        {
            //new(JwtClaimTypes.Id, account.Id),
          new(JwtClaimTypes.Subject, account.Id),
            new(JwtClaimTypes.Scope, jwtOptions.Scope),
            new(AppClaimTypes.AccountId, account.AccountId),
            new(AppClaimTypes.PlatformSource, account.PlatformSource),
            new(AppClaimTypes.PlatformSourceName, account.PlatformSourceName),
        };

        var token = _jwtSecurity.EncodeJwtToken(claims);
        tokenRequest.IsSuccess = true;
        tokenRequest.Message = "获取成功";
        tokenRequest.Token = token;
        return tokenRequest;
    }
}