using System.Text.Json;

namespace Tiku.Application.Growth;

public sealed record CrmAdminActor(Guid TenantId, Guid UserId);

public sealed record UpsertCrmConfigCommand(
    bool Enabled,
    string? Url,
    string? SecretRef,
    string? Secret,
    string? FormName,
    string? ExamType,
    int? TimeoutSeconds,
    int? DelaySeconds,
    string? AssignmentMode,
    JsonElement? AssignmentPool,
    JsonElement? AssignmentConfig);

public sealed record CrmQueueQuery(string? Status = null, Guid? QueueId = null, string? Source = null, int? Limit = null);

public sealed record CrmQueueLogQuery(Guid? QueueId = null, int? Limit = null);

public sealed record CrmQueueActionCommand(Guid QueueId, string? Action, string? Note, JsonElement? Metadata);

public sealed record CrmConfigItem(
    Guid Id,
    bool Enabled,
    string? Url,
    string? SecretRef,
    string AssignmentMode,
    JsonElement AssignmentPool,
    string? FormName,
    string? ExamType,
    int? TimeoutSeconds,
    int? DelaySeconds,
    DateTimeOffset UpdatedAt);

public sealed record CrmQueueItem(
    Guid Id,
    string Status,
    int Attempts,
    string? LeadId,
    string? RecordId,
    string? Source,
    string? Provider,
    string? LastError,
    DateTimeOffset? ScheduledAt,
    DateTimeOffset? NextAttemptAt,
    JsonElement Payload);

public sealed record CrmQueueLogItem(
    Guid Id,
    Guid? QueueId,
    string? RecordId,
    string? LeadId,
    int? HttpCode,
    string Outcome,
    string? ErrorMessage,
    string? Operation,
    JsonElement RequestPayload,
    string? ResponseSummary,
    DateTimeOffset CreatedAt);

public sealed record CrmDeadLetterSummary(int Failed, int Discarded, int Total, DateTimeOffset? OldestOpenAt);

public sealed record CrmDeadLetterResult(CrmDeadLetterSummary Summary, IReadOnlyCollection<CrmQueueItem> Items);

public sealed record CrmList<T>(IReadOnlyCollection<T> Items);

public interface ICrmService
{
    Task<CrmConfigItem> GetConfigAsync(CrmAdminActor actor, CancellationToken cancellationToken = default);

    Task<CrmConfigItem> UpsertConfigAsync(
        CrmAdminActor actor,
        UpsertCrmConfigCommand command,
        CancellationToken cancellationToken = default);

    Task<CrmList<CrmQueueItem>> GetQueueAsync(
        CrmAdminActor actor,
        CrmQueueQuery query,
        CancellationToken cancellationToken = default);

    Task<CrmDeadLetterResult> GetDeadLettersAsync(
        CrmAdminActor actor,
        CrmQueueQuery query,
        CancellationToken cancellationToken = default);

    Task<CrmList<CrmQueueLogItem>> GetLogsAsync(
        CrmAdminActor actor,
        CrmQueueLogQuery query,
        CancellationToken cancellationToken = default);

    Task<CrmQueueItem> ApplyQueueActionAsync(
        CrmAdminActor actor,
        CrmQueueActionCommand command,
        CancellationToken cancellationToken = default);
}

public sealed class CrmException(string message, string code) : Exception(message)
{
    public string Code { get; } = code;
}
