import type { ServerEndpoint, ServerSourceSelector } from '../models/server-directory.model';
import { normaliseConfiguredServerUrl, sanitiseServerBaseUrl } from './server-endpoint-defaults.logic';

export interface RoomSignalSource {
  sourceId?: string;
  sourceName?: string;
  sourceUrl?: string;
}

export interface RoomSignalSourceInput extends RoomSignalSource {
  fallbackName?: string;
  signalingUrl?: string;
}

const DEFAULT_SIGNAL_SOURCE_NAME = 'Signal Server';

export function getSourceUrlFromSignalingUrl(signalingUrl?: string): string | undefined {
  const normalizedUrl = normalizeString(signalingUrl);

  if (!normalizedUrl) {
    return undefined;
  }

  const resolvedUrl = normaliseConfiguredServerUrl(normalizedUrl, 'https');

  return resolvedUrl || undefined;
}

export function buildRoomSignalSource(
  source?: RoomSignalSourceInput | null,
  endpoint?: Pick<ServerEndpoint, 'id' | 'name' | 'url'> | null
): RoomSignalSource {
  const sourceId = normalizeString(endpoint?.id) ?? normalizeString(source?.sourceId);
  const sourceUrl = endpoint
    ? sanitiseServerBaseUrl(endpoint.url)
    : (normalizeUrl(source?.sourceUrl) ?? getSourceUrlFromSignalingUrl(source?.signalingUrl));
  const sourceName = normalizeString(endpoint?.name)
    ?? normalizeString(source?.sourceName)
    ?? normalizeString(source?.fallbackName)
    ?? (sourceUrl ? DEFAULT_SIGNAL_SOURCE_NAME : undefined);

  return {
    sourceId,
    sourceName,
    sourceUrl
  };
}

export function buildRoomSignalSelector(
  source?: RoomSignalSourceInput | null
): ServerSourceSelector | undefined {
  const normalizedSource = buildRoomSignalSource(source);

  if (normalizedSource.sourceId) {
    return { sourceId: normalizedSource.sourceId };
  }

  if (normalizedSource.sourceUrl) {
    return { sourceUrl: normalizedSource.sourceUrl };
  }

  return undefined;
}

export function hasRoomSignalSource(source?: RoomSignalSourceInput | null): boolean {
  return !!buildRoomSignalSelector(source);
}

export function areRoomSignalSourcesEqual(
  left?: RoomSignalSourceInput | null,
  right?: RoomSignalSourceInput | null
): boolean {
  const normalizedLeft = buildRoomSignalSource(left);
  const normalizedRight = buildRoomSignalSource(right);

  return normalizedLeft.sourceId === normalizedRight.sourceId
    && normalizedLeft.sourceName === normalizedRight.sourceName
    && normalizedLeft.sourceUrl === normalizedRight.sourceUrl;
}

function normalizeString(value: string | undefined | null): string | undefined {
  if (typeof value !== 'string') {
    return undefined;
  }

  const trimmed = value.trim();

  return trimmed || undefined;
}

function normalizeUrl(value: string | undefined | null): string | undefined {
  const normalizedValue = normalizeString(value);

  return normalizedValue ? sanitiseServerBaseUrl(normalizedValue) : undefined;
}
