//
//  CustomMessageContentCell.swift
//  ChatExample
//
//  Created by Vignesh J on 01/05/21.
//  Copyright © 2021 MessageKit. All rights reserved.
//

import MessageKit
import UIKit

class CustomMessageContentCell: MessageCollectionViewCell {
  // MARK: Lifecycle

  override init(frame: CGRect) {
    super.init(frame: frame)
    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    setupSubviews()
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    setupSubviews()
  }

  // MARK: Internal

  /// The `MessageCellDelegate` for the cell.
  weak var delegate: MessageCellDelegate?

  /// The container used for styling and holding the message's content view.
  var messageContainerView: UIView = {
    let containerView = UIView()
    containerView.clipsToBounds = true
    containerView.layer.masksToBounds = true
    return containerView
  }()

  /// The top label of the cell.
  var cellTopLabel: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    label.textAlignment = .center
    return label
  }()

  var cellDateLabel: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    label.textAlignment = .right
    return label
  }()

  override func prepareForReuse() {
    super.prepareForReuse()
    cellTopLabel.text = nil
    cellTopLabel.attributedText = nil
    cellDateLabel.text = nil
    cellDateLabel.attributedText = nil
  }

  /// Handle tap gesture on contentView and its subviews.
  override func handleTapGesture(_ gesture: UIGestureRecognizer) {
    let touchLocation = gesture.location(in: self)

    switch true {
    case messageContainerView.frame
      .contains(touchLocation) && !cellContentView(canHandle: convert(touchLocation, to: messageContainerView)):
      delegate?.didTapMessage(in: self)
    case cellTopLabel.frame.contains(touchLocation):
      delegate?.didTapCellTopLabel(in: self)
    case cellDateLabel.frame.contains(touchLocation):
      delegate?.didTapMessageBottomLabel(in: self)
    default:
      delegate?.didTapBackground(in: self)
    }
  }

  /// Handle long press gesture, return true when gestureRecognizer's touch point in `messageContainerView`'s frame
  override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    let touchPoint = gestureRecognizer.location(in: self)
    guard gestureRecognizer.isKind(of: UILongPressGestureRecognizer.self) else { return false }
    return messageContainerView.frame.contains(touchPoint)
  }

  func setupSubviews() {
    messageContainerView.layer.cornerRadius = 5

    contentView.addSubview(cellTopLabel)
    contentView.addSubview(messageContainerView)
    messageContainerView.addSubview(cellDateLabel)
  }

  func configure(
    with message: MessageType,
    at indexPath: IndexPath,
    in messagesCollectionView: MessagesCollectionView,
    dataSource: MessagesDataSource,
    and sizeCalculator: CustomLayoutSizeCalculator)
  {
    guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
      return
    }
    cellTopLabel.frame = sizeCalculator.cellTopLabelFrame(
      for: message,
      at: indexPath)
    cellDateLabel.frame = sizeCalculator.cellMessageBottomLabelFrame(
      for: message,
      at: indexPath)
    messageContainerView.frame = sizeCalculator.messageContainerFrame(
      for: message,
      at: indexPath,
      fromCurrentSender: dataSource
        .isFromCurrentSender(message: message))
    cellTopLabel.attributedText = dataSource.cellTopLabelAttributedText(
      for: message,
      at: indexPath)
    cellDateLabel.attributedText = dataSource.messageBottomLabelAttributedText(
      for: message,
      at: indexPath)
    messageContainerView.backgroundColor = displayDelegate.backgroundColor(
      for: message,
      at: indexPath,
      in: messagesCollectionView)
  }

  /// Handle `ContentView`'s tap gesture, return false when `ContentView` doesn't needs to handle gesture
  func cellContentView(canHandle _: CGPoint) -> Bool {
    false
  }
}
