import { NativeModules } from 'react-native'

import { createInteractor } from '../architecture/Interactor'
import { check } from '../utility/check'
import { log } from '../utility/log'
import { checkJSONObject, createJSONObject } from '../utility/json'

export const createDependency = () => {}

type EventInteractor = {
    trackEvent(
        category: string,
        semanticAttributes?: Record<string, any>,
        customAttributes?: Record<string, any>,
    ): void
}

createDependency.EventModule = () => ({
    interactor: createInteractor<EventInteractor>(NativeModules.EventInteractor),
})

export type EventModule = ReturnType<typeof createEventModule>

export const createEventModule = () => {
    // create dependency
    const { interactor } = createDependency.EventModule()

    // define method
    const trackEvent = (
        category: string,
        semanticAttributes?: Record<string, any>,
        customAttributes?: Record<string, any>,
    ): void => {
        if (!check.string(category)) {
            log.unmatchedType('category', 'string')
            return
        }
        if (!(check.null(semanticAttributes) ||
            check.undefined(semanticAttributes) || 
            check.object(semanticAttributes))) {
            log.unmatchedType('semanticAttributes', 'object?')
            return
        }
        if (!(check.null(customAttributes) ||
            check.undefined(customAttributes) || 
            check.object(customAttributes))) {
            log.unmatchedType('customAttributes', 'object?')
            return
        }

        if (!check.null(customAttributes) &&
            check.defined(semanticAttributes) &&
            !checkJSONObject(semanticAttributes)) {
            log.nonJSONValue('semanticAttributes')
            semanticAttributes = createJSONObject(semanticAttributes)
        }
        if (!check.null(customAttributes) &&
            check.defined(customAttributes) &&
            !checkJSONObject(customAttributes)) {
            log.nonJSONValue('customAttributes')
            customAttributes = createJSONObject(customAttributes)
        }

        interactor.trackEvent(category, semanticAttributes, customAttributes)
    }

    // create object
    return {
        trackEvent,
    }
}
