//
//  SearchBarPlugin.swift
//  Astro
//
//  Created by Crystal To on 2016-09-06.
//  Copyright © 2016 Mobify Research & Development Inc. All rights reserved.
//

import Foundation

public class SearchBarPlugin: Plugin, ViewPlugin, UISearchBarDelegate, LocaleChangedListener {
    @objc public let viewController = UIViewController()
    @objc let searchBar = UISearchBar()
    @objc var placeholderTextKey = "search_bar_hint"

    public required init(address: MessageAddress, messageBus: MessageBus, pluginResolver: PluginResolver, options: JSONObject?) {
        super.init(address: address, messageBus: messageBus, pluginResolver: pluginResolver, options: options)

        self.addRpcMethodShim("blur") { _, respond in
            ////////// This will be autogenerated at some point //////////
            self.blur(respond)
            /////////////////////////////////////////////////////////////
        }

        self.addRpcMethodShim("focus") { _, respond in
            ////////// This will be autogenerated at some point //////////
            self.focus(respond)
            /////////////////////////////////////////////////////////////
        }

        self.addRpcMethodShim("setQuery") { params, respond in
            ////////// This will be autogenerated at some point //////////
            if let query: String = MethodShimUtils.getArg(params, key: "query", respond: respond) {
                self.setQuery(query, respond: respond)
            }
            /////////////////////////////////////////////////////////////
        }

        self.addRpcMethodShim("setPlaceholderText") { params, respond in
            ////////// This will be autogenerated at some point //////////
            if let text: String = MethodShimUtils.getArg(params, key: "text", respond: respond) {
                self.setPlaceholderText(text, respond: respond)
            }
            /////////////////////////////////////////////////////////////
        }

        self.addRpcMethodShim("setBackgroundColor") { params, respond in
            ////////// This will be autogenerated at some point //////////
            if let color: String = MethodShimUtils.getArg(params, key: "color", respond: respond) {
                self.setBackgroundColor(color, respond: respond)
            }
            /////////////////////////////////////////////////////////////
        }

        self.addRpcMethodShim("submit") { _, respond in
            ////////// This will be autogenerated at some point //////////
            self.submit(respond)
            /////////////////////////////////////////////////////////////
        }

        Localization.addLocaleChangedListener(self)

        searchBar.delegate = self
        searchBar.isTranslucent = true
        setLocalizedPlaceholderText()
        searchBar.translatesAutoresizingMaskIntoConstraints = false
        viewController.view.addSubview(searchBar)
        searchBar.pinToSuperviewEdges()
    }

    // MARK: - UISearchBarDelegate

    public func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        triggerSearchChangedEvent(searchText)
    }

    public func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        guard let query = searchBar.text, query.count > 0 else {
            return
        }
        trigger("search:submitted", params:["searchTerms": query])
        clearSearchBarText()
        blurAndHideCancelButton()
    }

    public func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        blurAndHideCancelButton()
        trigger("search:cancelled")
    }

    public func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        focusAndShowCancelButton()
    }

    // MARK: - RPC Methods

    // @RpcMethod
    func blur(_ respond: RPCMethodCallback) {
        blurAndHideCancelButton()
    }

    // @RpcMethod
    func focus(_ respond: RPCMethodCallback) {
        focusAndShowCancelButton()
    }

    // @RpcMethod
    func setQuery(_ query: String, respond: RPCMethodCallback) {
        searchBar.text = query
        triggerSearchChangedEvent(query)
    }

    // @RpcMethod
    func setPlaceholderText(_ text: String, respond: RPCMethodCallback) {
        placeholderTextKey = text
        setLocalizedPlaceholderText()
    }

    // @RpcMethod
    func setBackgroundColor(_ color: String, respond: RPCMethodCallback) {
        searchBar.barTintColor = UIColor(hex: color)
    }

    // @RpcMethod
    func submit(_ respond: RPCMethodCallback) {
        searchBarSearchButtonClicked(searchBar)
    }

    public func localeDidChange(newLocale: Locale) {
        setLocalizedPlaceholderText()
    }

    // MARK: - Helper Methods

    private func setLocalizedPlaceholderText() {
        searchBar.placeholder = Localization.translate(placeholderTextKey)
    }

    private func clearSearchBarText() {
        searchBar.text = ""
        triggerSearchChangedEvent("")
    }

    private func triggerSearchChangedEvent(_ newQuery: String) {
        let params: JSONObject = [
            "searchTerms": newQuery
        ]
        trigger("search:changed", params: params)
    }

    private func focusAndShowCancelButton() {
        searchBar.setShowsCancelButton(true, animated: true)
        searchBar.becomeFirstResponder()
    }

    private func blurAndHideCancelButton() {
        searchBar.resignFirstResponder()
        searchBar.setShowsCancelButton(false, animated: true)
    }
}
