import AnalyticsClient
import APIClient
import ComposableArchitecture
import Foundation
import Utilities

extension HooksPostScreenReducer {
    struct Analytics: AnalyticsReducer {
        var source: String = "hooks_post"
        
        // swiftlint:disable:next cyclomatic_complexity
        func analytics(before: State, after _: State, action: Action) -> Effect<Action> {
            switch action {
            case .backTapped:
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .backTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )
                
            case .confirmGoBack:
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .confirmBackTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )

            case .doneTapped:
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .doneTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )

            case .showLyricsToggled(let isToggled):
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .showLyricsToggled,
                        actionType: .tap,
                        elementType: .toggle,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: isToggled,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )
                
            case .allowCommentsToggled(let isToggled):
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .allowCommentsToggled,
                        actionType: .tap,
                        elementType: .toggle,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: isToggled
                        )
                    )
                )
                
            case .previewTapped:
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .previewTapped,
                        actionType: .tap,
                        elementType: .hookPreview,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )

            case .destination(.presented(.fullscreenPreview(.closeTapped))):
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .previewCloseTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )

            case .publishClipTapped:
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .publishClipTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )
                
            case .dismissPublishClipPopUp:
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .publishClipCloseTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )
                
            case .postHookTapped:
                track(
                    Event(
                        category: .hooksPost,
                        actionName: .postHookTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.clipId.remoteId,
                        context: HooksPostAnalyticsContext.createContext(
                            videoId: before.localVideoURL?.absoluteString,
                            clipId: before.clipId.remoteId,
                            caption: before.caption,
                            showLyricsEnabled: before.showLyrics,
                            allowCommentsEnabled: before.allowComments
                        )
                    )
                )
                
            default:
                break
            }
            return .none
        }
    }
}

struct HooksPostAnalyticsContext: Codable {
    var videoId: String?
    var clipId: String?
    var caption: String?
    var showLyricsEnabled: Bool?
    var allowCommentsEnabled: Bool?

    init(
        videoId: String? = nil,
        clipId: String? = nil,
        caption: String? = nil,
        showLyricsEnabled: Bool? = nil,
        allowCommentsEnabled: Bool? = nil
    ) {
        self.videoId = videoId
        self.clipId = clipId
        self.caption = caption
        self.showLyricsEnabled = showLyricsEnabled
        self.allowCommentsEnabled = allowCommentsEnabled
    }

    func toJsonString() -> String {
        guard let data = try? JSONEncoder().encode(self),
              let jsonString = String(data: data, encoding: .utf8)
        else {
            return "{}"
        }
        return jsonString
    }

    static func createContext(
        videoId: String? = nil,
        clipId: String? = nil,
        caption: String? = nil,
        showLyricsEnabled: Bool? = nil,
        allowCommentsEnabled: Bool? = nil
    ) -> String {
        HooksPostAnalyticsContext(
            videoId: videoId,
            clipId: clipId,
            caption: caption,
            showLyricsEnabled: showLyricsEnabled,
            allowCommentsEnabled: allowCommentsEnabled
        ).toJsonString()
    }
}

