import * as uuid from 'uuid'
import { AppState } from '../root/reducers'
import { LogglyLogger, LogglyConfigInterface } from './loggly'
import { config } from '../config'

// Don't assume that config exists. Breaks tests if you do!
const LOGGLY_KEY = ((self ? self : window) as any).config ? config.LOGGLY_KEY : ''
const SERVICE = ((self ? self : window) as any).config ? config.SERVICE : ''
const APP_VERSION = ((self ? self : window) as any).config ? config.APP_VERSION : ''
const ENV = ((self ? self : window) as any).config ? config.ENV : 'local'

const _logglyOptions: LogglyConfigInterface = {
    key: LOGGLY_KEY,
    tag: `${SERVICE}-${ENV}`,
    host: 'logs-01.loggly.com',
    sendConsoleErrors: false,
    appVersion: APP_VERSION,
}

// console.log('LOGGLY OPTIONS', _logglyOptions)

export const logger = new LogglyLogger(_logglyOptions)

export interface Ctx {
    action: string
    actionID: string
    runID: string
}

interface LogMessage {
    message: string
    level: string,
    parameters?: {}
    [name: string]: any
    ctx?: Ctx
}

export const forAction =
    (action: string, state: AppState, ctx?: Ctx) => {
        if (ctx) {
            return ctx
        }

        const actionID = uuid()
        const runID = state.logger.runID

        return { action, actionID, runID }
    }

const mkMessage =
    (level: string, message: string, properties: object, parameters: object, ctx: Ctx): any => {
        const env = config.ENV
        const service = config.SERVICE
        const timestamp = new Date().toISOString()

        return {
            message,
            level,
            parameters,
            env,
            service,
            timestamp,
            ...properties,
            ...ctx,
        }
    }

const log = (logMessage: LogMessage) => {
    console.group(`${logMessage.level.toUpperCase()} - ${logMessage.message}`)
    console.log(logMessage)
    console.groupEnd()

    logger.log(logMessage)
}

const logError = (logMessage: LogMessage) => {
    console.group(`${logMessage.level.toUpperCase()} - ${logMessage.message}`)
    console.error(logMessage)
    console.groupEnd()
    logger.log(logMessage)
}

export const kpi = (type: string, parameters: { [name: string]: any }, ctx?: Ctx) => {
    log(mkMessage('KPI', type, {}, parameters, ctx))
}

export const info =
    (message: string, parameters: { [name: string]: any }, ctx?: Ctx) => {
        log(mkMessage('info', message, {}, parameters, ctx))
    }

export const trace =
    (message: string, traceID: string, parameters: { [name: string]: any }, ctx?: Ctx) => {
        log(mkMessage('info', message, { traceID }, parameters, ctx))
    }

export const debug =
    (message: string, parameters: { [name: string]: any }, ctx?: Ctx) => {
        log(mkMessage('debug', message, {}, parameters, ctx))
    }

export const error =
    (message: string, errorObj: any, parameters: { [name: string]: any }, ctx?: Ctx) => {
        logError(mkMessage('error', message, { error: errorObj }, parameters, ctx))
    }
