using System.Text.Json;
using Tiku.Domain.Growth;
using Tiku.Domain.Platform;
using Tiku.Domain.Tenancy;
using Tiku.Application.Tenancy;

namespace Tiku.Application.PlatformAdmin;

public sealed record PlatformCapabilityActor(Guid UserId);
public sealed record PlatformCapabilityQuery(Guid? TenantId = null, string? Status = null, int Limit = 100);

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

public sealed record UpsertPlatformCrmConfigCommand(
    Guid? Id,
    Guid TenantId,
    bool Enabled,
    string? Url,
    string? SecretRef,
    string? FormName,
    string? ExamType,
    int? TimeoutSeconds,
    int? DelaySeconds,
    string? AssignmentMode,
    JsonElement? AssignmentPool,
    JsonElement? AssignmentConfig);

public sealed record PlatformCrmLeadRetryCommand(Guid QueueId, string? Note);
public sealed record PlatformTenantCapabilityList<T>(IReadOnlyCollection<T> Items);

public interface IPlatformCrmAdminService
{
    Task<PlatformTenantCapabilityList<PlatformCrmConfigItem>> GetConfigsAsync(PlatformCapabilityActor actor, PlatformCapabilityQuery query, CancellationToken cancellationToken = default);
    Task<PlatformCrmConfigItem> UpsertConfigAsync(PlatformCapabilityActor actor, UpsertPlatformCrmConfigCommand command, CancellationToken cancellationToken = default);
    Task<PlatformTenantCapabilityList<CrmWebhookQueueItem>> GetLeadsAsync(PlatformCapabilityActor actor, PlatformCapabilityQuery query, CancellationToken cancellationToken = default);
    Task<CrmWebhookQueueItem> RetryLeadAsync(PlatformCapabilityActor actor, PlatformCrmLeadRetryCommand command, CancellationToken cancellationToken = default);
    Task<PlatformTenantCapabilityList<CrmWebhookLog>> GetLogsAsync(PlatformCapabilityActor actor, Guid? tenantId, Guid? queueId, int limit, CancellationToken cancellationToken = default);
}

public sealed record PlatformSmsChannelItem(
    Guid Id,
    Guid TenantId,
    string TenantName,
    string Provider,
    string Name,
    string Signature,
    string Scene,
    TenantExternalProviderStatus Status,
    string? SecretRef,
    int Priority,
    int MonthlyQuota,
    int SentThisMonth,
    JsonElement ConfigPublic,
    JsonElement Metadata,
    DateTimeOffset UpdatedAt);

public sealed record UpsertPlatformSmsChannelCommand(
    Guid? Id,
    Guid TenantId,
    string Provider,
    string Name,
    string Signature,
    string Scene,
    TenantExternalProviderStatus Status,
    string? SecretRef,
    int? Priority,
    int? MonthlyQuota,
    JsonElement ConfigPublic,
    JsonElement Metadata);

public sealed record PlatformSmsTemplateItem(
    Guid Id,
    Guid TenantId,
    string TenantName,
    Guid ChannelId,
    string ChannelName,
    string Code,
    string Name,
    SmsTemplateType Type,
    SmsTemplateAuditStatus AuditStatus,
    SmsTemplateStatus Status,
    string? ProviderTemplateCode,
    string Content,
    string? Remark,
    int SentCount,
    int FailedCount,
    DateTimeOffset UpdatedAt);

public sealed record UpsertPlatformSmsTemplateCommand(
    Guid? Id,
    Guid TenantId,
    Guid ChannelId,
    string Code,
    string Name,
    SmsTemplateType Type,
    SmsTemplateAuditStatus AuditStatus,
    SmsTemplateStatus Status,
    string? ProviderTemplateCode,
    string Content,
    string? Remark,
    JsonElement Metadata);

public interface IPlatformSmsAdminService
{
    Task<PlatformTenantCapabilityList<PlatformSmsChannelItem>> GetChannelsAsync(PlatformCapabilityActor actor, PlatformCapabilityQuery query, CancellationToken cancellationToken = default);
    Task<PlatformSmsChannelItem> UpsertChannelAsync(PlatformCapabilityActor actor, UpsertPlatformSmsChannelCommand command, CancellationToken cancellationToken = default);
    Task<PlatformSmsChannelItem> DisableChannelAsync(PlatformCapabilityActor actor, Guid channelId, CancellationToken cancellationToken = default);
    Task<PlatformTenantCapabilityList<PlatformSmsTemplateItem>> GetTemplatesAsync(PlatformCapabilityActor actor, PlatformCapabilityQuery query, CancellationToken cancellationToken = default);
    Task<PlatformSmsTemplateItem> UpsertTemplateAsync(PlatformCapabilityActor actor, UpsertPlatformSmsTemplateCommand command, CancellationToken cancellationToken = default);
    Task<PlatformSmsTemplateItem> SubmitTemplateReviewAsync(PlatformCapabilityActor actor, Guid templateId, CancellationToken cancellationToken = default);
    Task<PlatformSmsTemplateItem> DisableTemplateAsync(PlatformCapabilityActor actor, Guid templateId, CancellationToken cancellationToken = default);
    Task<PlatformTenantCapabilityList<SmsSendLog>> GetLogsAsync(PlatformCapabilityActor actor, PlatformCapabilityQuery query, CancellationToken cancellationToken = default);
}

public sealed record UpsertPlatformPaymentAppCommand(
    Guid? Id,
    string AppCode,
    string AppName,
    PlatformPaymentAppStatus Status,
    string SettlementMode,
    string? Description,
    JsonElement Metadata);

public sealed record UpsertPlatformPaymentChannelCommand(
    Guid? Id,
    Guid AppId,
    string Provider,
    string Mode,
    PlatformPaymentChannelStatus Status,
    string DisplayName,
    string? SecretRef,
    string? CallbackPath,
    int? Priority,
    JsonElement ConfigPublic,
    JsonElement Metadata);

public sealed record PlatformRebateSummary(int GrossAmountCents, int CommissionAmountCents, int PendingSettlementCents, int PaidSettlementCents, int ExceptionCount);

public interface IPlatformPaymentSettingsService
{
    Task<IReadOnlyCollection<PlatformPaymentApp>> GetAppsAsync(PlatformCapabilityActor actor, string? status, int limit, CancellationToken cancellationToken = default);
    Task<PlatformPaymentApp> UpsertAppAsync(PlatformCapabilityActor actor, UpsertPlatformPaymentAppCommand command, CancellationToken cancellationToken = default);
    Task<IReadOnlyCollection<PlatformPaymentChannel>> GetChannelsAsync(PlatformCapabilityActor actor, Guid? appId, string? status, int limit, CancellationToken cancellationToken = default);
    Task<PlatformPaymentChannel> UpsertChannelAsync(PlatformCapabilityActor actor, UpsertPlatformPaymentChannelCommand command, CancellationToken cancellationToken = default);
    Task<PlatformPaymentChannel> DisableChannelAsync(PlatformCapabilityActor actor, Guid channelId, CancellationToken cancellationToken = default);
    Task<IReadOnlyCollection<PlatformBillingPaymentEvent>> GetEventsAsync(PlatformCapabilityActor actor, string? status, int limit, CancellationToken cancellationToken = default);
    Task<PlatformRebateSummary> GetRebateSummaryAsync(PlatformCapabilityActor actor, CancellationToken cancellationToken = default);
}

public interface IPlatformTenantPaymentAdminService
{
    Task<PlatformTenantCapabilityList<TenantExternalProviderItem>> GetAppsAsync(PlatformCapabilityActor actor, PlatformCapabilityQuery query, CancellationToken cancellationToken = default);
    Task<TenantExternalProviderItem> UpsertAppAsync(PlatformCapabilityActor actor, Guid tenantId, UpsertTenantExternalProviderCommand command, CancellationToken cancellationToken = default);
    Task<PlatformTenantCapabilityList<object>> GetEventsAsync(PlatformCapabilityActor actor, PlatformCapabilityQuery query, CancellationToken cancellationToken = default);
}

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