//
//  Text+DynamicType.swift
//  lichunWebsocket
//
//  Dynamic Type support for accessibility
//

import SwiftUI

// MARK: - Text Dynamic Type Extensions
extension Text {
    /// Scale text to fit within available space
    /// - Parameters:
    ///   - min: Minimum scale factor (default: 0.5)
    ///   - max: Maximum scale factor (default: 1.5)
    /// - Returns: Text view that scales to fit
    func scaledToFit(min: CGFloat = 0.5, max: CGFloat = 1.5) -> some View {
        self
            .minimumScaleFactor(min)
            .lineLimit(nil)
    }

    /// Apply dynamic type with specific size category limits
    func dynamicTypeSize(min: DynamicTypeSize, max: DynamicTypeSize) -> some View {
        self.dynamicTypeSize(min...max)
    }

    /// Apply accessibility-friendly text styling
    func accessibleText(
        lineLimit: Int? = nil,
        allowsTightening: Bool = false
    ) -> some View {
        Group {
            if let lineLimit = lineLimit {
                self
                    .lineLimit(lineLimit)
                    .if(allowsTightening) { text in
                        text.allowsTightening(true)
                    }
            } else {
                self
                    .if(allowsTightening) { text in
                        text.allowsTightening(true)
                    }
            }
        }
    }

    /// Apply bold text if accessibility bold text is enabled
    func accessibilityBoldText() -> Text {
        if AccessibilityHelpers.isBoldTextEnabled {
            return self.bold()
        }
        return self
    }
}

// MARK: - View Dynamic Type Extensions
extension View {
    /// Limit dynamic type size range
    /// - Parameter range: The allowed range of dynamic type sizes
    /// - Returns: View with limited dynamic type range
    func dynamicTypeSize(range: ClosedRange<DynamicTypeSize>) -> some View {
        self.dynamicTypeSize(range)
    }

    /// Limit dynamic type to specific min and max
    func limitDynamicType(
        min: DynamicTypeSize = .small,
        max: DynamicTypeSize = .accessibility3
    ) -> some View {
        self.dynamicTypeSize(min...max)
    }

    /// Apply standard dynamic type limits for most content
    func standardDynamicType() -> some View {
        self.dynamicTypeSize(.small...(.accessibility2))
    }

    /// Apply strict dynamic type limits for fixed layouts
    func strictDynamicType() -> some View {
        self.dynamicTypeSize(.small...(.large))
    }
}

// MARK: - Adaptive Font Sizes
struct AdaptiveFontSize {
    /// Get adaptive font size based on current Dynamic Type setting
    static func size(for textStyle: Font.TextStyle, defaultSize: CGFloat) -> CGFloat {
        let contentSize = UIApplication.shared.preferredContentSizeCategory

        switch contentSize {
        case .extraSmall:
            return defaultSize * 0.8
        case .small:
            return defaultSize * 0.9
        case .medium:
            return defaultSize
        case .large:
            return defaultSize * 1.1
        case .extraLarge:
            return defaultSize * 1.2
        case .extraExtraLarge:
            return defaultSize * 1.3
        case .extraExtraExtraLarge:
            return defaultSize * 1.4
        case .accessibilityMedium:
            return defaultSize * 1.6
        case .accessibilityLarge:
            return defaultSize * 1.8
        case .accessibilityExtraLarge:
            return defaultSize * 2.0
        case .accessibilityExtraExtraLarge:
            return defaultSize * 2.2
        case .accessibilityExtraExtraExtraLarge:
            return defaultSize * 2.4
        default:
            return defaultSize
        }
    }
}

// MARK: - Readable Content Guide
extension View {
    /// Constrain content to readable width for better accessibility
    func readableContentGuide() -> some View {
        self.frame(maxWidth: 672) // Standard readable width
    }

    /// Apply readable width conditionally based on device size
    func adaptiveReadableWidth() -> some View {
        GeometryReader { geometry in
            self.frame(maxWidth: min(geometry.size.width, 672))
                .frame(width: geometry.size.width)
        }
    }
}

// MARK: - Adaptive Spacing
struct AdaptiveSpacing {
    /// Get adaptive spacing based on Dynamic Type size
    static func spacing(base: CGFloat) -> CGFloat {
        let contentSize = UIApplication.shared.preferredContentSizeCategory

        switch contentSize {
        case .accessibilityMedium, .accessibilityLarge,
             .accessibilityExtraLarge, .accessibilityExtraExtraLarge,
             .accessibilityExtraExtraExtraLarge:
            return base * 1.5
        case .extraExtraLarge, .extraExtraExtraLarge:
            return base * 1.3
        case .extraLarge:
            return base * 1.1
        default:
            return base
        }
    }
}

// MARK: - Accessibility-Aware Padding
extension View {
    /// Apply padding that scales with Dynamic Type
    func accessiblePadding(_ edges: Edge.Set = .all, base: CGFloat = AppSpacing.md) -> some View {
        self.padding(edges, AdaptiveSpacing.spacing(base: base))
    }

    /// Apply adaptive spacing that scales with Dynamic Type
    func adaptiveSpacing(_ spacing: CGFloat) -> some View {
        self.padding(AdaptiveSpacing.spacing(base: spacing))
    }
}

// MARK: - Text Contrast Enhancement
extension View {
    /// Enhance text contrast for accessibility
    func enhancedContrast() -> some View {
        self.modifier(EnhancedContrastModifier())
    }
}

struct EnhancedContrastModifier: ViewModifier {
    @Environment(\.colorSchemeContrast) var contrast

    func body(content: Content) -> some View {
        if contrast == .increased {
            content
                .fontWeight(.semibold)
        } else {
            content
        }
    }
}

// MARK: - Preview
#if DEBUG
struct DynamicType_Previews: PreviewProvider {
    static var previews: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: AppSpacing.lg) {
                Text("Dynamic Type Test")
                    .font(.appTitle)
                    .accessibleHeader("Dynamic Type Test")

                Text("This text scales with Dynamic Type settings.")
                    .font(.appBody)
                    .scaledToFit()

                Text("This text has limited scaling.")
                    .font(.appBody)
                    .limitDynamicType(min: .small, max: .large)

                Text("Bold Text Enhancement")
                    .accessibilityBoldText()

                HStack {
                    Text("Readable")
                    Spacer()
                    Text("Content")
                }
                .readableContentGuide()

                Text("Enhanced Contrast")
                    .enhancedContrast()
            }
            .accessiblePadding()
        }
        .background(AppColors.background)
        .previewLayout(.sizeThatFits)
        .environment(\.sizeCategory, .accessibilityLarge)
    }
}
#endif
