import type { RadioBrowserStation, RadioStation } from './radioTypes.js';

const MAX_TAGS = 12;
const OBVIOUSLY_UNSUPPORTED_CODECS = new Set([
  'wma',
  'wmav2',
  'asf',
  'ra',
  'rm',
  'ape',
  'alac',
  'amr',
]);

function trimToNull(value: string | null | undefined): string | null {
  if (typeof value !== 'string') return null;
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : null;
}

function toNumber(value: number | string | null | undefined): number {
  const parsed = typeof value === 'number' ? value : Number(value ?? 0);
  return Number.isFinite(parsed) ? parsed : 0;
}

function toNullableNumber(value: number | string | null | undefined): number | null {
  const parsed = typeof value === 'number' ? value : Number(value ?? NaN);
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
}

function parseTags(tags: string | null | undefined): string[] {
  if (typeof tags !== 'string' || tags.trim().length === 0) return [];

  const seen = new Set<string>();
  const parsed: string[] = [];

  for (const rawTag of tags.split(',')) {
    const tag = rawTag.trim();
    if (!tag) continue;
    const normalizedTag = tag.toLowerCase();
    if (seen.has(normalizedTag)) continue;
    seen.add(normalizedTag);
    parsed.push(tag);
    if (parsed.length >= MAX_TAGS) break;
  }

  return parsed;
}

function isHttpsUrl(value: string | null): value is string {
  if (!value) return false;

  try {
    const url = new URL(value);
    return url.protocol === 'https:';
  } catch {
    return false;
  }
}

export function normalizeRadioBrowserStation(
  station: RadioBrowserStation,
  countryName: string,
): RadioStation | null {
  const stationUuid = trimToNull(station.stationuuid);
  if (!stationUuid) return null;

  const name = trimToNull(station.name);
  if (!name) return null;

  const streamUrl = trimToNull(station.url_resolved) ?? trimToNull(station.url);
  if (!isHttpsUrl(streamUrl)) return null;

  const codec = trimToNull(station.codec);
  if (codec && OBVIOUSLY_UNSUPPORTED_CODECS.has(codec.toLowerCase())) {
    return null;
  }

  return {
    id: stationUuid,
    name,
    country: trimToNull(station.country) ?? countryName,
    countryCode: trimToNull(station.countrycode) ?? '',
    language: trimToNull(station.language),
    tags: parseTags(station.tags),
    codec,
    bitrate: toNullableNumber(station.bitrate),
    streamUrl,
    homepage: trimToNull(station.homepage),
    logoUrl: trimToNull(station.favicon),
    votes: toNumber(station.votes),
    clickcount: toNumber(station.clickcount),
    source: 'radio-browser',
    sourceStationUuid: stationUuid,
  };
}