//
//  SQTextField.swift
//  Sequoia
//
//  Created by Victor on 10/10/2024.
//

import SwiftUI

struct SQTextField: View {
    var label: String
    var placeholder: String
    var errorText: String
    var icon: SQIcon?
    var isDisabled: Bool = false
    var isOptional: Bool = false
    var isInError: Bool = false
    var minCharacters: Int?
    var maxCharacters: Int?
    @Binding var text: String
    @FocusState private var isFocused: Bool
    let infoAction: (() -> Void)?
    let iconAction: (() -> Void)?

    private var accentColor: Color = .sqNeutral(80)

    init(_ label: String, placeholder: String, errorText: String = "", text: Binding<String>, icon: SQIcon? = nil, isDisabled: Bool = false, isOptional: Bool = false, isInError: Bool = false, minCharacters: Int? = nil, maxCharacters: Int? = nil, infoAction: (() -> Void)? = nil, iconAction: (() -> Void)? = nil) {
        self.label = label
        self.placeholder = placeholder
        self.errorText = errorText
        self._text = text
        self.icon = icon
        self.isDisabled = isDisabled
        self.isOptional = isOptional
        self.isInError = isInError
        self.minCharacters = minCharacters
        self.maxCharacters = maxCharacters
        self.infoAction = infoAction
        self.iconAction = iconAction
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack(spacing: 8) {
                SQText(label)
                if let infoAction = infoAction {
                    Button {
                        infoAction()
                    } label: {
                        SQIcon(.circle_info, color: .sqNeutral(80))
                    }
                }
                Spacer()
                if isOptional {
                    SQText("Optionnel", size: 12, textColor: .sqNeutral(50))
                }
            }
            // TextField
            HStack(spacing: 4) {
                TextField(placeholder, text: Binding(
                    get: { self.text },
                    set: { self.text = String($0.prefix(self.maxCharacters ?? Int.max)) }
                ))
                .font(.sq(.medium))
                .tint(accentColor)
                if let icon = icon {
                    Button {
                        iconAction?()
                    } label: {
                        icon
                    }
                }
            }
            .padding(16)
            .foregroundStyle(Color.sqNeutral())
            .background(isDisabled ? Color.sqNeutral(10) : .clear)
            .overlay(
                RoundedRectangle(cornerRadius: 8)
                    .inset(by: 0.5)
                    .stroke(isFocused ? accentColor : isDisabled ? Color.sqNeutral(20) : Color.sqNeutral(30), lineWidth: 1)
            )
            .focused($isFocused)
            .disabled(isDisabled)
            HStack(spacing: 16) {
                // HStack error
                if isInError {
                    HStack(spacing: 4) {
                        SQIcon(.circle_exclamation, customSize: 12, type: .solid, color: .sqSemanticRed)
                        SQText(errorText, size: 12, textColor: .sqSemanticRed)
                    }
                }
                Spacer()
                if !characterCountText.isEmpty {
                    SQText(characterCountText, size: 12, textColor: .sqNeutral(50))
                }
            }
        }
    }

    private var characterCountText: String {
        let count = text.count
        if let min = minCharacters, count < min {
            return "\(count)/\(min)"
        } else if let max = maxCharacters {
            return count >= (max * 4 / 5) ? "\(count)/\(max)" : "\(count)"
        }
        return ""
    }
}

#Preview {
    VStack(spacing: 32) {
        SQTextField("Label name", placeholder: "Placeholder", text: .constant("Bonjour, "), minCharacters: 20)
        SQTextField("Label name", placeholder: "Placeholder", text: .constant(""), isOptional: true)
        SQTextField("Label name", placeholder: "Placeholder", text: .constant(""), isDisabled: true)
    }
    .padding()
}
