// Copyright 2020 Google LLC. 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 GooglePlaces
import UIKit

/// All other autocomplete demo classes inherit from this class. This class optionally adds a button
/// to present the autocomplete widget, and displays the results when these are selected.
class AutocompleteBaseViewController: UIViewController {
  private lazy var textView: UITextView = {
    let textView = UITextView()
    textView.isEditable = false
    textView.textContainerInset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
    return textView
  }()

  private lazy var photoButton: UIBarButtonItem = {
    return UIBarButtonItem(
      title: "Photos", style: .plain, target: self, action: #selector(showPhotos))
  }()

  private lazy var pagingPhotoView: PagingPhotoView = {
    let photoView = PagingPhotoView()
    photoView.isHidden = true
    return photoView
  }()

  var autocompleteConfiguration: AutocompleteConfiguration?

  override func viewDidLoad() {
    super.viewDidLoad()

    if #available(iOS 13.0, *) {
      view.backgroundColor = .systemBackground
    } else {
      view.backgroundColor = .white
    }
    view.addSubview(textView)
    textView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(pagingPhotoView)
    pagingPhotoView.translatesAutoresizingMaskIntoConstraints = false
    let guide = view.safeAreaLayoutGuide
    NSLayoutConstraint.activate([
      textView.topAnchor.constraint(equalTo: guide.topAnchor),
      textView.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
      textView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
      textView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
    ])
    NSLayoutConstraint.activate([
      pagingPhotoView.topAnchor.constraint(equalTo: guide.topAnchor),
      pagingPhotoView.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
      pagingPhotoView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
      pagingPhotoView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
    ])
  }

  @objc func showPhotos() {
    pagingPhotoView.isHidden = false
    navigationItem.rightBarButtonItem = nil
    textView.isHidden = true
  }

  func autocompleteDidSelectPlace(_ place: GMSPlace) {
    let text = NSMutableAttributedString(string: place.description)
    text.append(NSAttributedString(string: "\nPlace status: "))
    text.append(NSAttributedString(string: place.isOpen().description))
    if let attributions = place.attributions {
      text.append(NSAttributedString(string: "\n\n"))
      text.append(attributions)
    }

    if #available(iOS 13.0, *) {
      text.addAttribute(.foregroundColor, value: UIColor.label, range: NSMakeRange(0, text.length))
    }
    textView.attributedText = text
    textView.isHidden = false
    pagingPhotoView.isHidden = true
    if let photos = place.photos, photos.count > 0 {
      preloadPhotoList(photos: photos)
    }
  }

  func autocompleteDidFail(_ error: Error) {
    textView.text = String(
      format: NSLocalizedString(
        "Demo.Content.Autocomplete.FailedErrorMessage",
        comment: "Format string for 'autocomplete failed with error' message"), error as NSError)
  }

  func autocompleteDidCancel() {
    textView.text = NSLocalizedString(
      "Demo.Content.Autocomplete.WasCanceledMessage",
      comment: "String for 'autocomplete canceled message'")
  }

  override func viewWillTransition(
    to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
  ) {
    super.viewWillTransition(to: size, with: coordinator)
    pagingPhotoView.shouldRedraw = true
  }
}

extension AutocompleteBaseViewController {
  // Preload the photos to be displayed.
  func preloadPhotoList(photos: [GMSPlacePhotoMetadata]) {
    var attributedPhotos: [AttributedPhoto] = []
    let placeClient = GMSPlacesClient.shared()
    DispatchQueue.global().async {
      let downloadGroup = DispatchGroup()
      photos.forEach { photo in
        downloadGroup.enter()
        placeClient.loadPlacePhoto(photo) { imageData, error in
          if let image = imageData, let attributions = photo.attributions {
            attributedPhotos.append(AttributedPhoto(image: image, attributions: attributions))
          }
          downloadGroup.leave()
        }
      }

      downloadGroup.notify(queue: DispatchQueue.main) {
        self.navigationItem.rightBarButtonItem = self.photoButton
        self.pagingPhotoView.updatePhotos(attributedPhotos)
      }
    }
  }
}

extension GMSPlaceOpenStatus: CustomStringConvertible {
  public var description: String {
    switch self {
    case .open:
      return "Open"
    case .closed:
      return "Closed"
    case .unknown:
      return "Unknown"
    default:
      return ""
    }
  }
}