import { Channel, ChannelType } from '../../shared-kernel';

export function normalizeChannelName(name: string): string {
  return name.trim().replace(/\s+/g, ' ');
}

function channelNameKey(name: string): string {
  return normalizeChannelName(name).toLocaleLowerCase();
}

function typedChannelNameKey(type: ChannelType, name: string): string {
  return `${type}:${channelNameKey(name)}`;
}

export function isChannelNameTaken(
  channels: Channel[],
  name: string,
  channelType: ChannelType,
  excludeChannelId?: string
): boolean {
  const targetKey = channelNameKey(name);

  if (!targetKey) {
    return false;
  }

  return channels.some(
    (channel) => channel.id !== excludeChannelId
      && channel.type === channelType
      && channelNameKey(channel.name) === targetKey
  );
}

export function normalizeRoomChannels(channels: Channel[] | undefined): Channel[] | undefined {
  if (!Array.isArray(channels)) {
    return channels;
  }

  const seenIds = new Set<string>();
  const seenNames = new Set<string>();
  const normalized: Channel[] = [];

  for (const [index, channel] of channels.entries()) {
    const id = typeof channel.id === 'string' ? channel.id.trim() : '';
    const name = normalizeChannelName(channel.name);
    const type = channel.type === 'text' || channel.type === 'voice' ? channel.type : null;
    const nameKey = type ? typedChannelNameKey(type, name) : '';

    if (!id || !name || !type || seenIds.has(id) || seenNames.has(nameKey)) {
      continue;
    }

    seenIds.add(id);
    seenNames.add(nameKey);
    normalized.push({
      id,
      name,
      type,
      position: typeof channel.position === 'number' ? channel.position : index
    });
  }

  return normalized;
}
