using System.Text.Json;
using Tiku.Domain.Platform;

namespace Tiku.Application.PlatformAdmin;

public sealed record PagedQuery(
    int Page = 1,
    int PageSize = 50,
    string? Search = null,
    string? SortBy = null,
    bool Descending = true)
{
    public int SafePage => Math.Max(1, Page);
    public int SafePageSize => Math.Clamp(PageSize, 1, 200);
}

public sealed record PagedResult<T>(IReadOnlyCollection<T> Items, int Total, int Page, int PageSize);

public sealed record PlatformConfigurationDefinitionItem(
    Guid Id,
    string Code,
    string Name,
    string Category,
    PlatformConfigurationValueType ValueType,
    bool AllowRuntimeManagement,
    bool IsSensitive,
    string? Description,
    JsonElement ValidationSchema);

public sealed record PlatformConfigurationVersionItem(
    Guid Id,
    Guid DefinitionId,
    string Environment,
    int Version,
    PlatformConfigurationVersionStatus Status,
    JsonElement? Value,
    string? SecretRef,
    Guid CreatedBy,
    Guid? PublishedBy,
    Guid? RolledBackFromVersionId,
    string Reason,
    DateTimeOffset? PublishedAt,
    DateTimeOffset CreatedAt);

public sealed record SavePlatformConfigurationDraftCommand(
    string DefinitionCode,
    string Environment,
    JsonElement? Value,
    string? SecretRef,
    string Reason);

public sealed record PlatformNotificationTemplateItem(
    Guid Id,
    string Code,
    string Name,
    PlatformNotificationChannel Channel,
    string SubjectTemplate,
    string BodyTemplate,
    bool Enabled,
    JsonElement Variables,
    DateTimeOffset UpdatedAt);

public sealed record UpsertPlatformNotificationTemplateCommand(
    Guid? Id,
    string Code,
    string Name,
    PlatformNotificationChannel Channel,
    string SubjectTemplate,
    string BodyTemplate,
    bool Enabled,
    JsonElement Variables);

public sealed record SendPlatformNotificationCommand(
    Guid TemplateId,
    IReadOnlyCollection<string> RoleCodes,
    IReadOnlyDictionary<string, string> Variables,
    string IdempotencyKey);

public sealed record PlatformNotificationDeliveryItem(
    Guid Id,
    Guid TemplateId,
    Guid RecipientUserId,
    string RecipientRoleCode,
    PlatformNotificationChannel Channel,
    PlatformNotificationDeliveryStatus Status,
    string Subject,
    string Body,
    int Attempts,
    string? LastError,
    DateTimeOffset? SentAt,
    DateTimeOffset CreatedAt);

public interface IPlatformGovernanceService
{
    Task<IReadOnlyCollection<PlatformConfigurationDefinitionItem>> GetConfigurationDefinitionsAsync(
        PlatformApprovalActor actor, CancellationToken cancellationToken = default);

    Task<IReadOnlyCollection<PlatformConfigurationVersionItem>> GetConfigurationVersionsAsync(
        PlatformApprovalActor actor, string definitionCode, string? environment,
        CancellationToken cancellationToken = default);

    Task<PlatformConfigurationVersionItem> SaveConfigurationDraftAsync(PlatformApprovalActor actor,
        SavePlatformConfigurationDraftCommand command, CancellationToken cancellationToken = default);

    Task<PlatformConfigurationVersionItem> PublishConfigurationAsync(PlatformApprovalActor actor, Guid versionId,
        CancellationToken cancellationToken = default);

    Task<PlatformConfigurationVersionItem> RollbackConfigurationAsync(PlatformApprovalActor actor, Guid versionId,
        string reason, CancellationToken cancellationToken = default);

    Task<PagedResult<PlatformNotificationDeliveryItem>> GetNotificationDeliveriesAsync(PlatformApprovalActor actor,
        PagedQuery query, PlatformNotificationDeliveryStatus? status, CancellationToken cancellationToken = default);

    Task<IReadOnlyCollection<PlatformNotificationTemplateItem>> GetNotificationTemplatesAsync(
        PlatformApprovalActor actor, CancellationToken cancellationToken = default);

    Task<PlatformNotificationTemplateItem> UpsertNotificationTemplateAsync(PlatformApprovalActor actor,
        UpsertPlatformNotificationTemplateCommand command, CancellationToken cancellationToken = default);

    Task<IReadOnlyCollection<PlatformNotificationDeliveryItem>> SendNotificationAsync(PlatformApprovalActor actor,
        SendPlatformNotificationCommand command, CancellationToken cancellationToken = default);

    Task<PlatformNotificationDeliveryItem> RetryNotificationAsync(PlatformApprovalActor actor, Guid deliveryId,
        CancellationToken cancellationToken = default);
}