//
//  SegmentedPlugin.swift
//  Astro
//
//  Created by Helen on 2016-06-30.
//  Copyright © 2016 Mobify Research & Development Inc. All rights reserved.
//

// A segmented control plugin, intended for switching between related views.

import Foundation

public class SegmentedPlugin: Plugin, ViewPlugin {

    @objc public let viewController: UIViewController = {
        let viewController = UIViewController()
        viewController.view.backgroundColor = UIColor.white
        return viewController
    }()

    fileprivate let segmentedControl: UISegmentedControl = {
        let segmentedControl = UISegmentedControl(items: [])
        segmentedControl.translatesAutoresizingMaskIntoConstraints = false
        return segmentedControl
    }()

    fileprivate var segmentData = [[String: String]]()

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

        super.init(address: address, messageBus: messageBus, pluginResolver: pluginResolver, options: options)

        self.addRpcMethodShim("setItems") { params, respond in
            ////////// This will be autogenerated at some point //////////
            if let items: [JSONObject] = MethodShimUtils.getArg(params, key: "items", respond: respond) {
                self.setItems(items, respond: respond)
            }
            /////////////////////////////////////////////////////////////
        }

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

        self.addRpcMethodShim("setInactiveColor") { _, _ in
            // DO NOTHING - this is irrelevant in iOS
        }

        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("selectItem") { params, respond in
            ////////// This will be autogenerated at some point //////////
            if let key: String = MethodShimUtils.getArg(params, key: "key", respond: respond) {
                self.selectItem(key, respond: respond)
            }
            /////////////////////////////////////////////////////////////
        }

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

        Localization.addLocaleChangedListener(self)
        segmentedControl.addTarget(self, action: #selector(SegmentedPlugin.valueDidChange(_:)), for: .valueChanged)
        viewController.view.addSubview(segmentedControl)
        addSegmentedControlConstraints()
    }

    private func addSegmentedControlConstraints() {
        segmentedControl.centerInSuperview()
        segmentedControl.pinToSuperviewEdgesHorizontally(withMargin: 10)
        segmentedControl.pinToSuperviewEdgesVertically(withMargin: 10)
    }

    @objc func valueDidChange(_ sender: UISegmentedControl) {
        let key = segmentData[sender.selectedSegmentIndex]["key"]!
        let params: JSONObject = [
            "key": key
        ]
        trigger("itemSelect", params: params)
    }

    // MARK: - RPC Methods

    // @RpcMethod
    func setItems(_ items: [JSONObject], respond: RPCMethodCallback) {
        segmentedControl.removeAllSegments()
        segmentData.removeAll()
        for (index, item) in items.enumerated() {
            guard let key: String = MethodShimUtils.getArg(item, key: "key", respond: respond),
                let title: String = MethodShimUtils.getArg(item, key: "text", respond: respond)
            else {
                respond(.error("Could not get 'key' or 'text' from item json."))
                break
            }
            segmentedControl.insertSegment(withTitle: Localization.translate(title), at: segmentedControl.numberOfSegments, animated: false)
            if index != segmentData.count {
                respond(.error("Segment data not in sync with Segment control"))
            }
            segmentData.append(["key": key, "title": title])
        }
        segmentedControl.selectedSegmentIndex = 0
    }

    // @RpcMethod
    func setColor(_ color: String, respond: RPCMethodCallback) {
        segmentedControl.tintColor = UIColor(hex: color)
    }

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

    // @RpcMethod
    func selectItem(_ key: String, respond: RPCMethodCallback) {
        let index = segmentData.firstIndex {
            return $0["key"] == key
        }

        segmentedControl.selectedSegmentIndex = index ?? -1
        valueDidChange(segmentedControl)
    }

    // @AsyncRpcMethod
    func getSelectedItem(_ respond: RPCMethodCallback) {
        let index = segmentedControl.selectedSegmentIndex
        if index >= 0, let key = segmentData[index]["key"] {
            respond(.result(key))
        } else {
            respond(.error("No segment selected"))
        }
    }
}

// MARK: - LocaleChangedListener

extension SegmentedPlugin: LocaleChangedListener {
    public func localeDidChange(newLocale: Locale) {
        for i in 0..<(segmentedControl.numberOfSegments) {
            let title = segmentData[i]["title"]!
            segmentedControl.setTitle(Localization.translate(title), forSegmentAt: i)
        }
    }
}
