import { createDefaultLicenseHttpOptions } from './license.contract';
import type { AsukaLicenseOptions } from '../../types/options';
import type {
  AsukaLicenseHttpOptions,
  AsukaLicenseRefreshOptions,
  AsukaLicenseTokenInput,
} from './license.types';

export interface NormalizedAsukaLicenseOptions {
  enabled: boolean;
  key?: string;
  token?: AsukaLicenseTokenInput;
  domain?: string;
  instanceId?: string;
  channel: string;
  audience: string;
  debug: boolean;
  http: AsukaLicenseHttpOptions;
  refresh: Required<Pick<AsukaLicenseRefreshOptions, 'enabled' | 'intervalMs' | 'onFocus' | 'onVisibilityChange'>>;
}

function trimOrUndefined(value: unknown): string | undefined {
  if (typeof value !== 'string') return undefined;
  const trimmed = value.trim();
  return trimmed || undefined;
}

function normalizeDomain(value: unknown): string | undefined {
  const trimmed = trimOrUndefined(value);
  if (!trimmed) return undefined;
  try {
    if (/^https?:\/\//i.test(trimmed)) {
      return new URL(trimmed).hostname || undefined;
    }
    return new URL(`http://${trimmed}`).hostname || trimmed.split(':')[0] || undefined;
  } catch {
    return trimmed.split('/')[0]?.split(':')[0] || undefined;
  }
}

function normalizeHttpOptions(
  audience: string,
  channel: string,
): AsukaLicenseHttpOptions {
  return {
    ...createDefaultLicenseHttpOptions({ audience, channel }),
    audience,
    channel,
  };
}

export function normalizeLicenseOptions(input?: AsukaLicenseOptions | null): NormalizedAsukaLicenseOptions {
  const channel = trimOrUndefined(input?.channel) ?? 'js';
  const audience = trimOrUndefined(input?.audience) ?? 'asuka-designer';
  const refresh = input?.refresh ?? {};
  const intervalMs = Number(refresh.intervalMs ?? 6 * 60 * 60 * 1000);

  return {
    enabled: input?.enabled !== false,
    key: trimOrUndefined(input?.key),
    token: typeof input?.token === 'undefined' ? undefined : (input?.token ?? undefined),
    domain: normalizeDomain(input?.domain),
    instanceId: trimOrUndefined(input?.instanceId),
    channel,
    audience,
    debug: input?.debug === true,
    http: normalizeHttpOptions(audience, channel),
    refresh: {
      enabled: refresh.enabled !== false,
      intervalMs: Number.isFinite(intervalMs) && intervalMs > 0 ? intervalMs : 6 * 60 * 60 * 1000,
      onFocus: refresh.onFocus !== false,
      onVisibilityChange: refresh.onVisibilityChange !== false,
    },
  };
}
