using Ikar.Shared;

namespace Ikar.Server.Data.Entities;

public sealed class User
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public string Username { get; set; } = string.Empty;
    public string NormalizedUsername { get; set; } = string.Empty;
    public string DisplayName { get; set; } = string.Empty;
    public string PasswordHash { get; set; } = string.Empty;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public bool IsBlocked { get; set; }
    public DateTimeOffset? BlockedAt { get; set; }
    public string? PhoneNumber { get; set; }
    public string? NormalizedPhoneNumber { get; set; }
    public string? About { get; set; }
    public string? AvatarStoragePath { get; set; }
    public string? AvatarContentType { get; set; }
    public bool IsBot { get; set; }

    public ICollection<UserSession> Sessions { get; set; } = new List<UserSession>();
    public UserPrivacySettings? PrivacySettings { get; set; }
    public ICollection<ChatMember> ChatMemberships { get; set; } = new List<ChatMember>();
    public ICollection<Chat> CreatedChats { get; set; } = new List<Chat>();
    public ICollection<Message> Messages { get; set; } = new List<Message>();
    public ICollection<MessageReaction> MessageReactions { get; set; } = new List<MessageReaction>();
    public ICollection<PushDevice> PushDevices { get; set; } = new List<PushDevice>();
    public ICollection<Bot> OwnedBots { get; set; } = new List<Bot>();
    public Bot? BotProfile { get; set; }
}

public sealed class UserPrivacySettings
{
    public Guid UserId { get; set; }
    public User User { get; set; } = null!;
    public string PhoneNumberVisibility { get; set; } = "contacts";
    public string LastSeenVisibility { get; set; } = "contacts";
    public string ProfilePhotoVisibility { get; set; } = "everyone";
    public string BlockedUserIds { get; set; } = string.Empty;
    public string AlwaysAllowUserIds { get; set; } = string.Empty;
    public string NeverAllowUserIds { get; set; } = string.Empty;
    public bool PasscodeLockEnabled { get; set; }
    public bool ShowMessagePreview { get; set; } = true;
    public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class UserSession
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid UserId { get; set; }
    public User User { get; set; } = null!;
    public string TokenHash { get; set; } = string.Empty;
    public string? ClientPlatform { get; set; }
    public int? ClientVersionCode { get; set; }
    public string? ClientVersionName { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset LastSeenAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class Chat
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public ChatType Type { get; set; }
    public string? Title { get; set; }
    public string? Description { get; set; }
    public string? PublicUsername { get; set; }
    public Guid? LinkedDiscussionChatId { get; set; }
    public Chat? LinkedDiscussionChat { get; set; }
    public bool ChannelSignaturesEnabled { get; set; }
    public bool TopicsEnabled { get; set; }
    public bool HasProtectedContent { get; set; }
    public int? DefaultMessageTtlSeconds { get; set; }
    public Guid CreatedById { get; set; }
    public User CreatedBy { get; set; } = null!;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? LastActivityAt { get; set; }

    public ICollection<ChatMember> Members { get; set; } = new List<ChatMember>();
    public ICollection<Message> Messages { get; set; } = new List<Message>();
    public ICollection<ChatInviteLink> InviteLinks { get; set; } = new List<ChatInviteLink>();
    public ICollection<ChatJoinRequest> JoinRequests { get; set; } = new List<ChatJoinRequest>();
    public ICollection<ChatTopic> Topics { get; set; } = new List<ChatTopic>();
}

public sealed class ChatInviteLink
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid ChatId { get; set; }
    public Chat Chat { get; set; } = null!;
    public Guid CreatedById { get; set; }
    public User CreatedBy { get; set; } = null!;
    public string Token { get; set; } = string.Empty;
    public string? Title { get; set; }
    public bool CreatesJoinRequest { get; set; }
    public bool IsRevoked { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? RevokedAt { get; set; }
}

public sealed class ChatTopic
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid ChatId { get; set; }
    public Chat Chat { get; set; } = null!;
    public Guid CreatedById { get; set; }
    public User CreatedBy { get; set; } = null!;
    public string Title { get; set; } = string.Empty;
    public string Icon { get; set; } = "💬";
    public bool IsPinned { get; set; }
    public bool IsClosed { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset LastActivityAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class ChatJoinRequest
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid ChatId { get; set; }
    public Chat Chat { get; set; } = null!;
    public Guid InviteLinkId { get; set; }
    public ChatInviteLink InviteLink { get; set; } = null!;
    public Guid UserId { get; set; }
    public User User { get; set; } = null!;
    public ChatJoinRequestStatus Status { get; set; } = ChatJoinRequestStatus.Pending;
    public DateTimeOffset RequestedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? ResolvedAt { get; set; }
    public Guid? ResolvedByUserId { get; set; }
    public User? ResolvedByUser { get; set; }
}

public sealed class ChatMember
{
    public Guid ChatId { get; set; }
    public Chat Chat { get; set; } = null!;
    public Guid UserId { get; set; }
    public User User { get; set; } = null!;
    public bool IsOwner { get; set; }
    public ChatMemberRole Role { get; set; } = ChatMemberRole.Member;
    public bool CanPinMessages { get; set; } = true;
    public bool CanDeleteMessages { get; set; }
    public bool CanInviteUsers { get; set; } = true;
    public bool CanPostMessages { get; set; } = true;
    public bool IsArchived { get; set; }
    public bool IsPinned { get; set; }
    public DateTimeOffset? MutedUntil { get; set; }
    public string? FolderKey { get; set; }
    public DateTimeOffset JoinedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? LastDeliveredAt { get; set; }
    public DateTimeOffset? LastReadAt { get; set; }
}

public sealed class Message
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid ChatId { get; set; }
    public Chat Chat { get; set; } = null!;
    public Guid SenderId { get; set; }
    public User Sender { get; set; } = null!;
    public string Text { get; set; } = string.Empty;
    public DateTimeOffset SentAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? EditedAt { get; set; }
    public DateTimeOffset? DeletedAt { get; set; }
    public string? ForwardedFromDisplayName { get; set; }
    public Guid? ReplyToMessageId { get; set; }
    public Message? ReplyToMessage { get; set; }
    public DateTimeOffset? PinnedAt { get; set; }
    public Guid? PinnedByUserId { get; set; }
    public User? PinnedByUser { get; set; }
    public Guid? MediaAlbumId { get; set; }
    public Guid? TopicId { get; set; }
    public ChatTopic? Topic { get; set; }
    public bool HasProtectedContent { get; set; }
    public DateTimeOffset? ExpiresAt { get; set; }
    public int? TtlSeconds { get; set; }
    public bool PostedAsChannel { get; set; }
    public string? AuthorSignature { get; set; }

    public ICollection<Message> Replies { get; set; } = new List<Message>();
    public ICollection<MessageAttachment> Attachments { get; set; } = new List<MessageAttachment>();
    public ICollection<MessageReaction> Reactions { get; set; } = new List<MessageReaction>();
    public ICollection<MessageView> Views { get; set; } = new List<MessageView>();
    public ICollection<BotUpdate> BotUpdates { get; set; } = new List<BotUpdate>();
}

public sealed class MessageAttachment
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid MessageId { get; set; }
    public Message Message { get; set; } = null!;
    public string OriginalFileName { get; set; } = string.Empty;
    public string ContentType { get; set; } = "application/octet-stream";
    public long FileSizeBytes { get; set; }
    public string StoragePath { get; set; } = string.Empty;
    public int SortOrder { get; set; }
    public DateTimeOffset UploadedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class MessageReaction
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid MessageId { get; set; }
    public Message Message { get; set; } = null!;
    public Guid UserId { get; set; }
    public User User { get; set; } = null!;
    public string Emoji { get; set; } = string.Empty;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class MessageView
{
    public Guid MessageId { get; set; }
    public Message Message { get; set; } = null!;
    public Guid ViewerUserId { get; set; }
    public User ViewerUser { get; set; } = null!;
    public DateTimeOffset ViewedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class PushDevice
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid UserId { get; set; }
    public User User { get; set; } = null!;
    public PushPlatform Platform { get; set; }
    public string InstallationId { get; set; } = string.Empty;
    public string DeviceToken { get; set; } = string.Empty;
    public string? DeviceName { get; set; }
    public string? ClientPlatform { get; set; }
    public int? ClientVersionCode { get; set; }
    public string? ClientVersionName { get; set; }
    public bool NotificationsEnabled { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class Bot
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid UserId { get; set; }
    public User User { get; set; } = null!;
    public Guid OwnerUserId { get; set; }
    public User OwnerUser { get; set; } = null!;
    public string TokenHash { get; set; } = string.Empty;
    public bool IsEnabled { get; set; } = true;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;

    public ICollection<BotCommand> Commands { get; set; } = new List<BotCommand>();
    public ICollection<BotUpdate> Updates { get; set; } = new List<BotUpdate>();
}

public sealed class BotCommand
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid BotId { get; set; }
    public Bot Bot { get; set; } = null!;
    public string Command { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public int SortOrder { get; set; }
}

public sealed class BotUpdate
{
    public long Id { get; set; }
    public Guid BotId { get; set; }
    public Bot Bot { get; set; } = null!;
    public Guid ChatId { get; set; }
    public Chat Chat { get; set; } = null!;
    public Guid MessageId { get; set; }
    public Message Message { get; set; } = null!;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class ModerationLogEntry
{
    public long Id { get; set; }
    public Guid? ChatId { get; set; }
    public Chat? Chat { get; set; }
    public Guid ActorUserId { get; set; }
    public User ActorUser { get; set; } = null!;
    public ModerationLogTargetType TargetType { get; set; }
    public Guid? TargetId { get; set; }
    public string Action { get; set; } = string.Empty;
    public string? Reason { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class Story
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid AuthorUserId { get; set; }
    public User AuthorUser { get; set; } = null!;
    public string Text { get; set; } = string.Empty;
    public StoryVisibility Visibility { get; set; } = StoryVisibility.Everyone;
    public bool HasProtectedContent { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset ExpiresAt { get; set; } = DateTimeOffset.UtcNow.AddHours(24);
    public DateTimeOffset? DeletedAt { get; set; }

    public ICollection<StoryAttachment> Attachments { get; set; } = new List<StoryAttachment>();
    public ICollection<StoryView> Views { get; set; } = new List<StoryView>();
}

public sealed class StoryAttachment
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid StoryId { get; set; }
    public Story Story { get; set; } = null!;
    public string OriginalFileName { get; set; } = string.Empty;
    public string ContentType { get; set; } = "application/octet-stream";
    public long FileSizeBytes { get; set; }
    public string StoragePath { get; set; } = string.Empty;
    public int SortOrder { get; set; }
    public DateTimeOffset UploadedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class StoryView
{
    public Guid StoryId { get; set; }
    public Story Story { get; set; } = null!;
    public Guid ViewerUserId { get; set; }
    public User ViewerUser { get; set; } = null!;
    public DateTimeOffset ViewedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class AndroidUpdateCompatibilityHit
{
    public long Id { get; set; }
    public DateTimeOffset HitAt { get; set; } = DateTimeOffset.UtcNow;
    public string Route { get; set; } = string.Empty;
    public string RequestPath { get; set; } = string.Empty;
    public string? RequestedFileName { get; set; }
    public string? ClientPlatform { get; set; }
    public int? ClientVersionCode { get; set; }
    public string? ClientVersionName { get; set; }
    public string? UserAgent { get; set; }
    public string? RemoteIp { get; set; }
}
