//
//  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//

import Foundation

@objc
public protocol MessageApprovalViewControllerDelegate: class {
    func messageApproval(_ messageApproval: MessageApprovalViewController, didApproveMessage messageText: String)
    func messageApprovalDidCancel(_ messageApproval: MessageApprovalViewController)
}

@objc
public class MessageApprovalViewController: OWSViewController, UITextViewDelegate {

    let TAG = "[MessageApprovalViewController]"
    weak var delegate: MessageApprovalViewControllerDelegate?

    // MARK: Properties

    let thread: TSThread
    let initialMessageText: String
    let contactsManager: OWSContactsManager

    private(set) var textView: UITextView!
    private(set) var topToolbar: UIToolbar!

    // MARK: Initializers

    @available(*, unavailable, message:"use attachment: constructor instead.")
    required public init?(coder aDecoder: NSCoder) {
        fatalError("unimplemented")
    }

    @objc
    required public init(messageText: String, thread: TSThread, contactsManager: OWSContactsManager, delegate: MessageApprovalViewControllerDelegate) {
        self.initialMessageText = messageText
        self.thread = thread
        self.contactsManager = contactsManager
        self.delegate = delegate

        super.init(nibName: nil, bundle: nil)
    }

    // MARK: View Lifecycle

    override public func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = NSLocalizedString("MESSAGE_APPROVAL_DIALOG_TITLE",
                                                      comment: "Title for the 'message approval' dialog.")
    }

    private func updateToolbar() {
        var items = [UIBarButtonItem]()

        let cancelButton = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(cancelPressed))
        items.append(cancelButton)

        if textView.text.count > 0 {
            let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            items.append(spacer)
            let sendButton = UIBarButtonItem(title: NSLocalizedString("SEND_BUTTON_TITLE",
                                                                      comment:"Label for the send button in the conversation view."),
                                             style:.plain,
                                             target: self,
                                             action: #selector(sendPressed))
            items.append(sendButton)
        }

        topToolbar.items = items
    }

    // MARK: - Create Views

    public override func loadView() {

        self.view = UIView.container()
        self.view.backgroundColor = UIColor.white

        // Top Toolbar
        topToolbar = UIToolbar()
        topToolbar.backgroundColor = UIColor.ows_toolbarBackground
        self.view.addSubview(topToolbar)
        topToolbar.autoPinWidthToSuperview()
        topToolbar.autoPin(toTopLayoutGuideOf: self, withInset: 0)
        topToolbar.setContentHuggingVerticalHigh()
        topToolbar.setCompressionResistanceVerticalHigh()

        // Recipient Row
        let recipientRow = createRecipientRow()
        view.addSubview(recipientRow)
        recipientRow.autoPinWidthToSuperview()
        recipientRow.autoPinEdge(.top, to: .bottom, of: topToolbar)

        // Text View
        textView = UITextView()
        textView.delegate = self
        textView.backgroundColor = UIColor.white
        textView.textColor = UIColor.black
        textView.font = UIFont.ows_dynamicTypeBody()
        textView.text = self.initialMessageText
        textView.contentInset = UIEdgeInsets(top:0.0, left:0.0, bottom:0.0, right:0.0)
        textView.textContainerInset = UIEdgeInsets(top:10.0, left:10.0, bottom:10.0, right:10.0)
        view.addSubview(textView)
        textView.autoPinWidthToSuperview()
        textView.autoPinEdge(.top, to: .bottom, of: recipientRow)
        textView.autoPin(toBottomLayoutGuideOf: self, withInset: 0)

        updateToolbar()
    }

    private func createRecipientRow() -> UIView {
        let recipientRow = UIView.container()
        recipientRow.backgroundColor = UIColor.ows_toolbarBackground

        // Hairline borders should be 1 pixel, not 1 point.
        let borderThickness = 1.0 / UIScreen.main.scale
        let borderColor = UIColor(white:135 / 255.0, alpha:1.0)

        let topBorder = UIView.container()
        topBorder.backgroundColor = borderColor
        recipientRow.addSubview(topBorder)
        topBorder.autoPinWidthToSuperview()
        topBorder.autoPinTopToSuperview()
        topBorder.autoSetDimension(.height, toSize: borderThickness)

        let bottomBorder = UIView.container()
        bottomBorder.backgroundColor = borderColor
        recipientRow.addSubview(bottomBorder)
        bottomBorder.autoPinWidthToSuperview()
        bottomBorder.autoPinBottomToSuperview()
        bottomBorder.autoSetDimension(.height, toSize: borderThickness)

        let font = UIFont.ows_regularFont(withSize:ScaleFromIPhone5To7Plus(14.0, 18.0))
        let hSpacing = CGFloat(10)
        let hMargin = CGFloat(15)
        let vSpacing = CGFloat(5)
        let vMargin = CGFloat(10)

        let toLabel = UILabel()
        toLabel.text = NSLocalizedString("MESSAGE_APPROVAL_RECIPIENT_LABEL",
                                         comment: "Label for the recipient name in the 'message approval' dialog.")
        toLabel.textColor = UIColor.ows_darkGray
        toLabel.font = font
        recipientRow.addSubview(toLabel)

        let nameLabel = UILabel()
        nameLabel.textColor = UIColor.black
        nameLabel.font = font
        nameLabel.lineBreakMode = .byTruncatingTail
        recipientRow.addSubview(nameLabel)

        toLabel.autoPinLeadingToSuperview(withMargin: hMargin)
        toLabel.setContentHuggingHorizontalHigh()
        toLabel.setCompressionResistanceHorizontalHigh()
        toLabel.autoAlignAxis(.horizontal, toSameAxisOf: nameLabel)

        nameLabel.autoPinLeading(toTrailingOf: toLabel, margin:hSpacing)
        nameLabel.autoPinTrailingToSuperview(withMargin: hMargin)
        nameLabel.setContentHuggingHorizontalLow()
        nameLabel.setCompressionResistanceHorizontalLow()
        nameLabel.autoPinTopToSuperview(withMargin: vMargin)

        if let groupThread = self.thread as? TSGroupThread {
            let groupName = (groupThread.name().count > 0
            ? groupThread.name()
                : MessageStrings.newGroupDefaultTitle)

            nameLabel.text = groupName
            nameLabel.autoPinBottomToSuperview(withMargin: vMargin)

            return recipientRow
        }
        guard let contactThread = self.thread as? TSContactThread else {
            owsFail("Unexpected thread type")
            return recipientRow
        }

        nameLabel.attributedText = contactsManager.formattedFullName(forRecipientId:contactThread.contactIdentifier(), font:font)
        nameLabel.textColor = UIColor.black

        if let profileName = self.profileName(contactThread:contactThread) {
            // If there's a profile name worth showing, add it as a second line below the name.
            let profileNameLabel = UILabel()
            profileNameLabel.textColor = UIColor.ows_darkGray
            profileNameLabel.font = font
            profileNameLabel.text = profileName
            profileNameLabel.lineBreakMode = .byTruncatingTail
            recipientRow.addSubview(profileNameLabel)
            profileNameLabel.autoPinEdge(.top, to: .bottom, of: nameLabel, withOffset: vSpacing)
            profileNameLabel.autoPinLeading(toTrailingOf: toLabel, margin:hSpacing)
            profileNameLabel.autoPinTrailingToSuperview(withMargin: hMargin)
            profileNameLabel.setContentHuggingHorizontalLow()
            profileNameLabel.setCompressionResistanceHorizontalLow()
            profileNameLabel.autoPinBottomToSuperview(withMargin: vMargin)
        } else {
            nameLabel.autoPinBottomToSuperview(withMargin: vMargin)
        }

        return recipientRow
    }

    private func profileName(contactThread: TSContactThread) -> String? {
        let recipientId = contactThread.contactIdentifier()

        if contactsManager.hasNameInSystemContacts(forRecipientId:recipientId) {
            // Don't display profile name when we have a veritas name in system Contacts
            return nil
        }
        return contactsManager.formattedProfileName(forRecipientId:recipientId)
    }

    // MARK: - Event Handlers

    func cancelPressed(sender: UIButton) {
        delegate?.messageApprovalDidCancel(self)
    }

    func sendPressed(sender: UIButton) {
        delegate?.messageApproval(self, didApproveMessage: self.textView.text)
    }

    // MARK: - UITextViewDelegate

    public func textViewDidChange(_ textView: UITextView) {
        updateToolbar()
    }
}