using AutoFixture;
using Hotline.Api.Controllers;
using Hotline.Application.Tests.Infrastructure;
using Hotline.Identity.Accounts;
using Hotline.Identity.Roles;
using Hotline.Share.Dtos.Users;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.User;
using Hotline.Users;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using XF.Domain.Repository;

namespace Hotline.Application.Tests;
public class TestBase
{
    public readonly IAccountRepository _accountRepository;
    public readonly IRepository<User> _userRepository;
    public readonly IRepository<Role> _roleRepository;
    public readonly UserController _userController;
    public readonly IFixture _fixture;
    private readonly IServiceScopeFactory _scopeFactory;

    public TestBase(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository)
    {
        _fixture = new Fixture();
        _accountRepository = accountRepository;
        _roleRepository = roleRepository;
        _userController = userController;
        _userController.ControllerContext = new ControllerContext
        {
            HttpContext = new DefaultHttpContext()
        };
        _scopeFactory = scopeFactory;
        _userRepository = userRepository;
    }

    public void SetPaiDanYuan()
    {
        SetOperator("派单员", "市民热线服务中心", "单元测试派单员", "001", "13408389849", EUserType.Normal, TestSettingConstants.PaiDanYuanAccountName);
    }

    public void Set一级部门()
    {
        SetOperator("部门经办人", "测试部门", "测试", "001094", "13408389849", EUserType.Seat, TestSettingConstants.FirstOrgAccountName);
    }

    public void Set二级部门()
    {
        SetOperator("部门经办人", "测试部门/测试二级部门", "cs21", "001094001", "13408389849", EUserType.Seat, TestSettingConstants.SecondOrgAccountName);
    }

    public void Set班长()
    {
        SetOperator("中心班长", "市民热线服务中心", "单元测试班长", "001", "13408389849", EUserType.Normal, TestSettingConstants.BanZhangAccountName);
    }

    public void SetZuoXi()
    {
        SetOperator("坐席", "市民热线服务中心", "单元测试派单员", "001", "13408389849", EUserType.Seat, TestSettingConstants.PaiDanYuanAccountName);
    }

    private void SetOperator(string displayName, string fullOrgName, string name, string orgId, string phoneNo, EUserType userType, string userName)
    {
        var account = _accountRepository.GetExtAsync(
            d => d.UserName == userName,
            d => d.Includes(x => x.Roles)).GetAwaiter().GetResult();

        if (account == null)
        {
            var roleId = _roleRepository.Queryable()
                .Where(m => m.DisplayName == displayName)
                .Select(m => m.Id)
                .First();
            var newUser = new AddUserDto
            {
                FullOrgName = fullOrgName,
                Gender = EGender.Male,
                Name = name,
                OrgId = orgId,
                PhoneNo = phoneNo,
                RoleIds = new[] { roleId },
                UserType = userType,
                UserName = userName
            };
            var accountId = _userController.Add(newUser).GetAwaiter().GetResult();
            TestSessionConstants.UserId = accountId;
            account = _accountRepository.GetExtAsync(
                d => d.UserName == userName,
                d => d.Includes(x => x.Roles)).GetAwaiter().GetResult();
        }
        var user = _userRepository.GetAsync(account.Id).GetAwaiter().GetResult();
        TestSessionConstants.UserId = account.Id;
        TestSessionConstants.Roles = account.Roles.Select(m => m.Id).ToArray();
        TestSessionConstants.UserName = account.UserName;
        TestSessionConstants.OrgId = user.OrgId;
    }
}
