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

import UIKit

class AudioSettingsMeloDBassManagementViewModel: AudioSettingsBaseViewModel {
    typealias SizeOption = AudioSettingsSurroundSizeViewModel.Preset

    private enum RowType: String, CaseIterable, AudioSettingRowSource {
        case enable = "Enable"
        case subwoofer = "Subwoofer"
        case leftSurroundSize = "Left Surround Size"
        case rightSurroundSize = "Right Surround Size"
        case leftSurroundHigh = "Left Surround High"
        case rightSurroundHigh = "Right Surround High"
        case cornerFrequency = "Subwoofer Corner Frequency"

        func identifier() -> String {
            return self.rawValue
        }

        func title() -> String {
            return NSLocalizedString(self.rawValue, comment: "")
        }

        func value(player: IoTPlayer) -> AudioSettingRowSourceResult {
            switch self {
            case .enable:
                return .bool(value: player.meloDBassManagementEnabled)
            case .subwoofer:
                return .bool(value: player.meloDBassManagementSubwooferOut)
            case .leftSurroundSize:
                let index = min(Int(player.meloDBassManagementLeftSurroundSize.rawValue), SizeOption.allCases.count)
                let option = NSLocalizedString(SizeOption.allCases[index].rawValue, comment: "Effect Level")
                return .string(value: option)
            case .rightSurroundSize:
                let index = min(Int(player.meloDBassManagementRightSurroundSize.rawValue), SizeOption.allCases.count)
                let option = NSLocalizedString(SizeOption.allCases[index].rawValue, comment: "Effect Level")
                return .string(value: option)
            case .leftSurroundHigh:
                return .bool(value: player.meloDBassManagementLeftSurroundHeight)
            case .rightSurroundHigh:
                return .bool(value: player.meloDBassManagementRightSurroundHeight)
            case .cornerFrequency:
                return .double(value: player.meloDBassManagementCornerFreqBass)
            }
        }

        func accessibilityTitle(player: IoTPlayer) -> String {
            switch value(player: player) {
            case .bool(let value):
                switch self {
                    
                case .enable:
                    if value {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.enabled, comment:"")
                    } else {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.disabled, comment:"")
                    }
                case .subwoofer:
                    if value {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.subwooferEnabled, comment:"")
                    } else {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.subwooferDisabled, comment:"")
                    }
                case .leftSurroundHigh:
                    if value {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.leftSurroundHeightEnabled, comment:"")
                    } else {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.leftSurroundHeightDisabled, comment:"")
                    }
                case .rightSurroundHigh:
                    if value {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.rightSurroundHeightEnabled, comment:"")
                    } else {
                        return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.rightSurroundHeightDisabled, comment:"")
                    }
                default:
                    return ""
                }

            case .string(let value):
                switch self {
                case .leftSurroundSize:
                    return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.leftSurroundSize , comment:"") + " " + value
                case .rightSurroundSize:
                    return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.rightSurroundSize , comment:"") + " " + value
                default:
                    return ""
                }
            case .double(_):
                return NSLocalizedString(Accessibility.AudioEffectsSettingsScreen.MeloD.BassManagement.cornerSlider , comment:"")
            default:
                return ""
            }
        }

        func viewModel(player: IoTPlayer)->AudioSettingsViewModel? {
            if self == .leftSurroundSize {
                let vm = AudioSettingsSurroundSizeViewModel(getter: { [weak player] in
                    guard let player = player else { return 0 }
                    return player.meloDBassManagementLeftSurroundSize.rawValue
                    }, setter: { [weak player] (intValue) in
                        guard let player = player else { return }
                        if let cValue = IoTSurroundSpeakerLeft(rawValue: intValue) {
                            player.setMeloDBassManagementLeftSurroundSize(cValue,
                                                                          completion: nil,
                                                                          completionQueue: nil)
                        }
                })
                return vm
            } else {
                let vm = AudioSettingsSurroundSizeViewModel(getter: { [weak player] in
                    guard let player = player else { return 0 }
                    return player.meloDBassManagementRightSurroundSize.rawValue
                    }, setter: { [weak player] (intValue) in
                        guard let player = player else { return }
                        if let cValue = IoTSurroundSpeakerRight(rawValue: intValue) {
                            player.setMeloDBassManagementRightSurroundSize(cValue,
                                                                           completion: nil,
                                                                           completionQueue: nil)
                        }
                })
                return vm
            }
        }

        func available(player: IoTPlayer) -> Bool {
            if self == .enable {
                return true
            } else {
                return player.meloDBassManagementEnabled
            }
        }
    }

    override var title: String { return NSLocalizedString("BASS MANAGEMENT", comment: "Bass Management") }

    override func rows()->[AudioSettingsRow] {
        return rows(rowEnum: RowType.self)
    }

    override func toggleChanged(_ row: AudioSettingsRow, value: Bool) {
        if
            let playerID = playerID,
            let player = playerController?.player(id: playerID) {
            startTimeoutTimer()

            if let enumCase = RowType(rawValue: row.identifier) {
                switch enumCase {
                case .enable:
                    player.setMeloDBassManagementEnabled(value,
                                                         completion: nil,
                                                         completionQueue: nil)
                case .subwoofer:
                    player.setMeloDBassManagementSubwooferOut(value,
                                                              completion: nil,
                                                              completionQueue: nil)
                case .leftSurroundHigh:
                    player.setMeloDBassManagementLeftSurroundHeight(value,
                                                                    completion: nil,
                                                                    completionQueue: nil)
                case .rightSurroundHigh:
                    player.setMeloDBassManagementRightSurroundHeight(value,
                                                                     completion: nil,
                                                                     completionQueue: nil)
                default:
                    break
                }
            }
        }
    }

    override func optionRowTapped(_ row: AudioSettingsRow) {
        optionRowTapped(row, rowEnum: RowType.self)
    }

    override func sliderMoved(_ row: AudioSettingsRow, value: Double) {
        if
            let playerID = playerID,
            let player = playerController?.player(id: playerID) {
            player.setMeloDBassManagementCornerFreqBass(value,
                                                        completion: nil,
                                                        completionQueue: nil)
        }
    }
}
