// Copyright 2019-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.

import UIKit
import MaterialComponents.MaterialCollections
import MaterialComponents.MaterialDialogs
import MaterialComponents.MaterialDialogs_Theming 
import MaterialComponents.MaterialTextControls_FilledTextFields 
import MaterialComponents.MaterialTextControls_FilledTextFieldsTheming 
import MaterialComponents.MaterialContainerScheme
import MaterialComponents.MaterialTypographyScheme

class DialogsAccessoryExampleViewController: MDCCollectionViewController {

  @objc lazy var containerScheme: MDCContainerScheming = {
    let scheme = MDCContainerScheme()
    scheme.colorScheme = MDCSemanticColorScheme(defaults: .material201907)
    scheme.typographyScheme = MDCTypographyScheme(defaults: .material201902)
    return scheme
  }()

  let kReusableIdentifierItem = "customCell"

  var menu: [String] = []

  var handler: MDCActionHandler = { action in
    print(action.title ?? "Some Action")
  }

  override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = containerScheme.colorScheme.backgroundColor

    loadCollectionView(menu: [
      "Material Filled Text Field",
      "UI Text Field",
      "Confirmation Dialog",
      "Autolayout in Custom View",
    ])
  }

  func loadCollectionView(menu: [String]) {
    self.collectionView?.register(
      MDCCollectionViewTextCell.self, forCellWithReuseIdentifier: kReusableIdentifierItem)
    self.menu = menu
  }

  override func collectionView(
    _ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath
  ) {
    guard let alert = performActionFor(row: indexPath.row) else { return }
    self.present(alert, animated: true, completion: nil)
  }

  private func performActionFor(row: Int) -> MDCAlertController? {
    switch row {
    case 0:
      return performMDCTextField()
    case 1:
      return performUITextField()
    case 2:
      return performConfirmationDialog()
    case 3:
      return performCustomLabelWithButton()
    default:
      print("No row is selected")
      return nil
    }
  }

  // Demonstrate a custom view with MDCFilledTextField being assigned to the accessoryView API.
  // This example also demonstrates the use of autolayout in custom views.
  func performMDCTextField() -> MDCAlertController {
    let alert = MDCAlertController(title: "Rename File", message: nil)
    alert.addAction(MDCAlertAction(title: "Rename", emphasis: .medium, handler: handler))
    alert.addAction(MDCAlertAction(title: "Cancel", emphasis: .low, handler: handler))

    if let alertView = alert.view as? MDCAlertControllerView {
      alertView.contentInsets.bottom = 16.0
    }
    let view = UIView(frame: CGRect.zero)
    let label = newLabel(text: "OLD_FILE.PNG will be renamed:")

    let namefield = MDCFilledTextField()
    namefield.label.text = "New File Name"
    namefield.placeholder = "Enter a new file name"
    namefield.labelBehavior = MDCTextControlLabelBehavior.floats
    namefield.clearButtonMode = UITextField.ViewMode.whileEditing
    namefield.leadingAssistiveLabel.text = "An optional assistive message"
    namefield.applyTheme(withScheme: containerScheme)
    // Enable dynamic type.
    namefield.adjustsFontForContentSizeCategory = true
    namefield.font = UIFont.preferredFont(
      forTextStyle: .body, compatibleWith: namefield.traitCollection)
    namefield.leadingAssistiveLabel.font = UIFont.preferredFont(
      forTextStyle: .caption2, compatibleWith: namefield.traitCollection)

    label.translatesAutoresizingMaskIntoConstraints = false
    namefield.translatesAutoresizingMaskIntoConstraints = false
    view.translatesAutoresizingMaskIntoConstraints = true

    view.addSubview(label)
    view.addSubview(namefield)

    label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    label.bottomAnchor.constraint(equalTo: namefield.topAnchor, constant: -10).isActive = true

    namefield.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    namefield.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    namefield.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    alert.accessoryView = view
    alert.mdc_adjustsFontForContentSizeCategory = true  // Enable dynamic type.
    alert.applyTheme(withScheme: self.containerScheme)
    return alert
  }

  func performUITextField() -> MDCAlertController {
    let alert = MDCAlertController(title: "This is a title", message: "This is a message")
    let textField = UITextField()
    textField.placeholder = "This is a text field"
    alert.accessoryView = textField
    alert.addAction(MDCAlertAction(title: "Dismiss", emphasis: .medium, handler: handler))
    alert.mdc_adjustsFontForContentSizeCategory = true  // Enable dynamic type.
    alert.applyTheme(withScheme: self.containerScheme)
    return alert
  }

  // Demonstrate a confirmation dialog with a custom table view.
  func performConfirmationDialog() -> MDCAlertController {
    let alert = MDCAlertController(title: "Phone ringtone", message: "Please select a ringtone:")
    alert.addAction(MDCAlertAction(title: "OK", handler: handler))
    alert.addAction(MDCAlertAction(title: "Cancel", handler: handler))

    alert.accessoryView = ExampleTableSeparatorView()

    if let alertView = alert.view as? MDCAlertControllerView {
      // Zero bottom-inset ensuring the bottom separator appears immediately above the actions.
      alertView.contentInsets.bottom = 0
      // Decreasing vertical margin between the accessory view and the message
      alertView.accessoryViewVerticalInset = 8
      // Aligning the accessory view with the dialog's edge by removing all horizontal insets.
      alertView.accessoryViewHorizontalInset = -alertView.contentInsets.left
    }

    alert.mdc_adjustsFontForContentSizeCategory = true  // Enable dynamic type.
    alert.applyTheme(withScheme: self.containerScheme)
    return alert
  }

  // Demonstrate a custom accessory view with auto layout, presenting a label and a button.
  func performCustomLabelWithButton() -> MDCAlertController {
    let alert = MDCAlertController(title: "Title", message: nil)
    alert.addAction(MDCAlertAction(title: "Dismiss", emphasis: .medium, handler: handler))

    let view = UIView(frame: CGRect.zero)
    let label = newLabel(text: "Your storage is full. Your storage is full.")
    let button = MDCButton()
    button.setTitle("Learn More", for: UIControl.State.normal)
    button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 8)
    button.applyTextTheme(withScheme: containerScheme)

    label.translatesAutoresizingMaskIntoConstraints = false
    button.translatesAutoresizingMaskIntoConstraints = false
    view.translatesAutoresizingMaskIntoConstraints = true

    view.addSubview(label)
    view.addSubview(button)

    label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    label.bottomAnchor.constraint(equalTo: button.topAnchor).isActive = true

    button.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    button.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor).isActive = true
    button.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    alert.accessoryView = view
    alert.mdc_adjustsFontForContentSizeCategory = true  // Enable dynamic type.
    alert.applyTheme(withScheme: self.containerScheme)

    return alert
  }

  func newLabel(text: String) -> UILabel {
    let label = UILabel()
    label.textColor = containerScheme.colorScheme.onSurfaceColor
    label.font = containerScheme.typographyScheme.subtitle2
    label.text = text
    label.numberOfLines = 0
    return label
  }

}

// MDCCollectionViewController Data Source
extension DialogsAccessoryExampleViewController {

  override func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
  }

  override func collectionView(
    _ collectionView: UICollectionView, numberOfItemsInSection section: Int
  ) -> Int {
    return menu.count
  }

  override func collectionView(
    _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
  ) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(
      withReuseIdentifier: kReusableIdentifierItem,
      for: indexPath)
    guard let customCell = cell as? MDCCollectionViewTextCell else { return cell }

    customCell.isAccessibilityElement = true
    customCell.accessibilityTraits = .button

    let cellTitle = menu[indexPath.row]
    customCell.accessibilityLabel = cellTitle
    customCell.textLabel?.text = cellTitle

    return customCell
  }
}

// MARK: Catalog by convention
extension DialogsAccessoryExampleViewController {

  @objc class func catalogMetadata() -> [String: Any] {
    return [
      "breadcrumbs": ["Dialogs", "Dialog With Accessory View"],
      "primaryDemo": false,
      "presentable": true,
    ]
  }
}

// MARK: Snapshot Testing by Convention
extension DialogsAccessoryExampleViewController {

  func resetTests() {
    if presentedViewController != nil {
      dismiss(animated: false)
    }
  }

  @objc func testTextField() {
    resetTests()
    self.present(performUITextField(), animated: false, completion: nil)
  }

  @objc func testMDCTextField() {
    resetTests()
    self.present(performMDCTextField(), animated: false, completion: nil)
  }

  @objc func testCustomLabelWithButton() {
    resetTests()
    self.present(performCustomLabelWithButton(), animated: false, completion: nil)
  }

  @objc func testConfirmationDialog() {
    resetTests()
    self.present(performConfirmationDialog(), animated: false, completion: nil)
  }
}

// An example view with a tableview and a bottom separator.
class ExampleTableSeparatorView: UIView, UITableViewDataSource {

  let ringtones = ["Callisto", "Luna", "Phobos", "Dione"]

  let tableView: UITableView = {
    let tv = AutoSizedTableView()
    tv.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    tv.separatorStyle = .none
    tv.rowHeight = 40
    return tv
  }()

  init() {
    super.init(frame: .zero)
    setup()
  }

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

  func setup() {
    tableView.dataSource = self
    tableView.alwaysBounceVertical = false
    addSubview(tableView)

    let separator = UIView(frame: .zero)
    separator.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
    addSubview(separator)

    tableView.translatesAutoresizingMaskIntoConstraints = false
    separator.translatesAutoresizingMaskIntoConstraints = false

    NSLayoutConstraint.activate([
      tableView.topAnchor.constraint(lessThanOrEqualTo: self.topAnchor),
      tableView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
      tableView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
      separator.topAnchor.constraint(equalTo: tableView.bottomAnchor),
      separator.leadingAnchor.constraint(equalTo: self.leadingAnchor),
      separator.trailingAnchor.constraint(equalTo: self.trailingAnchor),
      separator.bottomAnchor.constraint(equalTo: self.bottomAnchor),
      separator.heightAnchor.constraint(equalToConstant: 2),
    ])

    tableView.reloadData()
    let currentRingtone = IndexPath(row: 1, section: 0)
    tableView.selectRow(at: currentRingtone, animated: false, scrollPosition: .top)
  }

  func numberOfSections(in tableView: UITableView) -> Int {
    return 1
  }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return ringtones.count
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = ringtones[indexPath.row]
    cell.indentationLevel = 1
    return cell
  }
}

// A tableview with intrinsic size that matches its content size.
final class AutoSizedTableView: UITableView {
  override var contentSize: CGSize {
    didSet {
      invalidateIntrinsicContentSize()
    }
  }

  override var intrinsicContentSize: CGSize {
    layoutIfNeeded()
    return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
  }
}
