using JetBrains.Annotations;
using NPin.Framework.SqlSugarCore.Abstractions;
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.Data;
using Volo.Abp.MultiTenancy;

namespace NPin.Framework.TenantManagement.Domain;

/// <summary>
/// 实现TenantStore
/// </summary>
public class SqlSugarTenantStore: ITenantStore
{
    private ISqlSugarTenantRepository TenantRepository { get; }
    protected ICurrentTenant CurrentTenant { get; }
    protected IDistributedCache<TenantCacheItem> Cache { get; }

    public SqlSugarTenantStore(ISqlSugarTenantRepository tenantRepository, ICurrentTenant currentTenant, IDistributedCache<TenantCacheItem> cache)
    {
        TenantRepository = tenantRepository;
        CurrentTenant = currentTenant;
        Cache = cache;
    }


    public Task<TenantConfiguration?> FindAsync(string name)
    {
        throw new NotImplementedException();
    }

    public Task<TenantConfiguration?> FindAsync(Guid id)
    {
        throw new NotImplementedException();
    }

    protected virtual async Task<TenantCacheItem> GetCacheItemAsync(Guid? id, string name)
    {
        var cacheKey = CalculateCacheKey(id, name);
        var cacheItem = await Cache.GetAsync(cacheKey, considerUow: true);
        if (cacheItem != null)
        {
            return cacheItem;
        }

        if (id.HasValue)
        {
            using (CurrentTenant.Change(null))
            {
                var tenant = await TenantRepository.FindAsync(id.Value);
                return await SetCacheAsync(cacheKey, tenant);
            }
        }

        if (!name.IsNullOrWhiteSpace())
        {
            using (CurrentTenant.Change(null))
            {
                var tenant = await TenantRepository.FindByNameAsync(name);
                return await SetCacheAsync(cacheKey, tenant);
            }
        }

        throw new AbpException("Id和Name不能都为空");
    }
    
    protected virtual async Task<TenantCacheItem> SetCacheAsync(string cacheKey, TenantAggregateRoot? tenant)
    {
        var tenantConfiguration = tenant != null ? MapToConfiguration(tenant) : null;
        var cacheItem = new TenantCacheItem(tenantConfiguration);
        await Cache.SetAsync(cacheKey, cacheItem, considerUow: true);
        return cacheItem;
    }
    
    private TenantConfiguration MapToConfiguration(TenantAggregateRoot tenantAggregateRoot)
    {
        var tenantConfiguration = new TenantConfiguration
        {
            Id = tenantAggregateRoot.Id,
            Name = tenantAggregateRoot.Name,
            ConnectionStrings = MapToString(tenantAggregateRoot.TenantConnectionString),
            IsActive = true
        };
        return tenantConfiguration;
    }
    
    private ConnectionStrings? MapToString(string tenantConnectionString)
    {

        //tenantConnectionString = tenantConnectionString.TrimEnd(';');
        //var strSpiteds = tenantConnectionString.Split(";");
        //if (strSpiteds.Count() == 0)
        //{
        //    return null;

        //}

        var connectionStrings = new ConnectionStrings();
        //foreach (string strSpited in strSpiteds)
        //{
        //    var key = strSpited.Split('=')[0];
        //    var value = strSpited.Split('=')[1];
        //    connectionStrings[key] = value;
        //}
        connectionStrings["test"] = tenantConnectionString;

        return connectionStrings;
    }
    
    protected virtual string CalculateCacheKey(Guid? id, string name)
    {
        return TenantCacheItem.CalculateCacheKey(id, name);
    }

    public TenantConfiguration? Find(string name)
    {
        throw new NotImplementedException("请使用异步方法");
    }

    public TenantConfiguration? Find(Guid id)
    {
        throw new NotImplementedException("请使用异步方法");
    }
}