/**
 * Takes TypeORM entity rows and converts them to plain DTO objects
 * matching the Angular-side interfaces.
 */

import { MessageEntity } from '../entities/MessageEntity';
import { UserEntity } from '../entities/UserEntity';
import { RoomEntity } from '../entities/RoomEntity';
import { ReactionEntity } from '../entities/ReactionEntity';
import { BanEntity } from '../entities/BanEntity';
import { AttachmentEntity } from '../entities/AttachmentEntity';
import { ReactionPayload } from './types';
import {
  relationRecordToRoomPayload,
  RoomChannelPermissionRecord,
  RoomChannelRecord,
  RoomMemberRecord,
  RoomRoleAssignmentRecord,
  RoomRoleRecord
} from './relations';

const DELETED_MESSAGE_CONTENT = '[Message deleted]';

export function rowToMessage(row: MessageEntity, reactions: ReactionPayload[] = []) {
  const isDeleted = !!row.isDeleted;

  return {
    id: row.id,
    roomId: row.roomId,
    channelId: row.channelId ?? undefined,
    senderId: row.senderId,
    senderName: row.senderName,
    content: isDeleted ? DELETED_MESSAGE_CONTENT : row.content,
    timestamp: row.timestamp,
    editedAt: row.editedAt ?? undefined,
    reactions: isDeleted ? [] : reactions,
    isDeleted,
    replyToId: row.replyToId ?? undefined,
    linkMetadata: row.linkMetadata ? JSON.parse(row.linkMetadata) : undefined
  };
}

export function rowToUser(row: UserEntity) {
  return {
    id: row.id,
    oderId: row.oderId ?? '',
    username: row.username ?? '',
    displayName: row.displayName ?? '',
    description: row.description ?? undefined,
    profileUpdatedAt: row.profileUpdatedAt ?? undefined,
    avatarUrl: row.avatarUrl ?? undefined,
    avatarHash: row.avatarHash ?? undefined,
    avatarMime: row.avatarMime ?? undefined,
    avatarUpdatedAt: row.avatarUpdatedAt ?? undefined,
    status: row.status ?? 'offline',
    role: row.role ?? 'member',
    joinedAt: row.joinedAt ?? 0,
    peerId: row.peerId ?? undefined,
    isOnline: !!row.isOnline,
    isAdmin: !!row.isAdmin,
    isRoomOwner: !!row.isRoomOwner,
    voiceState: row.voiceState ? JSON.parse(row.voiceState) : undefined,
    screenShareState: row.screenShareState ? JSON.parse(row.screenShareState) : undefined
  };
}

export function rowToRoom(
  row: RoomEntity,
  relations: {
    channels?: RoomChannelRecord[];
    members?: RoomMemberRecord[];
    roles?: RoomRoleRecord[];
    roleAssignments?: RoomRoleAssignmentRecord[];
    channelPermissions?: RoomChannelPermissionRecord[];
  } = {
    channels: [],
    members: [],
    roles: [],
    roleAssignments: [],
    channelPermissions: []
  }
) {
  const relationPayload = relationRecordToRoomPayload({ slowModeInterval: row.slowModeInterval }, {
    channels: relations.channels ?? [],
    members: relations.members ?? [],
    roles: relations.roles ?? [],
    roleAssignments: relations.roleAssignments ?? [],
    channelPermissions: relations.channelPermissions ?? []
  });

  return {
    id: row.id,
    name: row.name,
    description: row.description ?? undefined,
    topic: row.topic ?? undefined,
    hostId: row.hostId,
    password: row.password ?? undefined,
    hasPassword: !!row.hasPassword,
    isPrivate: !!row.isPrivate,
    createdAt: row.createdAt,
    userCount: row.userCount,
    maxUsers: row.maxUsers ?? undefined,
    icon: row.icon ?? undefined,
    iconUpdatedAt: row.iconUpdatedAt ?? undefined,
    slowModeInterval: row.slowModeInterval,
    permissions: relationPayload.permissions,
    channels: relationPayload.channels,
    members: relationPayload.members,
    roles: relationPayload.roles,
    roleAssignments: relationPayload.roleAssignments,
    channelPermissions: relationPayload.channelPermissions,
    sourceId: row.sourceId ?? undefined,
    sourceName: row.sourceName ?? undefined,
    sourceUrl: row.sourceUrl ?? undefined
  };
}

export function rowToReaction(row: ReactionEntity) {
  return {
    id: row.id,
    messageId: row.messageId,
    oderId: row.oderId ?? '',
    userId: row.userId ?? '',
    emoji: row.emoji,
    timestamp: row.timestamp
  };
}

export function rowToAttachment(row: AttachmentEntity) {
  return {
    id: row.id,
    messageId: row.messageId,
    filename: row.filename,
    size: row.size,
    mime: row.mime,
    isImage: !!row.isImage,
    uploaderPeerId: row.uploaderPeerId ?? undefined,
    filePath: row.filePath ?? undefined,
    savedPath: row.savedPath ?? undefined
  };
}

export function rowToBan(row: BanEntity) {
  return {
    oderId: row.oderId,
    userId: row.userId ?? '',
    roomId: row.roomId,
    bannedBy: row.bannedBy,
    displayName: row.displayName ?? undefined,
    reason: row.reason ?? undefined,
    expiresAt: row.expiresAt ?? undefined,
    timestamp: row.timestamp
  };
}
