//
//  View+Haptics.swift
//  lichunWebsocket
//
//  View extensions for easy haptic feedback integration
//

import SwiftUI

// MARK: - Haptic Style Enum
enum HapticStyle {
    case light, medium, heavy, soft, rigid
    case success, warning, error

    var impactStyle: UIImpactFeedbackGenerator.FeedbackStyle? {
        switch self {
        case .light: return .light
        case .medium: return .medium
        case .heavy: return .heavy
        case .soft: return .soft
        case .rigid: return .rigid
        default: return nil
        }
    }

    var notificationType: UINotificationFeedbackGenerator.FeedbackType? {
        switch self {
        case .success: return .success
        case .warning: return .warning
        case .error: return .error
        default: return nil
        }
    }
}

// MARK: - View Haptic Extensions
extension View {
    /// Add haptic feedback on tap gesture
    /// - Parameter style: The haptic style to use
    /// - Returns: Modified view with haptic feedback
    func hapticOnTap(style: HapticStyle = .light) -> some View {
        self.simultaneousGesture(
            TapGesture().onEnded { _ in
                performHaptic(style: style)
            }
        )
    }

    /// Add haptic feedback when a value changes
    /// - Parameters:
    ///   - value: The value to observe
    ///   - style: The haptic style to use
    /// - Returns: Modified view with haptic feedback on change
    func hapticOnChange<V: Equatable>(of value: V, perform style: HapticStyle = .light) -> some View {
        self.onChange(of: value) { _ in
            performHaptic(style: style)
        }
    }

    /// Add success haptic feedback when a value changes
    func hapticOnSuccess<V: Equatable>(of value: V) -> some View {
        self.onChange(of: value) { _ in
            performHaptic(style: .success)
        }
    }

    /// Add error haptic feedback when a value changes
    func hapticOnError<V: Equatable>(of value: V) -> some View {
        self.onChange(of: value) { _ in
            performHaptic(style: .error)
        }
    }

    /// Add warning haptic feedback when a value changes
    func hapticOnWarning<V: Equatable>(of value: V) -> some View {
        self.onChange(of: value) { _ in
            performHaptic(style: .warning)
        }
    }

    /// Perform haptic feedback (internal helper)
    private func performHaptic(style: HapticStyle) {
        if let notificationType = style.notificationType {
            hapticNotification(type: notificationType)
        } else if let impactStyle = style.impactStyle {
            hapticFeedback(style: impactStyle)
        }
    }
}

// MARK: - Haptic Button Wrapper
struct HapticButton<Label: View>: View {
    let action: () -> Void
    let style: HapticStyle
    let label: () -> Label

    init(
        style: HapticStyle = .light,
        action: @escaping () -> Void,
        @ViewBuilder label: @escaping () -> Label
    ) {
        self.action = action
        self.style = style
        self.label = label
    }

    var body: some View {
        Button {
            performHaptic()
            action()
        } label: {
            label()
        }
    }

    private func performHaptic() {
        if let notificationType = style.notificationType {
            hapticNotification(type: notificationType)
        } else if let impactStyle = style.impactStyle {
            hapticFeedback(style: impactStyle)
        }
    }
}

// MARK: - Selection Haptic
extension View {
    /// Add selection haptic feedback (like a dial)
    func selectionHaptic() -> some View {
        self.simultaneousGesture(
            TapGesture().onEnded { _ in
                let generator = UISelectionFeedbackGenerator()
                generator.selectionChanged()
            }
        )
    }
}
