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

namespace Tiku.Domain.Growth;

public sealed class ReferralTrack : AuditableTenantEntity
{
    public Guid? LeadId { get; set; }
    public Guid? ReferrerUserId { get; set; }
    public Guid? TargetUserId { get; set; }
    public string? LegacyId { get; set; }
    public string EventType { get; set; } = string.Empty;
    public string? RefCode { get; set; }
    public string? Source { get; set; }
    public string? IpAddress { get; set; }
    public string? UserAgent { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class ReferralCode : AuditableTenantEntity
{
    public Guid UserId { get; set; }
    public string Code { get; set; } = string.Empty;
    public ReferralCodeStatus Status { get; set; } = ReferralCodeStatus.Active;
    public string? Channel { get; set; }
    public string? LandingPath { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class ReferralLead : AuditableTenantEntity
{
    public Guid StudentUserId { get; set; }
    public Guid? ReferrerUserId { get; set; }
    public Guid? FirstTrackId { get; set; }
    public Guid? AssignedToUserId { get; set; }
    public Guid? AssignedBy { get; set; }
    public string? RefCode { get; set; }
    public string? Source { get; set; }
    public ReferralLeadBindType BindType { get; set; } = ReferralLeadBindType.FirstTouch;
    public ReferralLeadStatus Status { get; set; } = ReferralLeadStatus.Protected;
    public DateTimeOffset? ProtectedUntil { get; set; }
    public ReferralAssignmentMode? AssignmentMode { get; set; }
    public DateTimeOffset? AssignedAt { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset BoundAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class ReferralTeamEdge : AuditableTenantEntity
{
    public Guid MemberUserId { get; set; }
    public Guid? LeaderUserId { get; set; }
    public ReferralTeamRelationType RelationType { get; set; } = ReferralTeamRelationType.SalesTeam;
    public ReferralTeamEdgeStatus Status { get; set; } = ReferralTeamEdgeStatus.Active;
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class ReferralQrcode : AuditableTenantEntity
{
    public Guid? UserId { get; set; }
    public string RefCode { get; set; } = string.Empty;
    public string Scene { get; set; } = string.Empty;
    public string Page { get; set; } = "pages/index/index";
    public string Provider { get; set; } = "wechat-miniapp";
    public string? QrcodeUrl { get; set; }
    public ReferralQrcodeStatus Status { get; set; } = ReferralQrcodeStatus.Pending;
    public string? ErrorMessage { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class CrmConfig : AuditableTenantEntity
{
    public bool Enabled { get; set; }
    public string? Url { get; set; }
    public string? SecretRef { get; set; }
    public string? FormName { get; set; }
    public string? ExamType { get; set; }
    public int? TimeoutSeconds { get; set; }
    public int? DelaySeconds { get; set; }
    public ReferralAssignmentMode AssignmentMode { get; set; } = ReferralAssignmentMode.None;
    public JsonElement AssignmentPool { get; set; } = JsonDefaults.Array();
    public int AssignmentCursor { get; set; }
    public JsonElement AssignmentConfig { get; set; } = JsonDefaults.Object();
}

public sealed class CrmWebhookQueueItem : AuditableTenantEntity
{
    public string? LegacyId { get; set; }
    public string? RecordId { get; set; }
    public string? LeadId { get; set; }
    public string? Source { get; set; }
    public string? Provider { get; set; }
    public CrmWebhookQueueStatus Status { get; set; } = CrmWebhookQueueStatus.Pending;
    public DateTimeOffset? ScheduledAt { get; set; }
    public int Attempts { get; set; }
    public DateTimeOffset? NextAttemptAt { get; set; }
    public DateTimeOffset? LastAttemptAt { get; set; }
    public string? LastError { get; set; }
    public int? LastHttpCode { get; set; }
    public string? LastResponseSummary { get; set; }
    public DateTimeOffset? SentAt { get; set; }
    public string? IdempotencyKey { get; set; }
    public string? TargetUrl { get; set; }
    public JsonElement Payload { get; set; } = JsonDefaults.Object();
}

public sealed class CrmWebhookLog : AuditableTenantEntity
{
    public string? LegacyId { get; set; }
    public string? RecordId { get; set; }
    public string? LeadId { get; set; }
    public int? HttpCode { get; set; }
    public string? Outcome { get; set; }
    public string? ErrorMessage { get; set; }
    public string? RequestBody { get; set; }
    public JsonElement RequestPayload { get; set; } = JsonDefaults.Object();
    public string? ResponseSummary { get; set; }
    public DateTimeOffset? SignedAt { get; set; }
    public int? Attempt { get; set; }
}

public sealed class TenantCommissionSetting : AuditableTenantEntity
{
    public decimal DefaultRate { get; set; } = 0.2m;
    public int MinSettlementCents { get; set; }
    public CommissionSettlementCycle SettlementCycle { get; set; } = CommissionSettlementCycle.Monthly;
    public JsonElement Config { get; set; } = JsonDefaults.Object();
    public Guid? UpdatedBy { get; set; }
}

public sealed class CommissionSettlement : AuditableTenantEntity
{
    public Guid ReferrerUserId { get; set; }
    public Guid? GeneratedBy { get; set; }
    public Guid? ReviewedBy { get; set; }
    public Guid? PaidBy { get; set; }
    public string SettlementNo { get; set; } = string.Empty;
    public CommissionSettlementStatus Status { get; set; } = CommissionSettlementStatus.Draft;
    public DateOnly PeriodStart { get; set; }
    public DateOnly PeriodEnd { get; set; }
    public int SourceCount { get; set; }
    public int PaidUserCount { get; set; }
    public int GrossAmountCents { get; set; }
    public int CommissionAmountCents { get; set; }
    public decimal DefaultRate { get; set; }
    public decimal? EffectiveRate { get; set; }
    public DateTimeOffset? ReviewedAt { get; set; }
    public DateTimeOffset? PaidAt { get; set; }
    public string? PaymentMethod { get; set; }
    public string? PaymentAccount { get; set; }
    public string? Remark { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class CommissionSettlementItem : AuditableTenantEntity
{
    public Guid? SettlementId { get; set; }
    public Guid ReferrerUserId { get; set; }
    public Guid? StudentUserId { get; set; }
    public CommissionSourceType SourceType { get; set; } = CommissionSourceType.Order;
    public Guid SourceId { get; set; }
    public string? SourceNo { get; set; }
    public DateTimeOffset? SourcePaidAt { get; set; }
    public int GrossAmountCents { get; set; }
    public decimal CommissionRate { get; set; }
    public int CommissionAmountCents { get; set; }
    public CommissionRateSource RateSource { get; set; } = CommissionRateSource.Default;
    public string AttributionType { get; set; } = "protected_lead";
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class CommissionSettlementProof : AuditableTenantEntity
{
    public Guid SettlementId { get; set; }
    public Guid? AssetId { get; set; }
    public Guid? SubmittedBy { get; set; }
    public Guid? ReviewedBy { get; set; }
    public CommissionProofType ProofType { get; set; } = CommissionProofType.Payment;
    public CommissionProofStatus Status { get; set; } = CommissionProofStatus.Submitted;
    public string? Title { get; set; }
    public string? Description { get; set; }
    public string? ExternalUrl { get; set; }
    public int? AmountCents { get; set; }
    public string? PaymentMethod { get; set; }
    public string? PaymentAccount { get; set; }
    public DateTimeOffset? PaidAt { get; set; }
    public DateTimeOffset? ReviewedAt { get; set; }
    public string? ReviewNote { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class CommissionSettlementExportEvent : Entity, ITenantOwned
{
    public Guid SettlementId { get; set; }
    public Guid? ExportedBy { get; set; }
    public string ExportFormat { get; set; } = "csv";
    public string Filename { get; set; } = string.Empty;
    public int RowCount { get; set; }
    public string? ContentSha256 { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public enum ReferralCodeStatus
{
    Active,
    Disabled
}

public enum ReferralLeadBindType
{
    FirstTouch,
    Manual,
    Imported
}

public enum ReferralLeadStatus
{
    Protected,
    Invalid,
    Released
}

public enum ReferralAssignmentMode
{
    None,
    Direct,
    RoundRobin,
    Referrer
}

public enum ReferralTeamRelationType
{
    SalesTeam,
    AgentNetwork,
    TeacherClass
}

public enum ReferralTeamEdgeStatus
{
    Active,
    Disabled
}

public enum ReferralQrcodeStatus
{
    Pending,
    Ready,
    Failed,
    Disabled
}

public enum CrmWebhookQueueStatus
{
    Pending,
    Processing,
    Retrying,
    Sent,
    Failed,
    Discarded
}

public enum CommissionSettlementCycle
{
    Manual,
    Weekly,
    Monthly
}

public enum CommissionSettlementStatus
{
    Draft,
    PendingReview,
    Approved,
    Paid,
    Rejected,
    Cancelled
}

public enum CommissionSourceType
{
    Order,
    ActivationCode
}

public enum CommissionRateSource
{
    Batch,
    Member,
    Default
}

public enum CommissionProofType
{
    Payment,
    Invoice,
    Receipt,
    Adjustment,
    Other
}

public enum CommissionProofStatus
{
    Submitted,
    Approved,
    Rejected,
    Voided
}