import LogServiceTransport from './log-service-transport'
import { useConsoleLogger } from '../devTools'
import SdkSettings from '../../settings'
import { EcRenderConfig } from '../../enhancedContent'
import { SDK_VERSION } from '../../version'
import { Context } from '../../api'
import { inBrowser } from '../runtime'

export type ErrorProperties = {
  errorContext: 'per-product config' | 'exists' | 'event' | 'iframeResizeListener'
  errorType: 'fetch' | 'parse' | 'validation' | 'dom'
  errorMessage: string
}

export interface Logger {
  log<C extends string>(
    code: C,
    properties?: C extends 'error' ? ErrorProperties : Record<string, unknown> | SdkSettings | EcRenderConfig
  ): void
}

export const createLogger = (context: Context, settings: SdkSettings): Logger => new DefaultLogger(context, settings)

class DefaultLogger implements Logger {
  #context: Context
  #settings: SdkSettings
  #transport: LogServiceTransport

  public constructor(context: Context, settings: SdkSettings) {
    this.#context = context
    this.#settings = settings
    this.#transport = new LogServiceTransport(this.#context, this.#settings)
  }

  public log(code: string, properties = {}): void {
    const context: Record<string, unknown> = { version: SDK_VERSION }

    if (inBrowser()) {
      context['page'] = {
        url: window.location.href,
        title: window.document.title,
        scrollPosition: window.scrollY,
      }
    } else {
      context['serverSide'] = true
    }

    if (useConsoleLogger()) {
      // eslint-disable-next-line no-console
      console.log(`SXP SDK:`, {
        clientId: this.#context.clientId,
        sessionId: this.#context.sessionId,
        pageSessionId: this.#context.pageSessionId,
        code,
        properties,
        context,
      })
    } else {
      this.#transport.log(code, properties, context)
    }
  }
}
