//
//  SQTextFieldModifiers.swift
//  Allovoisins
//
//  Created by Claude on 22/10/2025.
//  Copyright © 2025 AlloVoisins. All rights reserved.
//

import SwiftUI

// MARK: - View Modifiers

/// View modifiers for Sequoia TextField components.
/// These modifiers allow chainable configuration, similar to native SwiftUI components.
///
/// Example usage:
/// ```swift
/// SQTextField("Name", text: $name)
///     .sqPlaceholder("Enter your name")
///     .sqMinCharacters(2)
///     .sqMaxCharacters(50)
///     .sqError($nameError)
/// ```

// MARK: - Individual Modifier Structs

private struct SQPlaceholderModifier: ViewModifier {
    let placeholder: String
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.placeholder = placeholder
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQMinCharactersModifier: ViewModifier {
    let count: Int
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.minCharacters = count
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQMaxCharactersModifier: ViewModifier {
    let count: Int
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.maxCharacters = count
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQHelperTextModifier: ViewModifier {
    let text: String
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.helperText = text
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQTooltipTextModifier: ViewModifier {
    let text: String
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.tooltipText = text
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQErrorModifier: ViewModifier {
    let error: Binding<SQFormFieldError>
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.error = error
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQOptionalModifier: ViewModifier {
    let isOptional: Bool
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.isOptional = isOptional
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQShowCharacterCountModifier: ViewModifier {
    let show: Bool
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.showCharacterCount = show
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQBackgroundColorModifier: ViewModifier {
    let color: Color
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.backgroundColor = color
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQKeyboardTypeModifier: ViewModifier {
    let type: UIKeyboardType
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.keyboardType = type
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQInfoActionModifier: ViewModifier {
    let action: () -> Void
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.infoAction = action
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQDisabledModifier: ViewModifier {
    let isDisabled: Bool
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.isDisabled = isDisabled
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

private struct SQIsLoadingModifier: ViewModifier {
    let isLoading: Binding<Bool>
    @Environment(\.sqTextFieldConfiguration) var config

    func body(content: Content) -> some View {
        var newConfig = config
        newConfig.isLoading = isLoading
        return content.environment(\.sqTextFieldConfiguration, newConfig)
    }
}

// MARK: - Public Extension

extension View {
    /// Sets the placeholder text for the text field.
    func sqPlaceholder(_ text: String) -> some View {
        modifier(SQPlaceholderModifier(placeholder: text))
    }

    /// Sets the minimum number of characters required.
    func sqMinCharacters(_ count: Int) -> some View {
        modifier(SQMinCharactersModifier(count: count))
    }

    /// Sets the maximum number of characters allowed.
    func sqMaxCharacters(_ count: Int) -> some View {
        modifier(SQMaxCharactersModifier(count: count))
    }

    /// Sets helper text to display below the text field.
    func sqHelperText(_ text: String) -> some View {
        modifier(SQHelperTextModifier(text: text))
    }

    /// Sets tooltip text with an info icon.
    func sqTooltipText(_ text: String) -> some View {
        modifier(SQTooltipTextModifier(text: text))
    }

    /// Binds an error to the text field for validation display.
    func sqError(_ error: Binding<SQFormFieldError>) -> some View {
        modifier(SQErrorModifier(error: error))
    }

    /// Marks the field as optional with an "Optionnel" badge.
    func sqOptional(_ isOptional: Bool = true) -> some View {
        modifier(SQOptionalModifier(isOptional: isOptional))
    }

    /// Marks the field as optional with an "Optionnel" badge (alias for sqOptional).
    func sqIsOptional(_ isOptional: Bool = true) -> some View {
        modifier(SQOptionalModifier(isOptional: isOptional))
    }

    /// Controls the visibility of the character counter.
    func sqShowCharacterCount(_ show: Bool = true) -> some View {
        modifier(SQShowCharacterCountModifier(show: show))
    }

    /// Sets the background color of the text field.
    func sqBackgroundColor(_ color: Color) -> some View {
        modifier(SQBackgroundColorModifier(color: color))
    }

    /// Sets the keyboard type for the text field.
    func sqKeyboardType(_ type: UIKeyboardType) -> some View {
        modifier(SQKeyboardTypeModifier(type: type))
    }

    /// Sets an action to execute when the info icon is tapped.
    func sqInfoAction(_ action: @escaping () -> Void) -> some View {
        modifier(SQInfoActionModifier(action: action))
    }

    /// Disables the text field.
    func sqDisabled(_ isDisabled: Bool = true) -> some View {
        modifier(SQDisabledModifier(isDisabled: isDisabled))
    }

    /// Shows a loading indicator in the text field.
    func sqIsLoading(_ isLoading: Binding<Bool>) -> some View {
        modifier(SQIsLoadingModifier(isLoading: isLoading))
    }
}
