import UIKit

class ViewController: UIViewController {
    
    private let textField = UITextField()
    private var isFirstKeyboardAppearance = true
    private var accessoryView: AnimatedAccessoryView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        setupTextField()
        setupKeyboardAccessoryView()
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillShow),
                                               name: UIResponder.keyboardWillShowNotification,
                                               object: nil)
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillHide),
                                               name: UIResponder.keyboardWillHideNotification,
                                               object: nil)
    }
    
    private func setupTextField() {
        textField.borderStyle = .roundedRect
        textField.placeholder = "ここに入力"
        textField.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textField)
        
        NSLayoutConstraint.activate([
            textField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            textField.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            textField.widthAnchor.constraint(equalToConstant: 250),
            textField.heightAnchor.constraint(equalToConstant: 40)
        ])
    }
    
    private func setupKeyboardAccessoryView() {
        accessoryView = AnimatedAccessoryView(closeAction: { [weak self] in
            self?.view.endEditing(true)
        })
        textField.inputAccessoryView = accessoryView
    }

    @objc private func keyboardWillShow() {
        if isFirstKeyboardAppearance {
            isFirstKeyboardAppearance = false
            accessoryView.animateButtonIn()
        }
    }
    
    @objc private func keyboardWillHide() {
        isFirstKeyboardAppearance = true
        accessoryView.resetButton()
    }
}

class AnimatedAccessoryView: UIView {
    private var closeButtonBottomConstraint: NSLayoutConstraint!
    private var closeAction: (() -> Void)?
    
    private let closeContainer: UIView = {
        let v = UIView()
        v.alpha = 0
        let btn = UIButton(type: .system)
        btn.setTitle("閉じる", for: .normal)
        btn.translatesAutoresizingMaskIntoConstraints = false
        v.addSubview(btn)
        NSLayoutConstraint.activate([
            btn.leadingAnchor.constraint(equalTo: v.leadingAnchor),
            btn.trailingAnchor.constraint(equalTo: v.trailingAnchor),
            btn.topAnchor.constraint(equalTo: v.topAnchor),
            btn.bottomAnchor.constraint(equalTo: v.bottomAnchor)
        ])
        return v
    }()
    
    private weak var innerButton: UIButton?
    private let viewHeight: CGFloat = 60

    init(closeAction: @escaping () -> Void) {
        self.closeAction = closeAction
        super.init(frame: .zero)
        commonInit()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func setupLayout() {
        addSubview(closeContainer)
        closeContainer.translatesAutoresizingMaskIntoConstraints = false
        closeButtonBottomConstraint = closeContainer.bottomAnchor
            .constraint(equalTo: bottomAnchor, constant: viewHeight)
        NSLayoutConstraint.activate([
            closeContainer.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            closeButtonBottomConstraint
        ])
    }
    
    private func commonInit() {
        backgroundColor = .secondarySystemBackground
        setupLayout()

        if let button = closeContainer.subviews.first as? UIButton {
            innerButton = button
            button.addTarget(self,
                             action: #selector(didTapClose),
                             for: .touchUpInside)
        }

        let tap = UITapGestureRecognizer(target: self,
                                         action: #selector(didTapClose))
        closeContainer.addGestureRecognizer(tap)
        closeContainer.isUserInteractionEnabled = true

        resetButton()
    }
    
    @objc private func didTapClose() {
        animateButtonOut { [weak self] in
            self?.closeAction?()
        }
    }
    
    func animateButtonIn() {
        closeButtonBottomConstraint.constant = -8
        UIView.animate(withDuration: 0.3,
                       delay: 0,
                       options: [.curveEaseInOut],
                       animations: {
            self.layoutIfNeeded()
            self.closeContainer.alpha = 1
        })
    }

    func animateButtonOut(completion: @escaping () -> Void) {
        closeButtonBottomConstraint.constant = viewHeight
        UIView.animate(withDuration: 0.3,
                       delay: 0,
                       options: [.curveEaseInOut],
                       animations: {
            self.layoutIfNeeded()
            self.closeContainer.alpha = 0
        }, completion: { _ in
            completion()
        })
    }

    func resetButton() {
        closeButtonBottomConstraint.constant = viewHeight
        closeContainer.alpha = 0
    }

    override var intrinsicContentSize: CGSize {
        CGSize(width: UIScreen.main.bounds.width, height: viewHeight)
    }
}