//
//  HealthHomeViewModel.swift
//  Lookfit
//
//  Created by Sheldon on 2021/9/19.
//  Copyright © 2021 Sheldon. All rights reserved.
//

import UIKit

class HealthHomeViewModel: ViewModel {

    // 用户信息
    let userIcon = BehaviorRelay<UIImage?>(value: R.image.icon_header())
    let userNickname = BehaviorRelay<String?>(value: nil)
    
    // 健康数据
    let relay = BehaviorRelay<[HealthSection]>(value: [])
    /// 用户信息
    private var userInfo = BehaviorRelay<UserInfo?>(value: nil)
    private var sleepHeartCellVM: SleepHeartCellViewModel?
    
    /// 发现DFU设备,自动升级
    let dfuDeviceUpgrate = PublishSubject<FirmwareUpdateViewModel>()
    
    private var tempDisposeBag = DisposeBag()
    
    override init() {
        super.init()
        // 监听系统时间改变
        var currenDay = DateClass.todayString()
        kNotificationCenter.rx.notification(UIApplication.significantTimeChangeNotification)
            .subscribe(onNext: { notication in
                // 日期改变了
                let newDay = DateClass.todayString()
                if currenDay != newDay {
                    currenDay = newDay
                    kNotificationCenter.post(name: NSNotification.Name(rawValue: DateChange), object: nil)
                }
            })
            .disposed(by: rx.disposeBag)
        loadDefaultData()
        loadHealthData()
        monitor()
    }
    
    private func loadDefaultData() {
        userInfo.accept(UserDefaultsManager.getUserInfo())
        userInfo.flatMapLatest({ (userInfo) -> Observable<UIImage?> in
            return Observable.just(userInfo?.avatarImg)
        })
            .filter { $0 != nil }
            .bind(to: userIcon)
            .disposed(by: rx.disposeBag)
        userInfo.flatMapLatest({ (userInfo) -> Observable<String?> in
                return Observable.just(userInfo?.nickname)
            })
            .bind(to: userNickname)
            .disposed(by: rx.disposeBag)
    }
    
    private func loadHealthData() {
        tempDisposeBag = DisposeBag()
        var items: [HealthSectionItem] = []
        // 功能适配
        var defaultTypes: [HealthType] = [.step, .heartRate]
        if let adapterInfo = UserDefaultsManager.getDeviceInfo()?.adapterInfo {
            if adapterInfo.sleep { defaultTypes.insert(.sleep, at: 1) }
            if adapterInfo.bodyTemperature { defaultTypes.append(.temperature) }
            if adapterInfo.bloodPressure { defaultTypes.append(.bloodPressure) }
            if adapterInfo.bloodOxygen { defaultTypes.append(.bloodOxygen) }
//            defaultTypes.append(.temperature)
//            defaultTypes.append(.bloodPressure)
//            defaultTypes.append(.bloodOxygen)
        }
        // 数据拼接
        defaultTypes.forEach { type in
            var item: HealthSectionItem
            if type == .step {
                let stepCellVM = StepCellViewModel()
                let stepItem = HealthSectionItem.stepItem(viewModel: stepCellVM)
                item = stepItem
                // 数据绑定
                BluetoothService.shared.realStep
                    .bind(to: stepCellVM.realStepModel)
                    .disposed(by: tempDisposeBag)
            }else {
                let healthItemCellVM = HealthCellViewModel(type: type)
                let healthItem = HealthSectionItem.healthItem(viewModel: healthItemCellVM)
                item = healthItem
                // 数据绑定
                switch type {
                case .sleep:
                    BluetoothService.shared.sleepUpdate
                        .subscribe(onNext: { _ in
                            DataBaseManager.shared.querySleepModel(dataDate: DateClass.todayString(), queryType: .day) { [weak self] (model) in
                                guard let sleepModel = model.first as? SleepModel else { return }
                                let sleep = String(format: "%.1f", Float(sleepModel.totalSleepDuration) / 60.0)
                                let progress = Float(sleepModel.totalSleepDuration) / Float(self?.userInfo.value?.sleepTarget ?? 480)
                                healthItemCellVM.value.accept(sleep)
                                healthItemCellVM.progress.accept(progress)
                            }
                        })
                        .disposed(by: tempDisposeBag)
                    userInfo.flatMapLatest { (userInfo) -> Observable<String> in
                        let sleepTarget = String(format: "%.1f", Float(userInfo?.sleepTarget ?? 480) / 60.0)
                        let value = MultiLanguageKey.sleepTarget.localized + ":" + sleepTarget
                        return Observable.just(value)
                    }.bind(to: healthItemCellVM.target)
                    .disposed(by: tempDisposeBag)
                case .heartRate:
                    BluetoothService.shared.realHeartRate
                        .flatMapLatest { (heartRate) -> Observable<String> in
                            let value = heartRate.heartRate == 0 ? "--" : String(heartRate.heartRate)
                            return Observable.just(value)
                        }
                        .bind(to: healthItemCellVM.value)
                        .disposed(by: tempDisposeBag)
                case .temperature:
                    BluetoothService.shared.realTemperature
                        .flatMapLatest { (temperature) -> Observable<String> in
                            let value = temperature.temperature == 0 ? "--" : String(format: "%.1f", temperature.temperature)
                            return Observable.just(value)
                        }
                        .bind(to: healthItemCellVM.value)
                        .disposed(by: tempDisposeBag)
                case .bloodPressure:
                    BluetoothService.shared.realBloodPressure
                        .flatMapLatest { (model) -> Observable<String> in
                            let value = model.sbp == 0 ? "--" : String(format: "%ld/%ld", model.sbp, model.dbp)
                            return Observable.just(value)
                        }
                        .bind(to: healthItemCellVM.value)
                        .disposed(by: tempDisposeBag)
                case .bloodOxygen:
                    BluetoothService.shared.realBloodOxygen
                        .flatMapLatest { (model) -> Observable<String> in
                            let value = model.bloodOxygen == 0 ? "--" : String(model.bloodOxygen) + "%"
                            return Observable.just(value)
                        }
                        .bind(to: healthItemCellVM.value)
                        .disposed(by: tempDisposeBag)
                default: break
                }
            }
            items.append(item)
        }
        // 插入空Item(一行四个Item,每行第一个最后一个插入)
        let tempItems = items[1...items.count - 1]
        let totalRow = tempItems.count/2 + tempItems.count%2
        for i in (0..<totalRow) {
            items.insert(HealthSectionItem.blankItem, at: 1 + i * 4)
            var endIndex = 4 + i * 4
            if endIndex > items.count {
                endIndex = items.count
            }
            items.insert(HealthSectionItem.blankItem, at: endIndex)
        }
        let section = HealthSection.health(title: "", items: items)
        relay.accept([section])
    }
    
    private func monitor() {
        // 用户信息更新
        kNotificationCenter.rx.notification(Notification.Name(rawValue: UserInfoUpdate))
            .flatMapLatest({ _ -> Observable<UserInfo?> in
                return Observable.just(UserDefaultsManager.getUserInfo())
            })
            .bind(to: userInfo)
            .disposed(by: rx.disposeBag)
        // 数据同步完成刷新睡眠
        BluetoothService.shared.syncState.skip(1)
            .subscribe(onNext: { [weak self] (syncState) in
                guard let `self` = self else { return }
                switch syncState {
                case .normal:
                    DataBaseManager.shared.querySleepModel(dataDate: DateClass.getCurrentTimeStr(formatStr: "yyyy-MM-dd"), queryType: .day) { (model) in
                        guard let sleepModel = model.first as? SleepModel else { return }
                        let sleep = String(format: "%.1f", Float(sleepModel.totalSleepDuration) / 60.0)
                        let progress = Float(sleepModel.totalSleepDuration) / Float(self.userInfo.value?.sleepTarget ?? 480)
                        self.sleepHeartCellVM?.sleep.accept(sleep)
                        self.sleepHeartCellVM?.sleepProgress.accept(progress)
                    }
                default: break
                }
            })
            .disposed(by: rx.disposeBag)
        // 日期改变
        kNotificationCenter.rx.notification(Notification.Name(rawValue: DateChange))
            .subscribe(onNext: { [weak self] notication in
                guard let `self` = self else { return }
                self.loadHealthData()
            })
            .disposed(by: rx.disposeBag)
        // 功能适配
        BluetoothService.shared.adapterInfoUpdate
            .subscribe(onNext: { [weak self] _ in
                guard let `self` = self else { return }
                self.loadHealthData()
            })
            .disposed(by: rx.disposeBag)
        // DFU设备
        kNotificationCenter.rx.notification(Notification.Name(rawValue: BluetoothNotificationAtDFUConnectSuccess))
            .subscribe(onNext: { [weak self] _ in
                guard let `self` = self else { return }
                let viewModel = FirmwareUpdateViewModel(isDFU: true)
                self.dfuDeviceUpgrate.onNext(viewModel)
            })
            .disposed(by: rx.disposeBag)
    }
}