using Fengling.Console.Models.Entities;
using Fengling.Console.Stores;
using Microsoft.AspNetCore.Identity;

namespace Fengling.Console.Managers;

public interface ITenantManager
{
    Task<Tenant?> FindByIdAsync(int tenantId, CancellationToken cancellationToken = default);
    Task<Tenant?> FindByTenantCodeAsync(string tenantCode, CancellationToken cancellationToken = default);
    Task<IList<Tenant>> GetAllAsync(CancellationToken cancellationToken = default);
    Task<IList<Tenant>> GetPagedAsync(int page, int pageSize, string? name = null, string? tenantCode = null, TenantStatus? status = null, CancellationToken cancellationToken = default);
    Task<int> GetCountAsync(string? name = null, string? tenantCode = null, TenantStatus? status = null, CancellationToken cancellationToken = default);
    Task<IdentityResult> CreateAsync(Tenant tenant, CancellationToken cancellationToken = default);
    Task<IdentityResult> UpdateAsync(Tenant tenant, CancellationToken cancellationToken = default);
    Task<IdentityResult> DeleteAsync(Tenant tenant, CancellationToken cancellationToken = default);
    Task<int> GetUserCountAsync(int tenantId, CancellationToken cancellationToken = default);
    Task<IdentityResult> SetTenantCodeAsync(Tenant tenant, string code, CancellationToken cancellationToken = default);
}

public class TenantManager : ITenantManager
{
    private readonly ITenantStore<Tenant> _store;

    public TenantManager(ITenantStore<Tenant> store)
    {
        _store = store;
    }

    public virtual async Task<Tenant?> FindByIdAsync(int tenantId, CancellationToken cancellationToken = default)
    {
        return await _store.FindByIdAsync(tenantId, cancellationToken);
    }

    public virtual async Task<Tenant?> FindByTenantCodeAsync(string tenantCode, CancellationToken cancellationToken = default)
    {
        return await _store.FindByTenantCodeAsync(tenantCode, cancellationToken);
    }

    public virtual async Task<IList<Tenant>> GetAllAsync(CancellationToken cancellationToken = default)
    {
        return await _store.GetAllAsync(cancellationToken);
    }

    public virtual async Task<IList<Tenant>> GetPagedAsync(int page, int pageSize, string? name = null, 
        string? tenantCode = null, TenantStatus? status = null, CancellationToken cancellationToken = default)
    {
        return await _store.GetPagedAsync(page, pageSize, name, tenantCode, status, cancellationToken);
    }

    public virtual async Task<int> GetCountAsync(string? name = null, string? tenantCode = null, 
        TenantStatus? status = null, CancellationToken cancellationToken = default)
    {
        return await _store.GetCountAsync(name, tenantCode, status, cancellationToken);
    }

    public virtual async Task<IdentityResult> CreateAsync(Tenant tenant, CancellationToken cancellationToken = default)
    {
        return await _store.CreateAsync(tenant, cancellationToken);
    }

    public virtual async Task<IdentityResult> UpdateAsync(Tenant tenant, CancellationToken cancellationToken = default)
    {
        return await _store.UpdateAsync(tenant, cancellationToken);
    }

    public virtual async Task<IdentityResult> DeleteAsync(Tenant tenant, CancellationToken cancellationToken = default)
    {
        return await _store.DeleteAsync(tenant, cancellationToken);
    }

    public virtual async Task<int> GetUserCountAsync(int tenantId, CancellationToken cancellationToken = default)
    {
        return await _store.GetUserCountAsync(tenantId, cancellationToken);
    }

    public virtual async Task<IdentityResult> SetTenantCodeAsync(Tenant tenant, string code, CancellationToken cancellationToken = default)
    {
        var existing = await _store.FindByTenantCodeAsync(code, cancellationToken);
        if (existing != null && existing.Id != tenant.Id)
        {
            return IdentityResult.Failed(new IdentityError { Description = "租户编码已存在" });
        }
        
        await _store.SetTenantCodeAsync(tenant, code, cancellationToken);
        return IdentityResult.Success;
    }
}
