using AutoFixture;
using Hotline.Api.Controllers;
using Hotline.Identity.Accounts;
using Hotline.Identity.Roles;
using Hotline.Settings;
using Hotline.Share.Dtos.Snapshot;
using Hotline.Share.Tools;
using Hotline.Users;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using XF.Domain.Repository;
using Hotline.Settings;
using XF.Domain.Cache;
using Hotline.ThirdAccountDomainServices.Interfaces;
using Hotline.ThirdAccountDomainServices;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Snapshot.IRepository;
using Hotline.Application.Snapshot.Contracts;
using Hotline.Application.Snapshot;

namespace Hotline.Tests.Application;
public class IndustryApplicationTest : TestBase
{
    private readonly IIndustryApplication _industryApplication;
    private readonly IIndustryRepository _industryRepository;
    private readonly ISystemOrganizeRepository _systemOrganizeRepository;

    public IndustryApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IIndustryApplication industryApplication, IIndustryRepository industryRepository, ISystemOrganizeRepository systemOrganizeRepository, ITypedCache<SystemSetting> cacheSettingData, ThirdAccounSupplierFactory thirdAccountDomainFactory, IServiceProvider serviceProvider) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData, thirdAccountDomainFactory, serviceProvider)
    {
        _industryApplication = industryApplication;
        _industryRepository = industryRepository;
        _systemOrganizeRepository = systemOrganizeRepository;
    }

    [Fact]
    public async Task GetVolunteerReportItems_Test()
    {
        var inDto = new VolunteerReportItemsInDto(null, null);
        var items = await _industryApplication.GetVolunteerReportItems(inDto).ToListAsync();
        items.ShouldNotBeNull();
    }

    [Fact]
    public async Task GetIndustryDetail_Test()
    {
        var industry = await _industryApplication.GetIndustres(new IndustryListInDto("电气焊", null)).FirstAsync();
        var detail = await _industryApplication.GetIndustryDetailAsync(industry.Id, CancellationToken.None);
        detail.Name.ShouldNotBeNull();
    }

    [Fact]
    public async Task UpdateIndustry_Test()
    {
        var industryItems = _industryApplication.GetIndustres(new IndustryListInDto(null, null)).ToList();
        industryItems.NotNullOrEmpty().ShouldBeTrue("行业集合为空");
        var industry = industryItems.First().Adapt<UpdateIndustryInDto>();
        var item = await _industryRepository.GetAsync(industry.Id);
        industry.ForeachClassProperties(async (industry, property, name, value) =>
        {
            if (name.ToUpper() == "ID") return true;
            if (value is String)
                industry.GetType().GetProperty(name).SetValue(industry, value + DateTime.Now.ToString("ss"));
            return true;
        });
        var orgs = await _systemOrganizeRepository.GetOrgEnabled();
        industry.ApproveOrgId = orgs.First().Key;
        industry.ApproveOrgName = null;
        industry.IsPoints = false;
        await _industryApplication.UpdateIndustryAsync(industry, CancellationToken.None);
        var updateIndustry = await _industryApplication.GetIndustryDetailAsync(item.Id, CancellationToken.None);
        updateIndustry.ForeachClassProperties(async (industry, property, name, value) =>
        {
            industry.GetType().GetProperty(name).GetValue(industry).ShouldBe(value);
            return true;
        });
        updateIndustry.IsPoints.ShouldBe(false);
        await _industryApplication.UpdateIndustryAsync(item.Adapt<UpdateIndustryInDto>(), CancellationToken.None);
        var changeItem = await _industryRepository.GetAsync(industry.Id);
        changeItem.ModuleCode.ShouldNotBeNull();
    }

    [Fact]
    public async Task IndustryCase_Test()
    {
        var industry = await _industryApplication.GetIndustres(new IndustryListInDto(null, null)).ToListAsync();
        var industryCase = new AddIndustryCaseDto
        {
            IndustryId = industry.First().Id,
            Name = "单元测试" + DateTime.Now.ToString("ss"),
            CitizenReadPackAmount = 10,
            GuiderReadPackAmount = 10,
            IsEnable = true,
            DisplayOrder = 1
        };
        var caseId = await _industryApplication.AddIndustryCaseAsync(industryCase);
        var items = await _industryApplication.GetIndustryCaseItems(new IndustryCaseItemInDto(null, null)).ToListAsync();
        items.Count.ShouldNotBe(0);
        items.Any(m => m.Id.IsNullOrEmpty()).ShouldBeFalse();
        items.Any(m => m.Name.IsNullOrEmpty()).ShouldBeFalse();

        var caseEntity = await _industryApplication.GetIndustryCaseAsync(caseId);
        var updateDto = caseEntity.Adapt<UpdateIndustryCaseDto>();
        updateDto.DisplayOrder = 2;
        await _industryApplication.UpdateIndustryCaseAsync(updateDto);
        var caseEntityUpdate = await _industryApplication.GetIndustryCaseAsync(caseId);
        caseEntityUpdate.DisplayOrder.ShouldBe(updateDto.DisplayOrder);
        caseEntityUpdate.Name.ShouldBe(updateDto.Name);
    }

    /// <summary>
    /// 新增行业短信模板
    /// 行业短信模板集合
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task SMSTemplate_Test()
    {
        var industryItems = await _industryApplication.GetIndustres(new IndustryListInDto(null, null)).ToListAsync();
        var industry = industryItems.First();
        var inDto = _fixture.Create<AddSnapshotSMSTemplateInDto>();
        inDto.IndustryId = industry.Id;
        var smsId = await _industryApplication.AddSMSTemplateAsync(inDto);
        var items = await _industryApplication.GetSMSTemplates(new SnapshotSMSTemplateItemsInDto(null)).ToListAsync();
        items.Count.ShouldNotBe(0);
        var sms = items.Where(m => m.Id == smsId).First();
        sms.Content.ShouldBe(inDto.Content);
        sms.IndustryName.ShouldNotBeNullOrEmpty();
        sms.IsEnable.ShouldBe(inDto.IsEnable);
    }
}
