/*
 Copyright 2016-present the Material Components for iOS authors. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

// swiftlint:disable function_body_length

import MaterialComponents.MaterialTextFields

final class TextFieldOutlinedSwiftExample: UIViewController {

  let scrollView = UIScrollView()
  var colorScheme = MDCSemanticColorScheme()
  var typographyScheme = MDCTypographyScheme()

  let name: MDCTextField = {
    let name = MDCTextField()
    name.translatesAutoresizingMaskIntoConstraints = false
    name.autocapitalizationType = .words
    name.backgroundColor = .white
    return name
  }()

  let address: MDCTextField = {
    let address = MDCTextField()
    address.translatesAutoresizingMaskIntoConstraints = false
    address.autocapitalizationType = .words
    address.backgroundColor = .white
    return address
  }()

  let city: MDCTextField = {
    let city = MDCTextField()
    city.translatesAutoresizingMaskIntoConstraints = false
    city.autocapitalizationType = .words
    city.backgroundColor = .white
    return city
  }()
  let cityController: MDCTextInputControllerOutlined

  let state: MDCTextField = {
    let state = MDCTextField()
    state.translatesAutoresizingMaskIntoConstraints = false
    state.autocapitalizationType = .allCharacters
    state.backgroundColor = .white
    return state
  }()
  let stateController: MDCTextInputControllerOutlined

  let zip: MDCTextField = {
    let zip = MDCTextField()
    zip.translatesAutoresizingMaskIntoConstraints = false
    zip.backgroundColor = .white
    return zip
  }()
  let zipController: MDCTextInputControllerOutlined

  let phone: MDCTextField = {
    let phone = MDCTextField()
    phone.translatesAutoresizingMaskIntoConstraints = false
    phone.backgroundColor = .white
    return phone
  }()

  let message: MDCMultilineTextField = {
    let message = MDCMultilineTextField()
    message.translatesAutoresizingMaskIntoConstraints = false
    message.backgroundColor = .white
    return message
  }()

  var allTextFieldControllers = [MDCTextInputControllerFloatingPlaceholder]()

  override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    cityController = MDCTextInputControllerOutlined(textInput: city)
    stateController = MDCTextInputControllerOutlined(textInput: state)
    zipController = MDCTextInputControllerOutlined(textInput: zip)
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white

    title = "Outlined Text Fields"

    setupScrollView()
    setupTextFields()

    registerKeyboardNotifications()
    addGestureRecognizer()
  }

  func setupTextFields() {
    scrollView.addSubview(name)
    let nameController = MDCTextInputControllerOutlined(textInput: name)
    name.delegate = self
    name.text = "Grace Hopper"
    nameController.placeholderText = "Name"
    nameController.helperText = "First and Last"
    allTextFieldControllers.append(nameController)

    scrollView.addSubview(address)
    let addressController = MDCTextInputControllerOutlined(textInput: address)
    address.delegate = self
    addressController.placeholderText = "Address"
    allTextFieldControllers.append(addressController)

    scrollView.addSubview(city)
    city.delegate = self
    cityController.placeholderText = "City"
    allTextFieldControllers.append(cityController)

    // In iOS 9+, you could accomplish this with a UILayoutGuide.
    // TODO: (larche) add iOS version specific implementations
    let stateZip = UIView()
    stateZip.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(stateZip)

    stateZip.addSubview(state)
    state.delegate = self
    stateController.placeholderText = "State"
    allTextFieldControllers.append(stateController)

    stateZip.addSubview(zip)
    zip.delegate = self
    zipController.placeholderText = "Zip Code"
    zipController.helperText = "XXXXX"
    allTextFieldControllers.append(zipController)

    scrollView.addSubview(phone)
    let phoneController = MDCTextInputControllerOutlined(textInput: phone)
    phone.delegate = self
    phoneController.placeholderText = "Phone Number"
    allTextFieldControllers.append(phoneController)

    scrollView.addSubview(message)
    let messageController = MDCTextInputControllerOutlinedTextArea(textInput: message)
    message.textView?.delegate = self
    #if swift(>=3.2)
      message.text = """
      This is where you could put a multi-line message like an email.

      It can even handle new lines.
      """
    #else
      message.text = "This is where you could put a multi-line message like an email. It can even handle new lines./n"
    #endif
    messageController.placeholderText = "Message"
    allTextFieldControllers.append(messageController)

    messageController.characterCountMax = 150

    var tag = 0
    for controller in allTextFieldControllers {
      guard let textField = controller.textInput as? MDCTextField else { continue }
      style(textInputController: controller);
      textField.tag = tag
      tag += 1
    }

    let views = [ "name": name,
                  "address": address,
                  "city": city,
                  "stateZip": stateZip,
                  "phone": phone,
                  "message": message ]
    var constraints = NSLayoutConstraint.constraints(withVisualFormat:
      "V:[name]-[address]-[city]-[stateZip]-[phone]-[message]",
                                                     options: [.alignAllLeading, .alignAllTrailing],
                                                     metrics: nil,
                                                     views: views)

    constraints += [NSLayoutConstraint(item: name,
                                       attribute: .leading,
                                       relatedBy: .equal,
                                       toItem: view,
                                       attribute: .leadingMargin,
                                       multiplier: 1,
                                       constant: 0)]
    constraints += [NSLayoutConstraint(item: name,
                                       attribute: .trailing,
                                       relatedBy: .equal,
                                       toItem: view,
                                       attribute: .trailingMargin,
                                       multiplier: 1,
                                       constant: 0)]
    constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:[name]|",
                                                  options: [],
                                                  metrics: nil,
                                                  views: views)

    #if swift(>=3.2)
      if #available(iOS 11.0, *) {
         constraints += [NSLayoutConstraint(item: name,
                                            attribute: .top,
                                            relatedBy: .equal,
                                            toItem: scrollView.contentLayoutGuide,
                                            attribute: .top,
                                            multiplier: 1,
                                            constant: 20),
                         NSLayoutConstraint(item: message,
                                            attribute: .bottom,
                                            relatedBy: .equal,
                                            toItem: scrollView.contentLayoutGuide,
                                            attribute: .bottomMargin,
                                            multiplier: 1,
                                            constant: -20)]
      } else {
        constraints += [NSLayoutConstraint(item: name,
                                          attribute: .top,
                                          relatedBy: .equal,
                                          toItem: scrollView,
                                          attribute: .top,
                                          multiplier: 1,
                                          constant: 20),
                       NSLayoutConstraint(item: message,
                                          attribute: .bottom,
                                          relatedBy: .equal,
                                          toItem: scrollView,
                                          attribute: .bottomMargin,
                                          multiplier: 1,
                                          constant: -20)]
      }
    #else
      constraints += [NSLayoutConstraint(item: name,
                                         attribute: .top,
                                         relatedBy: .equal,
                                         toItem: scrollView,
                                         attribute: .top,
                                         multiplier: 1,
                                         constant: 20),
                      NSLayoutConstraint(item: message,
                                         attribute: .bottom,
                                         relatedBy: .equal,
                                         toItem: scrollView,
                                         attribute: .bottomMargin,
                                         multiplier: 1,
                                         constant: -20)]
      #endif

    let stateZipViews = [ "state": state, "zip": zip ]
    constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[state(80)]-[zip]|",
                                                  options: [.alignAllTop],
                                                  metrics: nil,
                                                  views: stateZipViews)
    constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[state]|",
                                                  options: [],
                                                  metrics: nil,
                                                  views: stateZipViews)
    constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[zip]|",
                                                  options: [],
                                                  metrics: nil,
                                                  views: stateZipViews)

    NSLayoutConstraint.activate(constraints)
  }

  func setupScrollView() {
    view.addSubview(scrollView)
    scrollView.translatesAutoresizingMaskIntoConstraints = false

    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(
      withVisualFormat: "V:|[scrollView]|",
      options: [],
      metrics: nil,
      views: ["scrollView": scrollView]))
    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|",
                                                               options: [],
                                                               metrics: nil,
                                                               views: ["scrollView": scrollView]))
    let marginOffset: CGFloat = 16
    let margins = UIEdgeInsets(top: 0, left: marginOffset, bottom: 0, right: marginOffset)

    scrollView.layoutMargins = margins
  }

  func style(textInputController : MDCTextInputController) {
    MDCOutlinedTextFieldColorThemer.applySemanticColorScheme(colorScheme, to: textInputController)
    MDCTextFieldTypographyThemer.applyTypographyScheme(typographyScheme, to: textInputController)
  }

  func addGestureRecognizer() {
    let tapRecognizer = UITapGestureRecognizer(target: self,
                                               action: #selector(tapDidTouch(sender: )))
    self.scrollView.addGestureRecognizer(tapRecognizer)
  }

  // MARK: - Actions

  @objc func tapDidTouch(sender: Any) {
    self.view.endEditing(true)
  }

}

extension TextFieldOutlinedSwiftExample: UITextFieldDelegate {
  func textField(_ textField: UITextField,
                 shouldChangeCharactersIn range: NSRange,
                 replacementString string: String) -> Bool {
    guard let rawText = textField.text else {
      return true
    }

    let fullString = NSString(string: rawText).replacingCharacters(in: range, with: string)

    if textField == state {
      if let range = fullString.rangeOfCharacter(from: CharacterSet.letters.inverted),
        fullString[range].characterCount > 0 {
        stateController.setErrorText("Error: State can only contain letters",
                                     errorAccessibilityValue: nil)
      } else {
        stateController.setErrorText(nil, errorAccessibilityValue: nil)
      }
    } else if textField == zip {      if let range = fullString.rangeOfCharacter(from: CharacterSet.letters),
        fullString[range].characterCount > 0 {
        zipController.setErrorText("Error: Zip can only contain numbers",
                                   errorAccessibilityValue: nil)
      } else if fullString.characterCount > 5 {
        zipController.setErrorText("Error: Zip can only contain five digits",
                                   errorAccessibilityValue: nil)
      } else {
        zipController.setErrorText(nil, errorAccessibilityValue: nil)
      }
    } else if textField == city {
      if let range = fullString.rangeOfCharacter(from: CharacterSet.decimalDigits),
        fullString[range].characterCount > 0 {
        cityController.setErrorText("Error: City can only contain letters",
                                    errorAccessibilityValue: nil)
      } else {
        cityController.setErrorText(nil, errorAccessibilityValue: nil)
      }
    }
    return true
  }

  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    let index = textField.tag
    if index + 1 < allTextFieldControllers.count,
      let nextField = allTextFieldControllers[index + 1].textInput {
      nextField.becomeFirstResponder()
    } else {
      textField.resignFirstResponder()
    }

    return false
  }
}

extension TextFieldOutlinedSwiftExample: UITextViewDelegate {
  func textViewDidEndEditing(_ textView: UITextView) {
    print(textView.text)
  }
}

// MARK: - Keyboard Handling

extension TextFieldOutlinedSwiftExample {
  func registerKeyboardNotifications() {
    let notificationCenter = NotificationCenter.default
    notificationCenter.addObserver(
      self,
      selector: #selector(keyboardWillShow(notif:)),
      name: .UIKeyboardWillChangeFrame,
      object: nil)
    notificationCenter.addObserver(
      self,
      selector: #selector(keyboardWillShow(notif:)),
      name: .UIKeyboardWillShow,
      object: nil)
    notificationCenter.addObserver(
      self,
      selector: #selector(keyboardWillHide(notif:)),
      name: .UIKeyboardWillHide,
      object: nil)
  }

  @objc func keyboardWillShow(notif: Notification) {
    guard let frame = notif.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect else {
      return
    }
    scrollView.contentInset = UIEdgeInsets(top: 0.0,
                                           left: 0.0,
                                           bottom: frame.height,
                                           right: 0.0)
  }

  @objc func keyboardWillHide(notif: Notification) {
    scrollView.contentInset = UIEdgeInsets()
  }
}

// MARK: - Status Bar Style

extension TextFieldOutlinedSwiftExample {
  override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
  }
}

extension TextFieldOutlinedSwiftExample {
  @objc class func catalogBreadcrumbs() -> [String] {
    return ["Text Field", "Outlined Fields & Text Areas"]
  }
}
