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

namespace Tiku.Domain.Platform;

public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned
{
    public string? BillingName { get; set; }
    public string? TaxId { get; set; }
    public string? ContactName { get; set; }
    public string? ContactPhone { get; set; }
    public string? ContactEmail { get; set; }
    public string? BillingAddress { get; set; }
    public string? InvoiceTitle { get; set; }
    public TenantBillingInvoiceTitleType? InvoiceType { get; set; }
    public string? BankName { get; set; }
    public string? BankAccountMasked { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class TenantBillingPolicy : IHasTimestamps, ITenantOwned
{
    public TenantBillingCollectionMode CollectionMode { get; set; } = TenantBillingCollectionMode.Online;
    public string DefaultPaymentProvider { get; set; } = "manual";
    public bool AutoGenerateRenewal { get; set; } = true;
    public int RenewalLeadDays { get; set; } = 14;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class TenantOwnerActivationGrant : AuditableTenantEntity
{
    public Guid UserId { get; set; }
    public Guid CreatedBy { get; set; }
    public Guid? DomainId { get; set; }
    public string TokenHash { get; set; } = string.Empty;
    public DateTimeOffset ExpiresAt { get; set; }
    public DateTimeOffset? ConsumedAt { get; set; }
    public DateTimeOffset? RevokedAt { get; set; }
    public Guid? RevokedBy { get; set; }
    public string? RevocationReason { get; set; }
}

public sealed class PlatformOperationIdempotency : AuditableEntity
{
    public Guid ActorUserId { get; set; }
    public string Scope { get; set; } = string.Empty;
    public string IdempotencyKey { get; set; } = string.Empty;
    public string RequestHash { get; set; } = string.Empty;
    public Guid ResourceId { get; set; }
}

public sealed class PlatformBillingInvoiceReminder : AuditableTenantEntity
{
    public Guid InvoiceId { get; set; }
    public Guid? CreatedBy { get; set; }
    public PlatformBillingInvoiceReminderType ReminderType { get; set; } = PlatformBillingInvoiceReminderType.Overdue;
    public PlatformBillingInvoiceReminderChannel Channel { get; set; } = PlatformBillingInvoiceReminderChannel.Manual;
    public PlatformBillingInvoiceReminderStatus Status { get; set; } = PlatformBillingInvoiceReminderStatus.Pending;
    public DateOnly ReminderDate { get; set; }
    public int ReminderLevel { get; set; } = 1;
    public DateOnly? DueDate { get; set; }
    public int BalanceCentsSnapshot { get; set; }
    public string? Message { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset? SentAt { get; set; }
    public DateTimeOffset? AcknowledgedAt { get; set; }
}

public sealed class PlatformAuditAlertRule : AuditableEntity
{
    public Guid? TenantId { get; set; }
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
    public bool Enabled { get; set; } = true;
    public PlatformAlertSeverity Severity { get; set; } = PlatformAlertSeverity.Medium;
    public string[] ActionPatterns { get; set; } = [];
    public string[] TargetTypes { get; set; } = [];
    public JsonElement Conditions { get; set; } = JsonDefaults.Object();
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformAuditAlert : AuditableEntity
{
    public Guid RuleId { get; set; }
    public Guid AuditLogId { get; set; }
    public Guid? TenantId { get; set; }
    public Guid? AcknowledgedBy { get; set; }
    public Guid? ResolvedBy { get; set; }
    public PlatformAlertSeverity Severity { get; set; } = PlatformAlertSeverity.Medium;
    public PlatformAuditAlertStatus Status { get; set; } = PlatformAuditAlertStatus.Open;
    public string Action { get; set; } = string.Empty;
    public string? TargetType { get; set; }
    public string? TargetId { get; set; }
    public string Title { get; set; } = string.Empty;
    public string? Summary { get; set; }
    public JsonElement Details { get; set; } = JsonDefaults.Object();
    public DateTimeOffset FirstSeenAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset LastSeenAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? AcknowledgedAt { get; set; }
    public DateTimeOffset? ResolvedAt { get; set; }
    public string? ResolutionNote { get; set; }
}

public sealed class PlatformBillingDunningNotificationChannel : AuditableEntity
{
    public string ChannelCode { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
    public bool Enabled { get; set; } = true;
    public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;
    public string WebhookUrl { get; set; } = string.Empty;
    public string? SecretRef { get; set; }
    public string[] ReminderTypes { get; set; } = ["overdue", "final_notice"];
    public string[] ReminderChannels { get; set; } = ["internal"];
    public int MinReminderLevel { get; set; } = 1;
    public Guid[] TenantIds { get; set; } = [];
    public int TimeoutSeconds { get; set; } = 10;
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformBillingDunningNotificationEvent : AuditableTenantEntity
{
    public Guid ChannelId { get; set; }
    public Guid ReminderId { get; set; }
    public Guid InvoiceId { get; set; }
    public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;

    public PlatformBillingDunningNotificationStatus Status { get; set; } =
        PlatformBillingDunningNotificationStatus.Pending;

    public int Attempts { get; set; }
    public DateTimeOffset ScheduledAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? NextAttemptAt { get; set; }
    public DateTimeOffset? LastAttemptAt { get; set; }
    public DateTimeOffset? SentAt { get; set; }
    public string? LastError { get; set; }
    public int? LastHttpCode { get; set; }
    public string? LastResponseSummary { get; set; }
    public JsonElement RequestPayload { get; set; } = JsonDefaults.Object();
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformPaymentApp : AuditableEntity
{
    public string AppCode { get; set; } = string.Empty;
    public string AppName { get; set; } = string.Empty;
    public PlatformPaymentAppStatus Status { get; set; } = PlatformPaymentAppStatus.Disabled;
    public string SettlementMode { get; set; } = "PlatformCollect";
    public string? Description { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformPaymentChannel : AuditableEntity
{
    public Guid AppId { get; set; }
    public string Provider { get; set; } = "manual";
    public string Mode { get; set; } = "PlatformCollect";
    public PlatformPaymentChannelStatus Status { get; set; } = PlatformPaymentChannelStatus.Disabled;
    public string DisplayName { get; set; } = string.Empty;
    public string? SecretRef { get; set; }
    public string? CallbackPath { get; set; }
    public int Priority { get; set; } = 100;
    public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object();
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public enum PlatformBillingCycle
{
    Monthly,
    Quarterly,
    Yearly,
    OneTime
}

public enum TenantBillingInvoiceTitleType
{
    None,
    NormalVat,
    SpecialVat
}

public enum PlatformBillingInvoiceReminderType
{
    DueSoon,
    Overdue,
    FinalNotice,
    Manual
}

public enum PlatformBillingInvoiceReminderChannel
{
    Manual,
    Internal,
    Sms,
    Email,
    Wechat,
    Crm
}

public enum PlatformBillingInvoiceReminderStatus
{
    Pending,
    Sent,
    Acknowledged,
    Dismissed,
    Failed
}

public enum PlatformAlertSeverity
{
    Low,
    Medium,
    High,
    Critical
}

public enum PlatformAuditAlertStatus
{
    Open,
    Acknowledged,
    Resolved,
    Ignored
}

public enum PlatformBillingDunningProvider
{
    Generic,
    Dingtalk,
    Feishu,
    Wecom
}

public enum PlatformBillingDunningNotificationStatus
{
    Pending,
    Processing,
    Sent,
    Retrying,
    Failed,
    Discarded,
    Acknowledged,
    Ignored
}

public enum PlatformPaymentAppStatus
{
    Active,
    Disabled,
    Testing
}

public enum PlatformPaymentChannelStatus
{
    Active,
    Disabled,
    Testing
}

public enum TenantBillingCollectionMode
{
    Online,
    Manual
}