import { getClientOs, isWebview } from './platform';

/** Browser context captured for audit / legal acceptance (no fingerprinting libraries). */
export type WebAcceptanceClientContext = {
  platform: 'web';
  capturedAt: string;
  clientOs: ReturnType<typeof getClientOs>;
  isWebview: boolean;
  userAgent: string | undefined;
  language: string | undefined;
  languages: string[] | undefined;
  navigatorPlatform: string | undefined;
  cookieEnabled: boolean | undefined;
  onLine: boolean | undefined;
  timezone: string | undefined;
  screen:
    | {
        width: number;
        height: number;
        availWidth: number;
        availHeight: number;
        colorDepth: number;
        pixelDepth: number;
      }
    | undefined;
  viewport:
    | {
        innerWidth: number;
        innerHeight: number;
        outerWidth: number;
        outerHeight: number;
        devicePixelRatio: number;
      }
    | undefined;
  pageUrl: string | undefined;
  referrer: string | undefined;
  userAgentDataMobile: boolean | undefined;
  userAgentHighEntropy: Record<string, unknown> | undefined;
};

const HIGH_ENTROPY_HINTS = [
  'architecture',
  'bitness',
  'brands',
  'fullVersionList',
  'model',
  'platform',
  'platformVersion',
  'uaFullVersion',
  'wow64',
] as const;

async function tryGetHighEntropyValues(): Promise<
  Record<string, unknown> | undefined
> {
  if (typeof navigator === 'undefined') {
    return undefined;
  }
  const uaData = (
    navigator as Navigator & {
      userAgentData?: {
        getHighEntropyValues?: (
          hints: readonly string[],
        ) => Promise<Record<string, unknown>>;
      };
    }
  ).userAgentData;
  if (!uaData?.getHighEntropyValues) {
    return undefined;
  }
  try {
    const values = await uaData.getHighEntropyValues([...HIGH_ENTROPY_HINTS]);
    return values as Record<string, unknown>;
  } catch {
    return undefined;
  }
}

/**
 * Collects available browser metadata without extra dependencies.
 * Does not replace server-side data (IP, request User-Agent, etc.).
 */
export async function getWebAcceptanceClientContext(): Promise<WebAcceptanceClientContext> {
  const capturedAt = new Date().toISOString();

  if (typeof window === 'undefined' || typeof navigator === 'undefined') {
    return {
      platform: 'web',
      capturedAt,
      clientOs: undefined,
      isWebview: false,
      userAgent: undefined,
      language: undefined,
      languages: undefined,
      navigatorPlatform: undefined,
      cookieEnabled: undefined,
      onLine: undefined,
      timezone: undefined,
      screen: undefined,
      viewport: undefined,
      pageUrl: undefined,
      referrer: undefined,
      userAgentDataMobile: undefined,
      userAgentHighEntropy: undefined,
    };
  }

  const nav = navigator;
  const uaData = (
    nav as Navigator & {
      userAgentData?: { mobile?: boolean };
    }
  ).userAgentData;

  const userAgentHighEntropy = await tryGetHighEntropyValues();

  return {
    platform: 'web',
    capturedAt,
    clientOs: getClientOs(),
    isWebview,
    userAgent: nav.userAgent,
    language: nav.language,
    languages: nav.languages ? [...nav.languages] : undefined,
    navigatorPlatform: nav.platform,
    cookieEnabled: nav.cookieEnabled,
    onLine: nav.onLine,
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    screen:
      typeof screen !== 'undefined'
        ? {
            width: screen.width,
            height: screen.height,
            availWidth: screen.availWidth,
            availHeight: screen.availHeight,
            colorDepth: screen.colorDepth,
            pixelDepth: screen.pixelDepth,
          }
        : undefined,
    viewport: {
      innerWidth: window.innerWidth,
      innerHeight: window.innerHeight,
      outerWidth: window.outerWidth,
      outerHeight: window.outerHeight,
      devicePixelRatio: window.devicePixelRatio,
    },
    pageUrl: window.location.href,
    referrer: document.referrer || undefined,
    userAgentDataMobile: uaData?.mobile,
    userAgentHighEntropy,
  };
}
