//
// © 2018-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

import UIKit

enum VoiceUIHelper {
    enum Domain {
        case speaker
        case group
        case zigbee
    }

    static func localizedVoiceUINames(domain: Domain, playerController: PlayerControllerProtocol) -> [String] {
        switch domain {
        case .speaker:
            return [NSLocalizedString("Bedroom", comment: "VUI Target"),
                    NSLocalizedString("Kitchen", comment: "VUI Target"),
                    NSLocalizedString("Living Room", comment: "VUI Target")]
        case .group:
            return [NSLocalizedString("Bedroom", comment: "VUI Target"),
                    NSLocalizedString("Kitchen", comment: "VUI Target"),
                    NSLocalizedString("Living Room", comment: "VUI Target"),
                    NSLocalizedString("Group One", comment: "VUI Target"),
                    NSLocalizedString("Group Two", comment: "VUI Target"),
                    NSLocalizedString("Group Three", comment: "VUI Target")]
        case .zigbee:
            return [NSLocalizedString("Bedroom", comment: "VUI Target"),
                    NSLocalizedString("Kitchen", comment: "VUI Target"),
                    NSLocalizedString("Living Room", comment: "VUI Target")]
        }
    }

    // Names in use are localized
    static func localizedVoiceUINamesInUse(domain: Domain,
                                             playerController: PlayerControllerProtocol,
                                             ignoringName: String?) -> [String] {
        let allGroups = playerController.playerGroups
        let inUseGroupNames = Set(allGroups.compactMap { (group)->(String?) in
            let groupName = group.displayName
            if !group.isConvenienceGroup && groupName != ignoringName {
                return group.displayName
            } else {
                return nil
            }
        })

        let inUsePlayerNames = Set(playerController.players.compactMap { (player)->(String?) in
            let name = player.displayName
            if name != ignoringName {
                return name
            } else {
                return nil
            }
        })

        var inUseZigbeeNames = Set<String>()
        if playerController.zigbeeCoordinatorExists() {
            allGroups.forEach { (group) in
                if let coordinator = playerController.zigbeeCoordinator(playerGroupID: group.groupID) {
                    let zigbeeDevices = coordinator.zigbeeDevices
                    inUseZigbeeNames = Set(zigbeeDevices.compactMap { zbDevice in
                        let name = zbDevice.name
                        if name != ignoringName {
                            return name
                        } else {
                            return nil
                        }
                    })
                }
            }
        }

        let inUseVoiceUIOptions = localizedVoiceUINames(domain: domain,
                                                        playerController: playerController)
            .compactMap { (name) -> String? in
                var inUse = false
                if domain == .zigbee {
                    inUse = inUse || inUseZigbeeNames.contains(name)
                } else {
                    inUse = inUse || inUseGroupNames.contains(name)
                    inUse = inUse || inUsePlayerNames.contains(name)
                }

                return inUse ? name : nil
        }
        return inUseVoiceUIOptions
    }

    static func unlocalizedNameForService(_ service: IoTVoiceUIClient) -> String {
        switch service.type {
        case .AVS:
            return Accessibility.VoiceUIServices.avsServiceName
        case .GVA:
            return Accessibility.VoiceUIServices.gvaServiceName
        case .cortana:
            return Accessibility.VoiceUIServices.cortanaServiceName
        case .modular:
            return Accessibility.VoiceUIServices.modularServiceName
        case .unknown:
            return ""
        @unknown default:
            fatalError()
        }
    }

    static func unlocalizedStateForService(_ service: IoTVoiceUIClient) -> String {
        if !service.onboarded {
            return Accessibility.VoiceUIServices.notLinkedStatus
        } else {
            if service.wakeWordEnabled {
                return Accessibility.VoiceUIServices.enabledListeningStatus
            } else {
                return Accessibility.VoiceUIServices.enabledNotListeningStatus
            }
        }
    }

    static func unlocalizedWakeWordForService(_ service: IoTVoiceUIClient) -> String {
        switch service.type {
        case .AVS:
            return Accessibility.VoiceUIServices.avsWakeword
        case .GVA:
            return Accessibility.VoiceUIServices.gvaWakeword
        case .cortana:
            return Accessibility.VoiceUIServices.cortanaWakeword
        case .modular:
            return Accessibility.VoiceUIServices.modularWakeword
        case .unknown:
            return ""
        @unknown default:
            fatalError()
        }
    }

}
