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

namespace Tiku.Domain.Operations;

public sealed class Banner : AuditableTenantEntity
{
    public Guid? RegionId { get; set; }
    public string? LegacyId { get; set; }
    public string? Title { get; set; }
    public string? Subtitle { get; set; }
    public string? Content { get; set; }
    public string? ButtonText { get; set; }
    public string? ButtonLink { get; set; }
    public string? BackgroundColor { get; set; }
    public string? BorderColor { get; set; }
    public int SortOrder { get; set; }
    public bool IsActive { get; set; } = true;
}

public sealed class Faq : AuditableTenantEntity
{
    public Guid? RegionId { get; set; }
    public string? LegacyId { get; set; }
    public string? Question { get; set; }
    public string? Answer { get; set; }
    public int SortOrder { get; set; }
    public bool IsActive { get; set; } = true;
}

public sealed class Announcement : AuditableTenantEntity
{
    public string? LegacyId { get; set; }
    public string? Content { get; set; }
    public string? Link { get; set; }
    public string? BackgroundColor { get; set; }
    public int SortOrder { get; set; }
    public bool IsActive { get; set; } = true;
}

public sealed class AuditLog : Entity
{
    public Guid? TenantId { get; set; }
    public Guid? ActorUserId { get; set; }
    public string Action { get; set; } = string.Empty;
    public string? TargetType { get; set; }
    public string? TargetId { get; set; }
    public JsonElement Details { get; set; } = JsonDefaults.Object();
    public string? IpAddress { get; set; }
    public string? UserAgent { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class BackendPermission : AuditableEntity
{
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public BackendPermissionArea Area { get; set; } = BackendPermissionArea.Tenant;
    public string PermissionModuleCode { get; set; } = string.Empty;
    public string? Description { get; set; }
    public bool IsSystem { get; set; } = true;
    public int SortOrder { get; set; } = 100;
}

public sealed class BackendMenu : AuditableEntity
{
    public string Code { get; set; } = string.Empty;
    public string? ParentCode { get; set; }
    public string Title { get; set; } = string.Empty;
    public BackendPermissionArea Area { get; set; } = BackendPermissionArea.Tenant;
    public string? Path { get; set; }
    public string? Icon { get; set; }
    public string? PermissionCode { get; set; }
    public int SortOrder { get; set; } = 100;
    public bool IsActive { get; set; } = true;
}

public sealed class TenantBackendRole : AuditableTenantEntity
{
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public BackendRoleStatus Status { get; set; } = BackendRoleStatus.Active;
    public bool IsSystem { get; set; }
    public string? Description { get; set; }
    public JsonElement DataScope { get; set; } = JsonDefaults.Object();
}

public sealed class TenantBackendRolePermission : Entity, ITenantOwned
{
    public Guid RoleId { get; set; }
    public string PermissionCode { get; set; } = string.Empty;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class TenantBackendRoleMenu : Entity, ITenantOwned
{
    public Guid RoleId { get; set; }
    public string MenuCode { get; set; } = string.Empty;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class TenantBackendUserRole : Entity, ITenantOwned
{
    public Guid UserId { get; set; }
    public Guid RoleId { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class PlatformBackendRole : AuditableEntity
{
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public BackendRoleStatus Status { get; set; } = BackendRoleStatus.Active;
    public bool IsSystem { get; set; }
    public string? Description { get; set; }
}

public sealed class PlatformBackendRolePermission : Entity
{
    public Guid RoleId { get; set; }
    public string PermissionCode { get; set; } = string.Empty;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class PlatformBackendRoleMenu : Entity
{
    public Guid RoleId { get; set; }
    public string MenuCode { get; set; } = string.Empty;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class PlatformBackendUserRole : Entity
{
    public Guid UserId { get; set; }
    public Guid RoleId { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class AuthorizationScopeVersion : AuditableEntity
{
    public AuthRealm Realm { get; set; }
    public Guid? TenantId { get; set; }
    public long Version { get; set; } = 1;
}

public sealed class AuthorizationCacheInvalidation : AuditableEntity
{
    public string TargetType { get; set; } = string.Empty;
    public Guid? TenantId { get; set; }
    public Guid? UserId { get; set; }
    public Guid? SessionId { get; set; }
    public AuthRealm? Realm { get; set; }
    public long? Version { get; set; }
    public DateTimeOffset? ProcessedAt { get; set; }
    public int AttemptCount { get; set; }
    public string? LastError { get; set; }
}

public sealed class BackgroundJob : AuditableTenantEntity
{
    public string JobType { get; set; } = string.Empty;
    public string? IdempotencyKey { get; set; }
    public BackgroundJobStatus Status { get; set; } = BackgroundJobStatus.Pending;
    public JsonElement Payload { get; set; } = JsonDefaults.Object();
    public int RetryCount { get; set; }
    public int MaxRetries { get; set; } = 3;
    public string? LockedBy { get; set; }
    public DateTimeOffset? LockExpiresAt { get; set; }
    public DateTimeOffset? RunAfter { get; set; }
    public DateTimeOffset? StartedAt { get; set; }
    public DateTimeOffset? CompletedAt { get; set; }
    public DateTimeOffset? CancellationRequestedAt { get; set; }
    public Guid? CancellationRequestedBy { get; set; }
    public string? CancellationReason { get; set; }
    public string? LastError { get; set; }
    public Guid? OutputAssetId { get; set; }
    public JsonElement Result { get; set; } = JsonDefaults.Object();
}

public sealed class TenantLifecycleOperation : AuditableTenantEntity
{
    public TenantLifecycleOperationType OperationType { get; set; }
    public TenantLifecycleOperationStatus Status { get; set; } = TenantLifecycleOperationStatus.Pending;
    public Guid RequestedBy { get; set; }
    public Guid? TargetUserId { get; set; }
    public Guid? ExportAssetId { get; set; }
    public string? Reason { get; set; }
    public string? LastError { get; set; }
    public JsonElement Result { get; set; } = JsonDefaults.Object();
    public DateTimeOffset? StartedAt { get; set; }
    public DateTimeOffset? CompletedAt { get; set; }
}

public sealed class WorkerHeartbeat : Entity
{
    public string WorkerId { get; set; } = string.Empty;
    public string Processor { get; set; } = string.Empty;
    public DateTimeOffset StartedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset LastHeartbeatAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? LastIterationStartedAt { get; set; }
    public DateTimeOffset? LastIterationCompletedAt { get; set; }
    public DateTimeOffset? LastSucceededAt { get; set; }
    public string? LastError { get; set; }
    public bool IsRunning { get; set; }
}

public sealed class UserNotification : AuditableTenantEntity
{
    public Guid UserId { get; set; }
    public Guid? SourceId { get; set; }
    public Guid? CreatedBy { get; set; }
    public string NotificationType { get; set; } = string.Empty;
    public NotificationStatus Status { get; set; } = NotificationStatus.Unread;
    public NotificationSeverity Severity { get; set; } = NotificationSeverity.Info;
    public string Title { get; set; } = string.Empty;
    public string Message { get; set; } = string.Empty;
    public string? ActionLabel { get; set; }
    public string? ActionPath { get; set; }
    public string? SourceType { get; set; }
    public string? DedupeKey { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset? ReadAt { get; set; }
}

public sealed class Badge : AuditableTenantEntity
{
    public string? LegacyId { get; set; }
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
    public string? Category { get; set; }
    public string? IconUrl { get; set; }
    public int? Level { get; set; }
    public string? UnlockType { get; set; }
    public string? ConditionField { get; set; }
    public string? ConditionOperator { get; set; }
    public decimal? ConditionValue { get; set; }
    public JsonElement ConditionExtra { get; set; } = JsonDefaults.Object();
    public int SortOrder { get; set; }
    public bool IsActive { get; set; } = true;
}

public sealed class UserBadge : AuditableTenantEntity
{
    public Guid? UserId { get; set; }
    public Guid? BadgeId { get; set; }
    public Guid? GrantedBy { get; set; }
    public string? LegacyId { get; set; }
    public string? Note { get; set; }
    public DateTimeOffset? GrantedAt { get; set; }
}

public sealed class TenantContentNotification : AuditableTenantEntity
{
    public Guid? AdoptionId { get; set; }
    public Guid? SourceQuestionBankId { get; set; }
    public Guid? CreatedBy { get; set; }
    public Guid? ReadBy { get; set; }

    public TenantContentNotificationType NotificationType { get; set; } =
        TenantContentNotificationType.PublicQuestionBankSynced;

    public TenantContentNotificationStatus Status { get; set; } = TenantContentNotificationStatus.Unread;
    public NotificationSeverity Severity { get; set; } = NotificationSeverity.Info;
    public string Title { get; set; } = string.Empty;
    public string Message { get; set; } = string.Empty;
    public string? ActionLabel { get; set; }
    public string? ActionPath { get; set; }
    public string? DedupeKey { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset? ReadAt { get; set; }
    public DateTimeOffset? ResolvedAt { get; set; }
}

public sealed class TenantThemeTemplate : AuditableEntity
{
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
    public string? PreviewImageUrl { get; set; }
    public JsonElement Theme { get; set; } = JsonDefaults.Object();
    public JsonElement PublicAssets { get; set; } = JsonDefaults.Object();
    public TenantThemeTemplateStatus Status { get; set; } = TenantThemeTemplateStatus.Active;
    public int SortOrder { get; set; } = 100;
}

public sealed class TenantThemeConfig : AuditableTenantEntity
{
    public string? ActiveTemplateCode { get; set; }
    public JsonElement ActiveTheme { get; set; } = JsonDefaults.Object();
    public JsonElement ActivePublicAssets { get; set; } = JsonDefaults.Object();
    public string? DraftTemplateCode { get; set; }
    public JsonElement DraftTheme { get; set; } = JsonDefaults.Object();
    public JsonElement DraftPublicAssets { get; set; } = JsonDefaults.Object();
    public TenantThemeConfigStatus Status { get; set; } = TenantThemeConfigStatus.Published;
    public DateTimeOffset? PublishedAt { get; set; }
    public Guid? PublishedBy { get; set; }
    public Guid? DraftUpdatedBy { get; set; }
}

public enum NotificationStatus
{
    Unread,
    Read,
    Dismissed,
    Archived
}

public enum NotificationSeverity
{
    Info,
    Success,
    Warning,
    Error
}

public enum TenantContentNotificationType
{
    PublicQuestionBankSynced,
    PublicQuestionBankConflict
}

public enum TenantContentNotificationStatus
{
    Unread,
    Read,
    Dismissed,
    Resolved
}

public enum TenantThemeTemplateStatus
{
    Active,
    Disabled
}

public enum TenantThemeConfigStatus
{
    Draft,
    Published
}

public enum BackendPermissionArea
{
    Platform,
    Tenant,
    Both
}

public enum BackendRoleStatus
{
    Active,
    Disabled,
    Archived
}

public enum BackgroundJobStatus
{
    Pending,
    Processing,
    Succeeded,
    Failed,
    Cancelled
}

public enum TenantLifecycleOperationType
{
    Export,
    Archive,
    Restore,
    OwnerTransfer
}

public enum TenantLifecycleOperationStatus
{
    Pending,
    Processing,
    Succeeded,
    Failed
}