// Generated by ResgenSwift.Analytics 2.2.0

import Foundation
import FirebaseAnalytics
import os

// MARK: - Protocol

internal protocol AnalyticsManagerProtocol {

    func logScreen(
        name: String,
        path: String,
        params: [String: Any]?
    )

    func logEvent(
        name: String,
        action: String,
        category: String,
        params: [String: Any]?
    )

    func setEnable(_ enable: Bool)
}

// MARK: - Firebase

class FirebaseAnalyticsManager: AnalyticsManagerProtocol {

    // MARK: - Methods

    func logScreen(
        name: String,
        path: String,
        params: [String: Any]?
    ) {
        var parameters = [
            AnalyticsParameterScreenName: name as NSObject
        ]

        if path.isEmpty == false {
            parameters["path"] = path + "/iOS" as NSObject
        }

        if let supplementaryParameters = params {
            for (newKey, newValue) in supplementaryParameters {
                if parameters.contains(where: { (key: String, value: NSObject) in
                    key == newKey
                }) {
                    continue
                }

                parameters[newKey] = newValue as? NSObject
            }
        }

        Analytics.logEvent(
            AnalyticsEventScreenView,
            parameters: parameters
        )
    }

    func logEvent(
        name: String,
        action: String,
        category: String,
        params: [String: Any]?
    ) {
        var parameters: [String: NSObject] = [
            AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject
        ]

        if category.isEmpty == false {
            parameters["AnalyticsParameterItemCategory"] = category as NSObject
        }

        if action.isEmpty == false {
            parameters["action"] = action as NSObject
        }

        if let supplementaryParameters = params {
            for (newKey, newValue) in supplementaryParameters {
                if parameters.contains(where: { (key: String, value: NSObject) in
                    key == newKey
                }) {
                    continue
                }

                parameters[newKey] = newValue as? NSObject
            }
        }

        Analytics.logEvent(
            AnalyticsEventSelectContent,
            parameters: parameters
        )
    }

    func setEnable(_ enable: Bool) {
        Analytics.setAnalyticsCollectionEnabled(enable)
    }
}

// MARK: - Traker Type

internal enum TrackerType: CaseIterable {

    case firebase
}

// MARK: - Manager

internal class AnalyticsManager {

    internal static var shared = AnalyticsManager()

    private init() {}

    // MARK: - Properties

    var managers: [TrackerType: AnalyticsManagerProtocol] = [:]

    private var isDebugMode: Bool = false

    private var isEnabled: Bool {
        if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
            false
        } else {
            true
        }
    }

    private let logger = Logger(subsystem: "resgen", category: "analytics")

    // MARK: - Enable Methods

    private func setAnalytics(enable: Bool, _ analytics: [TrackerType]) {
        managers.forEach { (key, value) in
            if analytics.contains(where: { type in
                type == key
            }) {
                value.setEnable(enable)
            }
        }
    }

    internal func enableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) {
        setAnalytics(enable: true, analytics)
    }

    internal func disableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) {
        setAnalytics(enable: false, analytics)
    }

    internal func configure(isDebugMode: Bool = false) {
        self.isDebugMode = isDebugMode
        managers[TrackerType.firebase] = FirebaseAnalyticsManager()
    }

    // MARK: - Private Log Methods

    private func formattedParams(_ params: [String: Any]?) -> String {
        guard let params = params, !params.isEmpty else { return "-" }
        
        let formattedParams = params.map { key, value in
            "       \(key): \(value)"
        }
        .joined(separator: "\n")
    
        return "\n" + formattedParams
    }

    private func logScreen(
        name: String,
        path: String,
        params: [String: Any]?
    ) {
        guard isEnabled else {
            if isDebugMode {
                logger.log("Analytics disabled")
            }
            return 
        }

        managers.values.forEach { manager in
            
            if isDebugMode {
                logger.debug("""
                🖥️ Screen:
                     Name: \(name, privacy: .public)
                     Path: \(path, privacy: .public)
                     Params: \(self.formattedParams(params), privacy: .public)
                """)
            }

            manager.logScreen(
                name: name,
                path: path,
                params: params
            )
        }
    }

    private func logEvent(
        name: String,
        action: String,
        category: String,
        params: [String: Any]?
    ) {
        guard isEnabled else {
            if isDebugMode {
                logger.log("Analytics disabled")
            }
            return 
        }

        managers.values.forEach { manager in
                
            if isDebugMode {
                logger.debug("""
                📊 Event:
                     Name: \(name, privacy: .public)
                     Action: \(action.isEmpty ? "-" : action, privacy: .public)
                     Category: \(category.isEmpty ? "-" : category, privacy: .public)
                     Params: \(self.formattedParams(params), privacy: .public)
                """)
            }

            manager.logEvent(
                name: name,
                action: action,
                category: category,
                params: params
            )
        }
    }

    // MARK: - section_one

    internal func logScreenS1DefOne(title: String) {
        logScreen(
            name: "s1 def one \(title)",
            path: "s1_def_one/\(title)",
            params: nil
        )
    }

    internal func logEventS1DefTwo(
        title: String,
		count: String,
		test2: String = "test"
    ) {
        logEvent(
            name: "s1 def two",
            action: "test",
            category: "test",
            params: [
                "title": title,
				"count": count,
				"test": "test",
				"test2": test2
            ]
        )
    }

    // MARK: - section_two

    internal func logScreenS2DefOne() {
        logScreen(
            name: "s2 def one",
            path: "s2_def_one/",
            params: nil
        )
    }
}
