//
//  SettingsViewController.swift
//  sdk-demo-ios
//
//  Created by Smaato Inc on 25.06.18.
//  Copyright © 2018 Smaato Inc. All rights reserved.
//

import UIKit
import SmaatoSDKCore
import CoreLocation

struct UserDefaultKeys {
    static let queryKey = "QueryKey"
    static let keywordsKey = "KeywordsKey"
    static let ageKey = "AgeKey"
    static let genderKey = "GenderKey"
    static let httpsSettingsKey = "MySavedHTTPSOnlySettings"
}

extension SMAGender {

    static let allValues = [SMAGender.male, SMAGender.female, SMAGender.other, SMAGender.unknown]

    var asString: String? {
        get {
            switch self {
            case .male:
                return "Male"
            case .female:
                return "Female"
            case .other:
                return "Other"
            case .unknown:
                return "Unknown"
            @unknown default:
                return "Unknown"
            }
        }
    }
}

struct UserData {
    let keywords: String?
    let query: String?
    let gender: SMAGender
    let age: Int?
    let gps: Bool
    let coppa: Bool
    let httpsOnly: Bool
    
    static func getSmaatoUserSettings() -> UserData {

        let keywords = UserDefaults.standard.string(forKey: UserDefaultKeys.keywordsKey)
        let query = UserDefaults.standard.string(forKey: UserDefaultKeys.queryKey)
        
        var gender: SMAGender = .other
        if let genderValue = UserDefaults.standard.value(forKey: UserDefaultKeys.genderKey) as? UInt,
            let persistedGender = SMAGender(rawValue: genderValue) {
            gender = persistedGender
        }

        var gpsEnabled = false
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .authorizedAlways, .authorizedWhenInUse:
                gpsEnabled = true
            default:
                break
            }
        }

        let httpsOnly = UserDefaults.standard.bool(forKey: UserDefaultKeys.httpsSettingsKey)

        return UserData(keywords: keywords,
                        query: query,
                        gender: gender,
                        age: UserDefaults.standard.value(forKey: UserDefaultKeys.ageKey) as? Int,
                        gps: gpsEnabled,
                        coppa: SmaatoSDK.requireCoppaCompliantAds,
                        httpsOnly: httpsOnly)

    }

}

class SettingsViewController: UITableViewController {

    @IBOutlet fileprivate weak var keywordsTextField: InsetTextFiled!
    @IBOutlet fileprivate weak var queryTextField: InsetTextFiled!
    @IBOutlet fileprivate weak var ageTextField: InsetTextFiled!
    @IBOutlet fileprivate weak var genderTextField: InsetTextFiled!
    @IBOutlet fileprivate weak var gpsSwitch: UISwitch!
    @IBOutlet fileprivate weak var coppaSwitch: UISwitch!
    @IBOutlet fileprivate weak var httpsOnlySwitch: UISwitch!

    @IBOutlet private weak var sizeArrowImageView: UIImageView!

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        addGestureRecognizer()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        UserDefaults.standard.synchronize()
    }

    //MARK: Actions
    @IBAction func gpsSwitchDidChange(_ sender: UISwitch) {
        enableGPS(on: sender.isOn)
    }

    @IBAction func coppaSwitchDidChange(_ sender: UISwitch) {
        enableCoppa(on: sender.isOn)
    }

    @IBAction func httpsOnlySwitchDidChange(_ sender: UISwitch) {
        enableHTTPSOnly(on: sender.isOn)
    }

    //MARK: TableView
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        switch (indexPath.section, indexPath.row) {
        case (3, 0):
            showGenderSelector()
            break
        default:
            return
        }
    }

    //MARK: UI
    private func setupUI() {
        let userData = UserData.getSmaatoUserSettings()

        keywordsTextField.text = userData.keywords
        queryTextField.text = userData.query
        ageTextField.text = userData.age?.description
        genderTextField.text = userData.gender != .unknown ? userData.gender.asString : nil
        gpsSwitch.isOn = userData.gps
        coppaSwitch.isOn = userData.coppa
        httpsOnlySwitch.isOn = userData.httpsOnly
    }

    private func addGestureRecognizer() {
        let closeKeyboard = UITapGestureRecognizer(target: self, action: #selector(SettingsViewController.viewTapped(_:)))
        closeKeyboard.delegate = self
        view.addGestureRecognizer(closeKeyboard)
    }

    @objc private func viewTapped(_ sender: UITapGestureRecognizer) {
        view.endEditing(true)
    }
}

//MARK: -SmaatoSDK UserSettings functionality

extension SettingsViewController {

    fileprivate func setKeywords(_ keywords: String?) {
        UserDefaults.standard.setValue(keywords, forKey: UserDefaultKeys.keywordsKey)
        SmaatoSDK.userKeywords = keywords
    }

    fileprivate func setQuery(_ query: String?) {
        UserDefaults.standard.setValue(query, forKey: UserDefaultKeys.queryKey)
        SmaatoSDK.userSearchQuery = query
    }

    fileprivate func setAge(_ age: Int?) {
        UserDefaults.standard.setValue(age, forKey: UserDefaultKeys.ageKey)
        if let anAge = age {
            SmaatoSDK.userAge = anAge as NSNumber
        } else {
            SmaatoSDK.userAge = nil
        }
    }

    fileprivate func setGender(_ gender: SMAGender) {
        UserDefaults.standard.setValue(gender.rawValue, forKey: UserDefaultKeys.genderKey)
        SmaatoSDK.userGender = gender
    }

    fileprivate func enableGPS(on isEnabled: Bool) {
        if isEnabled {
            // If application has permission to use CoreLocation services,
            // Smaato SDK also can take coordinates for better ads targeting.
            locationManager.requestWhenInUseAuthorization()
        }
    }

    fileprivate func enableCoppa(on isEnabled: Bool) {
        SmaatoSDK.requireCoppaCompliantAds = isEnabled
    }

    fileprivate func enableHTTPSOnly(on isEnabled: Bool) {
        // HTTPSOnly setting will be applied after the application relaunch
        UserDefaults.standard.set(isEnabled, forKey: UserDefaultKeys.httpsSettingsKey)
    }
}

//MARK: - UITextField delegate

extension SettingsViewController: UITextFieldDelegate {

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

    func textFieldDidEndEditing(_ textField: UITextField) {

        switch textField {
        case keywordsTextField:
            setKeywords(textField.text)
            break

        case queryTextField:
            setQuery(textField.text)
            break

        case ageTextField:
            guard let ageText = textField.text else {
                setAge(nil)
                return
            }
            setAge(Int(ageText))
            break

        default:
            break
        }
    }

}

//MARK: - UIGestureRecognizer delegate

extension SettingsViewController: UIGestureRecognizerDelegate {

    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if touch.view is UITextField {
            return false
        } else if (touch.view?.isDescendant(of: tableView.cellForRow(at: IndexPath(item: 0, section: 3))!))! {
            return false
        }
        return true
    }

}

//MARK: - Under hood UI

extension SettingsViewController {

    private func showGenderSelector() {
        let actionSheetController: UIAlertController = UIAlertController(title: "SELECT GENDER",
                message: nil,
                preferredStyle: .actionSheet)

        let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel)
        actionSheetController.addAction(cancelAction)

        for gender in SMAGender.allValues {
            let action: UIAlertAction = UIAlertAction(title: gender.asString, style: .default) { [weak self] action -> Void in
                guard let this = self else {
                    return
                }
                this.genderTextField.text = gender.asString
                this.setGender(gender)
            }
            actionSheetController.addAction(action)
        }

        if let popoverController = actionSheetController.popoverPresentationController {
            popoverController.sourceView = sizeArrowImageView
            popoverController.sourceRect = CGRect(x: sizeArrowImageView.bounds.minX,
                    y: sizeArrowImageView.bounds.midY,
                    width: 0,
                    height: 0)
        }

        self.present(actionSheetController,
                animated: true,
                completion: nil)
    }

}

