using Hotline.Identity.Accounts;
using Hotline.Settings;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Users;
using IdentityModel;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using XF.Domain.Authentications;
using XF.Domain.Dependency;
using XF.Domain.Repository;

namespace Hotline.Authentications;
public class ChangeSessionProvider : IChangeSessionProvider, IScopeDependency
{
    private readonly IServiceProvider _serviceProvider;

    public ChangeSessionProvider(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public HttpContext ChangeSessionByUserId(string id, HttpContext httpContext)
    {
        if (httpContext == null) 
        {
            httpContext = new DefaultHttpContext();
        }
        var userRepository = _serviceProvider.GetService<IRepository<User>>();
        var accountRepository = _serviceProvider.GetService<IAccountRepository>();
        var user = userRepository.Queryable().Where(m => m.Id == id).First();
        if (user == null) return null;
        var account = accountRepository.GetExtAsync(m => m.Id == user.Id, m => m.Includes(x => x.Roles)).GetAwaiter().GetResult();

        List<Claim> userClaims = [
            new(JwtClaimTypes.Subject, account.Id),
                new(JwtClaimTypes.PhoneNumber, account.PhoneNo ?? string.Empty),
                new(ClaimTypes.NameIdentifier, user.Id),
                new(AppClaimTypes.UserDisplayName, account.Name),
                new(AppClaimTypes.DepartmentId, user.OrgId ?? string.Empty),
                new(AppClaimTypes.DepartmentIsCenter, user.Organization?.IsCenter.ToString() ?? string.Empty),
                new(AppClaimTypes.DepartmentName, user.Organization?.Name ?? string.Empty),
                new(AppClaimTypes.DepartmentAreaCode, user.Organization?.AreaCode ?? string.Empty),
                new(AppClaimTypes.DepartmentAreaName, user.Organization?.AreaName ?? string.Empty),
                new(AppClaimTypes.DepartmentLevel, user.Organization?.Level.ToString() ?? string.Empty),
                new(AppClaimTypes.AreaId, user.OrgId?.GetHigherOrgId() ?? string.Empty),
            ];
        userClaims.AddRange(account.Roles.Select(d => new Claim(JwtClaimTypes.Role, d.Name)));
        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
        return httpContext;
    }
}
