//
//  EventParamsBuilder.swift
//  blaze-rtn-sdk
//
//  Created by Assistant on 2024.
//

import Foundation
import BlazeSDK

/**
 * Shared helper class for building event parameters to eliminate duplication
 * between widget events and SDK module events on iOS.
 */
struct EventParamsBuilder {
    
    // MARK: - Constants
    
    struct Constants {
        static let playerTypeKey = "playerType"
        static let sourceIdKey = "sourceId"
        static let actionTypeKey = "actionType"
        static let actionParamKey = "actionParam"
        static let itemsCountKey = "itemsCount"
        static let playerEventType = "playerEventType"
        static let playerEventParams = "playerEventParams"
        static let errorKey = "error"
        static let widgetItemIdKey = "widgetItemId"
        static let widgetItemTitleKey = "widgetItemTitle"
        static let buttonIdKey = "buttonId"
        static let buttonNameKey = "buttonName"
        static let appMetadataKey = "appMetadata"
        static let newFollowingStateKey = "newFollowingState"
        static let followEntityIdKey = "followEntityId"
    }
    
    // MARK: - Data Load Events
    
    /**
     * Builds parameters for data load started events
     */
    static func buildDataLoadStartedParams(playerType: BlazePlayerType, sourceId: String?) -> [String: AnyHashable] {
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId
        ]
    }
    
    /**
     * Builds parameters for data load completed events
     */
    static func buildDataLoadCompletedParams(
        playerType: BlazePlayerType,
        sourceId: String?,
        itemsCount: Int,
        result: BlazeResult
    ) -> [String: AnyHashable] {
        var params: [String: AnyHashable] = [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId,
            Constants.itemsCountKey: itemsCount
        ]
        
        if case .failure(let error) = result {
            params[Constants.errorKey] = error.toReactValue
        }
        
        return params
    }
    
    // MARK: - Player Events
    
    /**
     * Builds parameters for player did appear events
     */
    static func buildPlayerDidAppearParams(playerType: BlazePlayerType, sourceId: String?) -> [String: AnyHashable] {
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId
        ]
    }
    
    /**
     * Builds parameters for player did dismiss events
     */
    static func buildPlayerDidDismissParams(playerType: BlazePlayerType, sourceId: String?) -> [String: AnyHashable] {
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId
        ]
    }
    
    // MARK: - CTA Events
    
    /**
     * Builds parameters for trigger CTA events
     */
    static func buildTriggerCTAParams(
        playerType: BlazePlayerType,
        sourceId: String?,
        actionType: BlazeCTAActionType,
        actionParam: String
    ) -> [String: AnyHashable] {
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId,
            Constants.actionTypeKey: actionType.toReactValue,
            Constants.actionParamKey: actionParam
        ]
    }
    
    /**
     * Builds parameters for trigger player body text link events
     */
    static func buildTriggerPlayerBodyTextLinkParams(
        playerType: BlazePlayerType,
        sourceId: String?,
        actionParam: String
    ) -> [String: AnyHashable] {
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId,
            Constants.actionParamKey: actionParam
        ]
    }
    
    // MARK: - Player Event Triggered
    
    /**
     * Builds parameters for player event triggered events
     */
    static func buildPlayerEventTriggeredParams(
        playerType: BlazePlayerType,
        sourceId: String?,
        event: BlazePlayerEvent
    ) -> [String: AnyHashable]? {
        guard let eventType = event.toReactEventType,
              let eventParams = event.toReactEventParams else {
            return nil
        }
        
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId,
            Constants.playerEventType: eventType,
            Constants.playerEventParams: eventParams
        ]
    }
    
    // MARK: - Custom Action Button
    
    /**
     * Builds parameters for trigger custom action button events
     */
    static func buildTriggerCustomActionButtonParams(
        playerType: BlazePlayerType,
        sourceId: String?,
        buttonParams: BlazePlayerCustomActionButtonParams
    ) -> [String: AnyHashable] {
        var params: [String: AnyHashable] = [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId,
            Constants.buttonIdKey: buttonParams.id,
            Constants.buttonNameKey: buttonParams.name
        ]
        
        let appMetadata = buttonParams.appMetadata
        if !appMetadata.isEmpty {
            params[Constants.appMetadataKey] = appMetadata
        }
        
        return params
    }
    
    // MARK: - Read Status Changed
    
    static func buildReadStatusChangedParams(
        playerType: BlazePlayerType,
        sourceId: String?,
        dataSourceStringRepresentation: String,
        isEntireContentRead: Bool,
        itemReadStatus: [String: Bool]
    ) -> [String: AnyHashable] {
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId,
            "dataSourceStringRepresentation": dataSourceStringRepresentation,
            "isEntireContentRead": isEntireContentRead,
            "itemReadStatus": itemReadStatus
        ]
    }
    
    // MARK: - Follow Entity Clicked
    
    static func buildFollowEntityClickedParams(
        playerType: BlazePlayerType,
        sourceId: String?,
        newFollowingState: Bool,
        followEntityId: String
    ) -> [String: AnyHashable] {
        return [
            Constants.playerTypeKey: playerType.toReactValue,
            Constants.sourceIdKey: sourceId,
            Constants.newFollowingStateKey: newFollowingState,
            Constants.followEntityIdKey: followEntityId
        ]
    }

    // MARK: - Widget Item Clicked
    
    /**
     * Builds parameters for widget item clicked events
     */
    static func buildWidgetItemClickedParams(
        sourceId: String?,
        widgetItemId: String,
        widgetItemTitle: String?
    ) -> [String: AnyHashable] {
        return [
            Constants.sourceIdKey: sourceId,
            Constants.widgetItemIdKey: widgetItemId,
            Constants.widgetItemTitleKey: widgetItemTitle
        ]
    }
} 
