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

import UIKit

class AudioSettingsSliderTableViewCell: UITableViewCell {
    static let reuseIdentifier = "AudioSettingsSliderTableViewCell"
    typealias AudioSettingsSliderDidChangeCellCallback = (AudioSettingsSliderTableViewCell) -> ()

    @IBOutlet weak var titleLabel: UILabel?
    @IBOutlet weak var slider: UISlider?
    var sliderDidChange: AudioSettingsSliderDidChangeCellCallback?

    @IBAction private func sliderChanged(_ sender: UISlider) {
        if let callback = sliderDidChange {
            callback(self)
        }
    }
}

class AudioSettingsTableViewController: UITableViewController {
    var viewModel: AudioSettingsViewModel?
    var rows = [AudioSettingsRow] ()
}

extension AudioSettingsTableViewController: AudioSettingsViewController {
    func reloadAll() {
        rows = viewModel?.rows() ?? []
        tableView.reloadData()
    }

    func present(viewController: AudioSettingsViewController) {
        if let vc = viewController as? UIViewController {
            navigationController?.pushViewController(vc, animated: true)
        }
    }
}

extension AudioSettingsTableViewController {
    override func viewDidLoad() {
        title = viewModel?.title
        rows = viewModel?.rows() ?? []

        super.viewDidLoad()

        let nib1 = UINib(nibName: SettingsOneRowTableViewCell.reuseIdentifier, bundle: nil)
        tableView?.register(nib1, forCellReuseIdentifier: SettingsOneRowTableViewCell.reuseIdentifier)

        let nib2 = UINib(nibName: SettingsTwoRowTableViewCell.reuseIdentifier, bundle: nil)
        tableView?.register(nib2, forCellReuseIdentifier: SettingsTwoRowTableViewCell.reuseIdentifier)

        let nib = UINib(nibName: SettingsTableViewHeaderView.reuseIdentifier, bundle: nil)
        tableView?.register(nib, forHeaderFooterViewReuseIdentifier: SettingsTableViewHeaderView.reuseIdentifier)

        // Accessibility
        tableView?.makeAccessible(Accessibility.AudioEffectsSettingsScreen.listTitle)
    }
}

// MARK: - Table view data source
extension AudioSettingsTableViewController {
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rows.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
		let row = rows[indexPath.row]
        switch row.type {
        case .simple,
             .submenu:
            let cell = tableView.dequeueReusableCell(withIdentifier:SettingsOneRowTableViewCell.reuseIdentifier) as? SettingsOneRowTableViewCell ?? SettingsOneRowTableViewCell()
            cell.style = .plain
            cell.titleLabel?.text = row.title
            cell.makeAccessible(row.accessibilityTitle, doNotLocalizeForHuman: true)
            switch row.type {
            case .simple:
                cell.accessoryType = .none
                cell.titleLabel?.textColor = UIColor.lightGray
            case .submenu:
                cell.accessoryType = .disclosureIndicator
                cell.titleLabel?.textColor = ColorCompat.label
            default:
                break
            }
            return cell
        case .toggle(let value):
            let cell = tableView.dequeueReusableCell(withIdentifier:SettingsOneRowTableViewCell.reuseIdentifier) as? SettingsOneRowTableViewCell ?? SettingsOneRowTableViewCell()
            cell.style = .toggle
            cell.accessoryType = .none
            cell.titleLabel?.textColor = ColorCompat.label
            cell.titleLabel?.text = row.title
            cell.makeAccessible(row.accessibilityTitle, doNotLocalizeForHuman: true)
            cell.setToggle(isOn: value)
            cell.onToggle = { [weak self] newState in
                guard let self = self else { return }
                cell.style = .waiting
                self.viewModel?.toggleChanged(row, value: newState)
            }
            return cell
        case .slider(let value):
            let cell = tableView.dequeueReusableCell(withIdentifier: AudioSettingsSliderTableViewCell.reuseIdentifier) as? AudioSettingsSliderTableViewCell ?? AudioSettingsSliderTableViewCell()
            cell.accessoryType = .none
            cell.titleLabel?.textColor = ColorCompat.label
            cell.titleLabel?.text = row.title
            cell.slider?.value = Float(value)
            cell.slider?.makeAccessible(row.accessibilityTitle, doNotLocalizeForHuman: true)
            cell.sliderDidChange = { [weak self] cell in
                guard let self = self else { return }
                self.viewModel?.sliderMoved(row, value: Double(cell.slider?.value ?? 0.0))
            }
            return cell
        case .option(let value):
            let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTwoRowTableViewCell.reuseIdentifier) as? SettingsTwoRowTableViewCell ?? SettingsTwoRowTableViewCell()
            cell.accessoryType = .disclosureIndicator
            cell.titleLabel?.textColor = ColorCompat.label
            cell.titleLabel?.text = row.title
            cell.subtitleLabel?.text = value
            cell.makeAccessible(row.accessibilityTitle, doNotLocalizeForHuman: true)
            return cell
        case .checkableOption(let checked):
            let cell = tableView.dequeueReusableCell(withIdentifier:SettingsOneRowTableViewCell.reuseIdentifier) as? SettingsOneRowTableViewCell ?? SettingsOneRowTableViewCell()
            cell.style = .plain
            cell.accessoryType = checked ? .checkmark : .none
            cell.titleLabel?.textColor = ColorCompat.label
            cell.titleLabel?.text = row.title
            cell.makeAccessible(row.accessibilityTitle, doNotLocalizeForHuman: true)
            return cell
        }
    }

    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        let row = rows[indexPath.row]
        switch row.type {
        case .simple:
            return nil
        case .submenu:
            return indexPath
        case .toggle(_):
            return nil
        case .slider(_):
            return nil
        case .option(_):
            return indexPath
        case .checkableOption(_):
            return indexPath
        }
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let row = rows[indexPath.row]
        switch row.type {
        case .submenu:
            viewModel?.submenuTapped(row)
        case .option(_):
            viewModel?.optionRowTapped(row)
        case .checkableOption(_):
            viewModel?.checkableOptionChecked(row)
        case .simple,
             .toggle(_),
             .slider(_):
            break
        }
    }

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return CGFloat.leastNormalMagnitude
    }
}
