using ColaFlow.Modules.Mcp.Domain.Entities;
using ColaFlow.Modules.Mcp.Domain.ValueObjects;

namespace ColaFlow.Modules.Mcp.Domain.Repositories;

/// <summary>
/// Repository interface for PendingChange aggregate root
/// </summary>
public interface IPendingChangeRepository
{
    /// <summary>
    /// Get a pending change by ID
    /// </summary>
    Task<PendingChange?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// Get all pending changes for a tenant
    /// </summary>
    Task<IReadOnlyList<PendingChange>> GetByTenantAsync(
        Guid tenantId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Get pending changes by status
    /// </summary>
    Task<IReadOnlyList<PendingChange>> GetByStatusAsync(
        Guid tenantId,
        PendingChangeStatus status,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Get expired pending changes (still in PendingApproval status but past expiration time)
    /// </summary>
    Task<IReadOnlyList<PendingChange>> GetExpiredAsync(
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Get pending changes by API key
    /// </summary>
    Task<IReadOnlyList<PendingChange>> GetByApiKeyAsync(
        Guid apiKeyId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Get pending changes for a specific entity
    /// </summary>
    Task<IReadOnlyList<PendingChange>> GetByEntityAsync(
        Guid tenantId,
        string entityType,
        Guid entityId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Check if there are any pending changes for a specific entity
    /// </summary>
    Task<bool> HasPendingChangesForEntityAsync(
        Guid tenantId,
        string entityType,
        Guid entityId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Add a new pending change
    /// </summary>
    Task AddAsync(PendingChange pendingChange, CancellationToken cancellationToken = default);

    /// <summary>
    /// Update an existing pending change
    /// </summary>
    Task UpdateAsync(PendingChange pendingChange, CancellationToken cancellationToken = default);

    /// <summary>
    /// Delete a pending change
    /// </summary>
    Task DeleteAsync(PendingChange pendingChange, CancellationToken cancellationToken = default);

    /// <summary>
    /// Save changes to the database
    /// </summary>
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
