//
//  View+Accessibility.swift
//  lichunWebsocket
//
//  Comprehensive accessibility support for VoiceOver and assistive technologies
//

import SwiftUI

// MARK: - View Accessibility Extensions
extension View {
    /// Add complete accessibility support with label, hint, value, and traits
    /// - Parameters:
    ///   - label: The accessibility label (required)
    ///   - hint: Optional hint describing the result of interacting with the element
    ///   - value: Optional current value of the element
    ///   - traits: Accessibility traits to add
    /// - Returns: Modified view with accessibility information
    func accessible(
        label: String,
        hint: String? = nil,
        value: String? = nil,
        traits: AccessibilityTraits = []
    ) -> some View {
        self
            .accessibilityLabel(label)
            .if(hint != nil) { view in
                view.accessibilityHint(hint!)
            }
            .if(value != nil) { view in
                view.accessibilityValue(value!)
            }
            .if(!traits.isEmpty) { view in
                view.accessibilityAddTraits(traits)
            }
    }

    /// Mark element as a button for VoiceOver
    /// - Parameters:
    ///   - label: The button's accessibility label
    ///   - hint: Optional hint describing what the button does
    /// - Returns: Modified view marked as a button
    func accessibleButton(_ label: String, hint: String? = nil) -> some View {
        self.accessible(label: label, hint: hint, traits: .isButton)
    }

    /// Mark element as a header for navigation
    /// - Parameter label: The header's accessibility label
    /// - Returns: Modified view marked as a header
    func accessibleHeader(_ label: String) -> some View {
        self.accessible(label: label, traits: .isHeader)
    }

    /// Mark element as an image
    /// - Parameter label: The image's accessibility label
    /// - Returns: Modified view marked as an image
    func accessibleImage(_ label: String) -> some View {
        self.accessible(label: label, traits: .isImage)
    }

    /// Mark element as a link
    /// - Parameters:
    ///   - label: The link's accessibility label
    ///   - hint: Optional hint describing where the link goes
    /// - Returns: Modified view marked as a link
    func accessibleLink(_ label: String, hint: String? = nil) -> some View {
        self.accessible(label: label, hint: hint, traits: .isLink)
    }

    /// Mark element as selected
    func accessibleSelected(_ isSelected: Bool) -> some View {
        self.modifier(SelectionAccessibilityModifier(isSelected: isSelected))
    }

    /// Respect reduce motion preference
    /// - Parameters:
    ///   - animation: The animation to use
    ///   - value: The value to animate
    /// - Returns: View with animation respecting reduce motion settings
    func respectReduceMotion<T: Equatable>(animation: Animation, value: T) -> some View {
        Group {
            if AccessibilityHelpers.isReduceMotionEnabled {
                self
            } else {
                self.animation(animation, value: value)
            }
        }
    }

    /// Conditionally apply animation based on reduce motion
    func conditionalAnimation<V: Equatable>(
        _ animation: Animation?,
        value: V
    ) -> some View {
        Group {
            if AccessibilityHelpers.isReduceMotionEnabled {
                self
            } else {
                self.animation(animation, value: value)
            }
        }
    }

    /// Mark as decorative (hidden from VoiceOver)
    func decorative() -> some View {
        self.accessibilityHidden(true)
    }

    /// Group accessibility elements
    func accessibilityGroup(label: String? = nil) -> some View {
        Group {
            if let label = label {
                self
                    .accessibilityElement(children: .combine)
                    .accessibilityLabel(label)
            } else {
                self.accessibilityElement(children: .combine)
            }
        }
    }

    // NOTE: accessibilityAction and accessibilitySortPriority are built into SwiftUI
    // Duplicate methods removed to avoid conflicts
}

// MARK: - Selection Accessibility Modifier
struct SelectionAccessibilityModifier: ViewModifier {
    let isSelected: Bool

    func body(content: Content) -> some View {
        content
            .if(isSelected) { view in
                view.accessibilityAddTraits(.isSelected)
            }
    }
}

// MARK: - Accessibility Helpers
struct AccessibilityHelpers {
    /// Check if VoiceOver is currently running
    static var isVoiceOverRunning: Bool {
        UIAccessibility.isVoiceOverRunning
    }

    /// Check if reduce motion is enabled
    static var isReduceMotionEnabled: Bool {
        UIAccessibility.isReduceMotionEnabled
    }

    /// Check if bold text is enabled
    static var isBoldTextEnabled: Bool {
        UIAccessibility.isBoldTextEnabled
    }

    /// Check if reduce transparency is enabled
    static var isReduceTransparencyEnabled: Bool {
        UIAccessibility.isReduceTransparencyEnabled
    }

    /// Check if switch control is running
    static var isSwitchControlRunning: Bool {
        UIAccessibility.isSwitchControlRunning
    }

    /// Check if spoken content is enabled
    static var isSpokenContentEnabled: Bool {
        UIAccessibility.isVoiceOverRunning || UIAccessibility.isSpeakSelectionEnabled
    }

    /// Post accessibility announcement
    static func announce(_ message: String, priority: UIAccessibility.Notification = .announcement) {
        DispatchQueue.main.async {
            UIAccessibility.post(notification: priority, argument: message)
        }
    }

    /// Post screen changed announcement
    static func announceScreenChange(_ message: String? = nil) {
        DispatchQueue.main.async {
            UIAccessibility.post(notification: .screenChanged, argument: message)
        }
    }

    /// Post layout changed announcement
    static func announceLayoutChange(_ message: String? = nil) {
        DispatchQueue.main.async {
            UIAccessibility.post(notification: .layoutChanged, argument: message)
        }
    }
}

// MARK: - Accessible Card Container
struct AccessibleCard<Content: View>: View {
    let label: String
    let hint: String?
    let content: () -> Content

    init(
        label: String,
        hint: String? = nil,
        @ViewBuilder content: @escaping () -> Content
    ) {
        self.label = label
        self.hint = hint
        self.content = content
    }

    var body: some View {
        content()
            .accessibilityElement(children: .combine)
            .accessibilityLabel(label)
            .if(hint != nil) { view in
                view.accessibilityHint(hint!)
            }
    }
}

// MARK: - Accessibility Focus State
struct AccessibilityFocusModifier<Value: Hashable>: ViewModifier {
    @AccessibilityFocusState var focusedField: Value?
    let field: Value
    let trigger: Value?

    func body(content: Content) -> some View {
        content
            .accessibilityFocused($focusedField, equals: field)
            .onChange(of: trigger) { newValue in
                if newValue == field {
                    focusedField = field
                }
            }
    }
}

// MARK: - Custom Rotor Support
// NOTE: accessibilityRotor is built into SwiftUI
// Duplicate method removed to avoid conflicts

// MARK: - Accessibility Preview Helper
#if DEBUG
struct AccessibilityPreviewWrapper<Content: View>: View {
    let content: Content
    @State private var isVoiceOverSimulated = false

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        VStack {
            Toggle("Simulate VoiceOver", isOn: $isVoiceOverSimulated)
                .padding()

            content
                .environment(\.accessibilityEnabled, isVoiceOverSimulated)
        }
    }
}
#endif

// Note: `if` modifier is already defined in View+Extensions.swift
