//
//  HeaderContentItem.swift
//  Astro
//
//  Created by Kerr Miller on 2016-12-05.
//  Copyright © 2016 Mobify Research & Development Inc. All rights reserved.
//

import Foundation

struct HeaderContentItem {
    let id: String
    let content: HeaderContentItemContent
    var hidden: Bool
    let shouldFlipOnRtl: Bool

    static let IDKey = "id"
    static let titleKey = "title"
    static let imageKey = "imageUrl"
    static let pluginAddressKey = "pluginAddress"
    static let shouldFlipOnRtlKey = "shouldFlipOnRtl"

    init(id: String, content: HeaderContentItemContent, hidden: Bool, shouldFlipOnRTL: Bool) {
        self.id = id
        self.content = content
        self.hidden = hidden
        self.shouldFlipOnRtl = shouldFlipOnRTL
    }

    init?(jsonObject: JSONObject, pluginResolver: PluginResolver, respond: RPCMethodCallback) {
        guard let id: String = jsonObject.get(HeaderContentItem.IDKey, respond: respond) else {
            return nil
        }

        let itemContent: HeaderContentItemContent? = {
            if jsonObject.keys.contains(HeaderContentItem.titleKey) {
                if let title: String = jsonObject.get(HeaderContentItem.titleKey, respond: respond) {
                    return .title(title)
                }
            }

            if jsonObject.keys.contains(HeaderContentItem.imageKey) {
                if let imageURLString: String = jsonObject.get(HeaderContentItem.imageKey, respond: respond),
                    let image = AstroFileUtils.image(filePath: imageURLString, respond: respond) {
                        return .image(image)
                }
            }

            if jsonObject.keys.contains(HeaderContentItem.pluginAddressKey) {
                if let pluginAddress: String = jsonObject.get(HeaderContentItem.pluginAddressKey, respond: respond),
                    let plugin: ViewPlugin = pluginResolver.pluginInstanceByAddress(pluginAddress, respond: respond) {
                        return .plugin(plugin)
                }
            }

            return nil
        }()

        guard let content = itemContent else {
            if !jsonObject.keys.contains(HeaderContentItem.titleKey) &&
                !jsonObject.keys.contains(HeaderContentItem.imageKey) &&
                !jsonObject.keys.contains(HeaderContentItem.pluginAddressKey) {
                respond(.error("One of \"\(HeaderContentItem.titleKey)\" or \"\(HeaderContentItem.imageKey)\" or \"\(HeaderContentItem.pluginAddressKey)\" is required, got: \(jsonObject)"))
            }
            // We coudn't get/parse the JSON and a response was already sent
            return nil
        }

        self.id = id
        self.content = content
        self.hidden = false
        self.shouldFlipOnRtl = jsonObject[HeaderContentItem.shouldFlipOnRtlKey] as? Bool ?? false
    }
}

extension HeaderContentItem: CustomStringConvertible {
    var description: String {
        return "HeaderContentItem(id: \(id), content: \(content))"
    }
}

extension HeaderContentItem: Equatable { }

func ==(lhs: HeaderContentItem, rhs: HeaderContentItem) -> Bool {
    return lhs.id == rhs.id && lhs.content == rhs.content
}
