//
//  SleepViewModels.swift
//  HPlusFit
//
//  Created by lemo. on 2019/10/6.
//  Copyright © 2019 lemo. All rights reserved.
//

import UIKit

fileprivate struct Metric {
    static let legends = [
        LegendData(docColor: kHexColor(0xF6BF47), name: MultiLanguageKey.awake.localized),
        LegendData(docColor: kHexColor(0xA4A3FF), name: MultiLanguageKey.shallowSleep.localized),
        LegendData(docColor: kHexColor(0x6E63FF), name: MultiLanguageKey.deepSleep.localized)
    ]
}

class SleepViewModels: ViewModel {
    
    // 图表数据
    lazy var relay: BehaviorRelay<ChartViewModel> = {
        return BehaviorRelay<ChartViewModel>(value: defaultVM)
    }()
    // 底部数据
    let formRealy = BehaviorRelay<HealthFormModel?>(value: nil)
    // 默认数据
    private lazy var defaultVM: ChartViewModel = {
        let chartViewModel: ChartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: [], source: [], chartType: .horizontalSegment, maxAxis: 12, xAxis: [], lineColor: kHexColor(0x6161ED), isShowMeasureLine: false, center: nil, centerColor: kHexColor(0xEEA82C), centerUnit: nil)
        return chartViewModel
    }()
    /// 当前时间(默认当前)
    private var currenTimeStr = DateClass.getCurrentTimeStr(formatStr: "yyyy-MM-dd")
    private var queryType: DataQueryType = .day
    
    override init() {
        super.init()
        // 默认加载当天
        loadSleepData(timeStr: currenTimeStr, queryType: queryType)
    }
    
    
    /// 加载计步数据
    func loadSleepData(timeStr: String?, queryType: DataQueryType?) {
        // 无查询类型默认为上一次查询类型
        let tempQueryType = queryType == nil ? self.queryType : queryType!
        self.queryType = tempQueryType
        // 查询时间戳
        let tempTimeStr = timeStr == nil ? currenTimeStr : timeStr!
        currenTimeStr = tempTimeStr
        DataBaseManager.shared.querySleepModel(dataDate: tempTimeStr, queryType: tempQueryType) { [weak self] (results) in
            guard let `self` = self else { return }
            guard let sleepModelArr = results as? [SleepModel], sleepModelArr.count > 0 else {
                self.relay.accept(self.defaultVM)
                self.formRealy.accept(nil)
                return
            }
            // 拼接数据模型
            var chartViewModel: ChartViewModel!
            var formModel: HealthFormModel?
            switch tempQueryType {
            case .day:
                let sleepModel = sleepModelArr.first!
                if sleepModel.totalSleepDuration == 0 {
                    self.relay.accept(self.defaultVM)
                    self.formRealy.accept(nil)
                    return
                }
                let source: [ChartViewData] = self.processSleepDetails(model: sleepModel)
                chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: Metric.legends, source: source, chartType: .horizontalSegment, maxAxis: 12, xAxis: ["21:00", "00:00", "03:00", "06:00", "09:00"], lineColor: kHexColor(0x6161ED), isShowMeasureLine: false, center: String(format: "%02d:%02d", sleepModel.totalSleepDuration / 60, sleepModel.totalSleepDuration % 60), centerColor: kHexColor(0x5447F6), centerUnit: MultiLanguageKey.hour.localized)
                // 底部数据总和
//                formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", sleepModel.deepSleepDuration / 60, sleepModel.deepSleepDuration % 60), twoValue: String(format: "%02d:%02d", sleepModel.lightSleepDuration / 60, sleepModel.lightSleepDuration % 60), threeValue: String(format: "%02d:%02d", sleepModel.totalSleepDuration / 60, sleepModel.totalSleepDuration % 60), fourValue: String(sleepModel.awakeNumber))
                formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", sleepModel.deepSleepDuration / 60, sleepModel.deepSleepDuration % 60), twoValue: String(format: "%02d:%02d", sleepModel.lightSleepDuration / 60, sleepModel.lightSleepDuration % 60), threeValue: String(format: "%02d:%02d", sleepModel.totalSleepDuration / 60, sleepModel.totalSleepDuration % 60), fourValue: String(sleepModel.awakeDuration%60))
            case .week:
                // 获取一周时间戳数组
                let weeks = (0...6).map { DateClass.dateStringOffset(from: tempTimeStr, offset: $0) }
                var sources: [ChartViewData] = []
                var maxAxis = 0
                var totalDeepSleep = 0
                var totalShallowSleep = 0
                var totalAwakeSleep = 0
                var totalSleep = 0
                var totalAwakeNumber = 0
                var xAxis: [String] = []
                // 边里匹配对应日期数据数组
                for dataDate in weeks {
                    let showDate = DateClass.getTimeStrToDate(formatStr: "yyyy-MM-dd", timeStr: dataDate).tranFormDateStr(format: "MM/dd")
                    xAxis.append(showDate)
                    var isMatch = false
                    for sleepModel in sleepModelArr {
                        if dataDate == sleepModel.dataDate && sleepModel.totalSleepDuration > 0 {
                            isMatch = true
                            if sleepModel.totalSleepDuration > maxAxis {
                                maxAxis = sleepModel.totalSleepDuration
                            }
                            totalDeepSleep += sleepModel.deepSleepDuration
                            totalShallowSleep += sleepModel.lightSleepDuration
                            totalAwakeSleep += sleepModel.awakeDuration
                            totalSleep += sleepModel.totalSleepDuration
                            totalAwakeNumber += sleepModel.awakeNumber
                            sources.append(ChartViewData(date: "", number: 0, sum: Float(sleepModel.totalSleepDuration) / 60.0, sleeps: [
                                sleepData(type: 2, value: Float(sleepModel.deepSleepDuration) / 60.0),
                                sleepData(type: 0, value: Float(sleepModel.awakeDuration) / 60.0),
                                sleepData(type: 1, value: Float(sleepModel.lightSleepDuration) / 60.0)
                                ], fallingsleepTimes: "", awakeTimes: ""))
                        }
                        // 添加空数据
                        if !isMatch {
                            sources.append(ChartViewData(date: "", number: 0, sum: 0.0, sleeps: [
                                sleepData(type: 2, value: 0.0),
                                sleepData(type: 0, value: 0.0),
                                sleepData(type: 1, value: 0.0)
                                ], fallingsleepTimes: "", awakeTimes: ""))
                        }
                    }
                }
                chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: Metric.legends, source:sources, chartType: .segmentBar, maxAxis: maxAxis / 60 + 2, xAxis: xAxis, lineColor: kHexColor(0xEEA82C), center: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), centerColor: kHexColor(0x5447F6), centerUnit: "")
                chartViewModel.points = sources.count
                // 底部数据总和
                formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", totalDeepSleep / 60, totalDeepSleep % 60), twoValue: String(format: "%02d:%02d", totalShallowSleep / 60, totalShallowSleep % 60), threeValue: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), fourValue: String(format: "%02d:%02d", totalAwakeSleep / 60, totalAwakeSleep % 60))
                
            case .month:
                // 获取一个月时间戳数组
                let selectDate = DateClass.getTimeStrToDate(formatStr: "yyyy-MM-dd", timeStr: tempTimeStr)
                let monthSatrtDate = selectDate.startOfCurrentMonth().tranFormDateStr(format: "yyyy-MM-dd")
                let monthRange = selectDate.getMonthHowManyDay()
                let months = monthRange.map { DateClass.dateStringOffset(from: monthSatrtDate, offset: $0 - 1) }
                var sources: [ChartViewData] = []
                var maxAxis = 0
                var totalDeepSleep = 0
                var totalShallowSleep = 0
                var totalAwakeSleep = 0
                var totalSleep = 0
                var totalAwakeNumber = 0
                var xAxis: [String] = []
                // 边里匹配对应日期数据数组
                for (offset, dataDate) in months.enumerated() {
                    // 只展示每周的
                    if offset == 0 || offset == months.count - 1 || offset == (months.count / 2) {
                        let showDate = DateClass.getTimeStrToDate(formatStr: "yyyy-MM-dd", timeStr: dataDate).tranFormDateStr(format: "dd")
                        xAxis.append(showDate)
                    }
                    var isMatch = false
                    for sleepModel in sleepModelArr {
                        let totalSleepTime = sleepModel.totalSleepDuration
                        if dataDate == sleepModel.dataDate && totalSleepTime > 0 {
                            isMatch = true
                            if totalSleepTime > maxAxis {
                                maxAxis = totalSleepTime
                            }
                            totalDeepSleep += sleepModel.deepSleepDuration
                            totalShallowSleep += sleepModel.lightSleepDuration
                            totalAwakeSleep += sleepModel.awakeDuration
                            totalSleep += sleepModel.totalSleepDuration
                            totalAwakeNumber += sleepModel.awakeNumber
                            sources.append(ChartViewData(date: "", number: 0, sum: Float(sleepModel.totalSleepDuration) / 60.0, sleeps: [
                                sleepData(type: 2, value: Float(sleepModel.deepSleepDuration) / 60.0),
                                sleepData(type: 0, value: Float(sleepModel.awakeDuration) / 60.0),
                                sleepData(type: 1, value: Float(sleepModel.lightSleepDuration) / 60.0)
                            ], fallingsleepTimes: "", awakeTimes: ""))
                        }
                        // 添加空数据
                        if !isMatch {
                            sources.append(ChartViewData(date: nil, number: 0, sum: 0.0, sleeps: [
                                sleepData(type: 2, value: 0.0),
                                sleepData(type: 0, value: 0.0),
                                sleepData(type: 1, value: 0.0)
                                ], fallingsleepTimes: "", awakeTimes: ""))
                        }
                    }
                }
                chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: Metric.legends, source:sources, chartType: .rectangleSegBar, maxAxis: maxAxis / 60 + 2, xAxis: xAxis, lineColor: kHexColor(0xEEA82C), center: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), centerColor: kHexColor(0x5447F6), centerUnit: "")
                chartViewModel.points = sources.count
                // 底部数据总和
                formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", totalDeepSleep / 60, totalDeepSleep % 60), twoValue: String(format: "%02d:%02d", totalShallowSleep / 60, totalShallowSleep % 60), threeValue: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), fourValue: String(format: "%02d:%02d", totalAwakeSleep / 60, totalAwakeSleep % 60))
   
            default:
                self.relay.accept(self.defaultVM)
                self.formRealy.accept(nil)
                return
            }
            // 更新数据
            self.relay.accept(chartViewModel)
            self.formRealy.accept(formModel)
        }
    }
    
}

extension SleepViewModels {
    
    /// 处理睡眠详情数据
    ///
    /// - Parameter sleepDetails: 睡眠详情
    /// - Returns: 图表模型
    private func processSleepDetails(model: SleepModel) -> [ChartViewData] {
        var chartViewArray: [ChartViewData] = []
        let detailsArr: [String] = model.sleepDetails.components(separatedBy: ",")
        for detail in detailsArr {
            let comps = detail.components(separatedBy: "|")
            // 睡眠详情数据(睡眠类型|开始时间戳|持续时长|结束时间戳,..)
            if comps.count == 4 {
                // 睡眠类型(转换图表类型)
                let type = (comps.first! as NSString).integerValue
                // 开始时间
                let startTime = DateClass.timestampToStr(comps[1].integerValue, formatStr: "HH:mm")
                // 时长
                let duration = comps[2].integerValue
                // 结束时间
                let endTime = DateClass.timestampToStr(comps[3].integerValue, formatStr: "HH:mm")
                // 创建图表数据模型
                let chartData = ChartViewData(sleep: sleepData(type: type, value: Float(duration) / 60.0, begin: startTime, end: endTime))
                chartViewArray.append(chartData)
            }
        }
        return chartViewArray
    }
    
    private func minToStr(min: Int) -> String {
        return String(format: "%02d:%02d", min / 60, min % 60)
    }
    
}