import ComposableArchitecture
import HapticsClient
import Sharing
import StatsigClient
import SwiftUI
import Utilities

public extension View {
    func haptic(_ style: HapticStyle, trigger: some Equatable) -> some View {
        self.onChange(of: trigger) { _, _ in
            @Dependency(\.hapticsClient) var hapticsClient
            hapticsClient.trigger(style)
        }
    }

    func hapticImpact(_ style: ImpactStyle, trigger: some Equatable) -> some View {
        self.haptic(.impact(style), trigger: trigger)
    }

    func hapticNotification(_ type: NotificationType, trigger: some Equatable) -> some View {
        self.haptic(.notification(type), trigger: trigger)
    }

    func hapticSelection(trigger: some Equatable) -> some View {
        self.haptic(.selection, trigger: trigger)
    }

    func sensoryFeedbackIfEnabled<T: Equatable>(_ feedback: SensoryFeedback, trigger: T) -> some View {
        self.modifier(ConditionalSensoryFeedbackModifier(feedback: feedback, trigger: trigger))
    }

    func sensoryFeedbackIfEnabled<T: Equatable>(
        trigger: T,
        _ feedback: @escaping (T, T) -> SensoryFeedback?
    ) -> some View {
        self.modifier(ConditionalSensoryFeedbackIntensityModifier(trigger: trigger, feedback: feedback))
    }
}

private struct ConditionalSensoryFeedbackModifier<T: Equatable>: ViewModifier {
    let feedback: SensoryFeedback
    let trigger: T

    @Shared(.appStorage(.hapticsEnabled)) var hapticsEnabled: Bool = true

    func body(content: Content) -> some View {
        if hapticsEnabled && FeatureFlag.legacy.hapticsClientEnabled {
            content.sensoryFeedback(feedback, trigger: trigger)
        } else {
            // Fallback behavior is triggering haptics
            content.sensoryFeedback(feedback, trigger: trigger)
        }
    }
}

private struct ConditionalSensoryFeedbackIntensityModifier<T: Equatable>: ViewModifier {
    let trigger: T
    let feedback: (T, T) -> SensoryFeedback?

    @Shared(.appStorage(.hapticsEnabled)) var hapticsEnabled: Bool = true

    func body(content: Content) -> some View {
        if hapticsEnabled && FeatureFlag.legacy.hapticsClientEnabled {
            content.sensoryFeedback(trigger: trigger, feedback)
        } else {
            // Fallback behavior is triggering haptics
            content.sensoryFeedback(trigger: trigger, feedback)
        }
    }
}
