import AnalyticsClient
import APIClient
import ComposableArchitecture
import Foundation
import Utilities

extension CommentsSheetReducer {
    struct Analytics: AnalyticsReducer {
        var source: String = "comments_sheet"

        func analytics(before: State, after _: State, action: Action) -> Effect<Action> {
            switch action {
            case .onUserCommentTextUpdated(let oldValue, let newValue):
                // Check if user just started typing (transition from empty to non-empty)
                let wasEmpty = oldValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
                let isNowNonEmpty = !newValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty

                // Only track once per typing session
                if wasEmpty && isNowNonEmpty && !before.hasStartedTypingSession {
                    let elementType: Event.ElementType = before.item is Hook ? .hook : .clip
                    let elementId = getElementId(from: before.item)

                    track(
                        Event(
                            category: .hooksPlayer,
                            actionName: .commentBeginWrite,
                            actionType: .textEntry,
                            elementType: elementType,
                            elementId: elementId,
                            context: createHookAnalyticsContext(item: before.item, source: before.source).toJsonString()
                        )
                    )
                }

            default:
                break
            }
            return .none
        }

        private func createHookAnalyticsContext<T: Commentable>(item: T, source: HooksFeedSource? = nil) -> HookAnalyticsContext {
            if let hook = item as? Hook {
                if let source = source {
                    let analytics = source.analyticsContext
                    return hook.analyticsContext(
                        contextType: analytics.contextType,
                        contextId: analytics.contextId,
                        sourceUrl: analytics.sourceUrl
                    )
                } else {
                    return hook.analyticsContext(contextType: "Unknown", contextId: nil)
                }
            } else {
                return HookAnalyticsContext(
                    recommendationItemId: nil,
                    contextType: "Unknown",
                    contextId: nil
                )
            }
        }

        private func getElementId<T: Commentable>(from item: T) -> String? {
            let mirror = Mirror(reflecting: item)

            if let idProperty = mirror.children.first(where: { $0.label == "id" }) {
                if let stringId = idProperty.value as? String {
                    return stringId
                }
                return String(describing: idProperty.value)
            }

            return nil
        }
    }
}
