//
//  FocusableTextField.swift
//  Tusker
//
//  Created by Shadowfacts on 11/2/20.
//  Copyright © 2020 Shadowfacts. All rights reserved.
//

import SwiftUI

struct FocusableTextField: UIViewRepresentable {
    typealias UIViewType = UITextField

    let placeholder: String
    let text: Binding<String>
    let becomeFirstResponder: Binding<Bool>?
    let onCommit: (() -> Void)?
    
    init(placeholder: String, text: Binding<String>, becomeFirstResponder: Binding<Bool>? = nil, onCommit: (() -> Void)? = nil) {
        self.placeholder = placeholder
        self.text = text
        self.becomeFirstResponder = becomeFirstResponder
        self.onCommit = onCommit
    }
    
    func makeUIView(context: Context) -> UITextField {
        let field = UITextField()
        field.delegate = context.coordinator
        field.addTarget(context.coordinator, action: #selector(Coordinator.didChange(_:)), for: .editingChanged)
        field.addTarget(context.coordinator, action: #selector(Coordinator.didEnd(_:)), for: .primaryActionTriggered)
        return field
    }
    
    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.placeholder = placeholder
        uiView.text = text.wrappedValue
        
        context.coordinator.text = text
        context.coordinator.onCommit = onCommit
        
        if becomeFirstResponder?.wrappedValue == true {
            DispatchQueue.main.async {
                uiView.becomeFirstResponder()
                becomeFirstResponder?.wrappedValue = false
            }
        }
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(text: text)
    }
    
    class Coordinator: NSObject, UITextFieldDelegate {
        var text: Binding<String>
        var onCommit: (() -> Void)?
        
        init(text: Binding<String>) {
            self.text = text
        }
        
        @objc func didChange(_ textField: UITextField) {
            text.wrappedValue = textField.text ?? ""
        }
        
        @objc func didEnd(_ textField: UITextField) {
            onCommit?()
        }
        
        func textFieldDidEndEditing(_ textField: UITextField) {
            onCommit?()
        }
    }
}
