import type { EventContext, MemberSummary, Sender, TimelineItem } from './types';

export type RoomProfiles = Record<string, Record<string, MemberSummary>>;

export function lacksProfile(sender: Sender): boolean {
  return !sender.display_name && !sender.avatar;
}

/** Rooms holding a sender or reply sender that came back with no name and no avatar. */
export function roomsLackingProfiles(items: { roomId: string; item: TimelineItem }[]): Set<string> {
  const rooms = new Set<string>();
  for (const { roomId, item } of items) {
    if (item.kind !== 'event') continue;
    const reply = item.event.reply_to?.details;
    if (lacksProfile(item.event.sender) || (reply?.kind === 'Ready' && lacksProfile(reply.sender))) rooms.add(roomId);
  }
  return rooms;
}

function filled(sender: Sender, members: Record<string, MemberSummary> | undefined): Sender {
  const member = members?.[sender.user_id];
  if (!member || !lacksProfile(sender) || (!member.display_name && !member.avatar)) return sender;
  return { ...sender, display_name: member.display_name, avatar: member.avatar, name_ambiguous: member.name_ambiguous };
}

export function withProfiles(item: TimelineItem, members: Record<string, MemberSummary> | undefined): TimelineItem {
  if (item.kind !== 'event' || !members) return item;
  const { reply_to: reply } = item.event;
  const details = reply?.details;
  const sender = filled(item.event.sender, members);
  const replySender = details?.kind === 'Ready' ? filled(details.sender, members) : null;
  if (sender === item.event.sender && (details?.kind !== 'Ready' || replySender === details.sender)) return item;
  const reply_to = reply && details?.kind === 'Ready' && replySender ? { ...reply, details: { ...details, sender: replySender } } : reply;
  return { ...item, event: { ...item.event, sender, reply_to } };
}

export function contextWithProfiles(context: EventContext, members: Record<string, MemberSummary> | undefined): EventContext {
  if (!members) return context;
  return {
    ...context,
    events_before: context.events_before.map((item) => withProfiles(item, members)),
    event: withProfiles(context.event, members),
    events_after: context.events_after.map((item) => withProfiles(item, members))
  };
}
