import AnalyticsClient
import APIClient
import ComposableArchitecture
import Foundation

// MARK: - Analytics Reducer

extension ShareSheetReducer {
    struct Analytics: AnalyticsReducer {
        var source: String = "share_sheet_v2"

        // swiftlint:disable:next cyclomatic_complexity
        func analytics(before: State, after _: State, action: Action) -> Effect<Action> {
            switch action {
            case .destination(.presented(let presented)):
                switch presented {
                case .downloadScreen(.onAppear):
                    track(
                        Event(
                            category: .share,
                            actionName: .shareSheetReachedLoadingScreen,
                            actionType: .event,
                            elementType: .none
                        ),
                        sourceOverride: source
                    )

                case .assetCreation(let creationAction):
                    switch creationAction {
                    case .visualizerGallery(let visualizerAction):
                        switch visualizerAction {
                        case .delegate(.startRenderWithSelectedConfig(let config, let startTime, let endTime)):
                            track(
                                Event(
                                    category: .share,
                                    actionName: .shareAssetVisualizerCreationStart,
                                    actionType: .event,
                                    elementType: .none,
                                    elementId: config.shareAssetConfig.compositeID,
                                    context: "\(startTime.format_m_ss),\(endTime.format_m_ss)"
                                ),
                                sourceOverride: source
                            )

                        default:
                            break
                        }

                    default:
                        break
                    }

                default:
                    break
                }

            case .onAppear:
                track(
                    Event(
                        category: .share,
                        actionName: .shareSheetAppeared,
                        actionType: .event,
                        elementType: .none
                    ),
                    sourceOverride: source
                )

            case .share(let shareAction):
                switch shareAction {
                case .triggerShareActionTarget(let target):
                    var context: String?

                    if target == .system(.download), let hook = before.item as? Hook {
                        context = createShareAnalyticsContext(
                            hook: hook,
                            isUserObjectOwner: before.isCreator
                        )
                    }

                    track(
                        Event(
                            category: .share,
                            actionName: .tappedShareDestination,
                            actionType: .tap,
                            elementType: .button,
                            elementId: target.compositeID,
                            context: context
                        ),
                        sourceOverride: source
                    )
                }

            default:
                break
            }

            return .none
        }

        private func createShareAnalyticsContext(hook: Hook, isUserObjectOwner: Bool?) -> String {
            return ShareSheetAnalyticsContext(
                targetUserId: hook.user?.externalUserId,
                isUserObjectOwner: isUserObjectOwner
            ).toJsonString()
        }
    }
}

// MARK: - Analytics Context

struct ShareSheetAnalyticsContext: Codable {
    var targetUserId: String?
    var isUserObjectOwner: Bool?

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