//
//  OOAttendanceCheckInNewController.swift
//  O2Platform
//
//  Created by FancyLou on 2020/7/21.
//  Copyright © 2020 zoneland. All rights reserved.
//

import UIKit
import CocoaLumberjack


class OOAttendanceCheckInNewController: UIViewController {


    @IBOutlet weak var checkInBtnTimeLabel: UILabel!
    @IBOutlet weak var checkInBtnLable: UILabel!
    @IBOutlet weak var checkInBtnView: UIView!
    @IBOutlet weak var locationCheckImageView: UIImageView!
    @IBOutlet weak var locationLabel: UILabel!
    @IBOutlet weak var schedulesView: UICollectionView!

    fileprivate let itemNumberInRow = 2

    //定位
    private var userLocation: BMKUserLocation!
    private var locService: BMKLocationManager!
    private var searchAddress: BMKGeoCodeSearch!
    private var workPlaces: [OOAttandanceWorkPlace] = []

    //定时器
    private var timer: Timer?
    private lazy var viewModel: OOAttandanceViewModel = {
        return OOAttandanceViewModel()
    }()
    //打卡和班次
    private var schedules: [OOAttandanceMobileScheduleInfo] = []
    private var lastRecord: OOAttandanceMobileDetail? = nil
    private var needCheckIn = false
    private var isInWorkPlace = false
    private var bmkResult: BMKReverseGeoCodeSearchResult? = nil
    //打卡对象
    var checkinForm: OOAttandanceMobileCheckinForm = OOAttandanceMobileCheckinForm()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.schedulesView.delegate = self
        self.schedulesView.dataSource = self
        self.schedulesView.register(UINib(nibName: "OOAttendanceScheduleViewCell", bundle: nil), forCellWithReuseIdentifier: "OOAttendanceScheduleViewCell")
        self.checkInBtnView.addTapGesture { (tap) in
            self.postCheckinButton(nil)
        }

        //初始化定时器
        self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timeTick), userInfo: nil, repeats: true)
        //获取数据
        self.loadMyRecords()
        //工作地址
        self.loadWorkPlace()
    }

    override func viewWillAppear(_ animated: Bool) {
        self.timer?.fire()
        self.startLocationService()
    }

    override func viewWillDisappear(_ animated: Bool) {
        self.timer?.invalidate()
        self.stopLocationService()
    }

    ///打卡
    private func postCheckinButton(_ scheduleInfo: OOAttandanceMobileScheduleInfo?) {
        if !self.needCheckIn {
            self.showError(title: "当前不需要打卡！")
            return
        }
        if !self.isInWorkPlace {
            self.showError(title: "不在打卡范围内！")
            return
        }


        if let info = scheduleInfo, info.recordId != nil { //更新打卡
            self.showDefaultConfirm(title: "更新打卡", message: "确定要更新这条打卡数据吗？") { (action) in
                self.showLoading()
                self.checkinForm.id = info.recordId
                self.checkinForm.recordAddress = self.bmkResult?.address
                self.checkinForm.desc = self.bmkResult?.sematicDescription
                self.checkinForm.longitude = String(self.bmkResult?.location.longitude ?? 0.0)
                self.checkinForm.latitude = String(self.bmkResult?.location.latitude ?? 0.0)
                self.checkinForm.empNo = O2AuthSDK.shared.myInfo()?.employee
                self.checkinForm.empName = O2AuthSDK.shared.myInfo()?.name
                let currenDate = Date()
                self.checkinForm.recordDateString = currenDate.toString("yyyy-MM-dd")
                self.checkinForm.signTime = currenDate.toString("HH:mm:ss")
                self.checkinForm.optMachineType = UIDevice.deviceModelReadable()
                self.checkinForm.optSystemName = "\(UIDevice.systemName()) \(UIDevice.systemVersion())"
                self.checkinForm.checkin_type = info.checkinType
                self.viewModel.postMyCheckin(self.checkinForm) { (result) in
                    DispatchQueue.main.async {
                        self.hideLoading()
                    }
                    switch result {
                    case .ok(_):
                        self.loadMyRecords()
                        break
                    case .fail(let errorMessage):
                        DDLogError(errorMessage)
                        break
                    default:
                        break
                    }
                }
            }
        } else {
            let reversed = self.schedules.reversed()
            var newList: [OOAttandanceMobileScheduleInfo] = []
            reversed.forEach { (info) in
                if info.checkinStatus == "未打卡" {
                    newList.append(info)
                }
            }
            let checkType = newList.count > 0 ? newList.last!.checkinType : ""
            self.showLoading()
            checkinForm.id = nil
            checkinForm.recordAddress = self.bmkResult?.address
            checkinForm.desc = self.bmkResult?.sematicDescription
            checkinForm.longitude = String(self.bmkResult?.location.longitude ?? 0.0)
            checkinForm.latitude = String(self.bmkResult?.location.latitude ?? 0.0)
            checkinForm.empNo = O2AuthSDK.shared.myInfo()?.employee
            checkinForm.empName = O2AuthSDK.shared.myInfo()?.name
            let currenDate = Date()
            checkinForm.recordDateString = currenDate.toString("yyyy-MM-dd")
            checkinForm.signTime = currenDate.toString("HH:mm:ss")
            checkinForm.optMachineType = UIDevice.deviceModelReadable()
            checkinForm.optSystemName = "\(UIDevice.systemName()) \(UIDevice.systemVersion())"
            checkinForm.checkin_type = checkType
            viewModel.postMyCheckin(checkinForm) { (result) in
                DispatchQueue.main.async {
                    self.hideLoading()
                }
                switch result {
                case .ok(_):
                    self.loadMyRecords()
                    break
                case .fail(let errorMessage):
                    DDLogError(errorMessage)
                    break
                default:
                    break
                }
            }
        }


    }

    ///接收到位置信息
    private func locationReceive(bmkResult: BMKReverseGeoCodeSearchResult, isIn: Bool, workPlace: OOAttandanceWorkPlace?) {
        self.isInWorkPlace = isIn
        self.bmkResult = bmkResult
        if isIn {
            // 打卡按钮启用
            self.locationLabel.text = workPlace?.placeName
            self.locationCheckImageView.image = UIImage(named: "icon__ok2_click")
        } else {
            //打卡按钮禁用
            self.locationLabel.text = bmkResult.address
            self.locationCheckImageView.image = UIImage(named: "icon_delete_1")
        }
    }

    ///定位
    private func startLocationService() {
        locService = BMKLocationManager()
        locService.desiredAccuracy = kCLLocationAccuracyBest
        //设置返回位置的坐标系类型
        locService.coordinateType = .BMK09LL
        //设置距离过滤参数
        locService.distanceFilter = kCLDistanceFilterNone;
        //设置预期精度参数
        locService.desiredAccuracy = kCLLocationAccuracyBest;
        //设置应用位置类型
        locService.activityType = .automotiveNavigation
        //设置是否自动停止位置更新
        locService.pausesLocationUpdatesAutomatically = false

        locService.delegate = self
        locService.startUpdatingLocation()

        searchAddress = BMKGeoCodeSearch()
        searchAddress.delegate = self
    }
    ///结束定位
    private func stopLocationService() {
        locService.stopUpdatingLocation()
        locService.delegate = nil
        searchAddress.delegate = nil
    }

    ///查询工作地址
    private func loadWorkPlace() {
        self.viewModel.getLocationWorkPlace { (myResult) in
            switch myResult {
            case .ok(let result):
                if let model = result as? [OOAttandanceWorkPlace] {
                    DispatchQueue.main.async {
                        self.workPlaces = model
                    }
                }
                break
            case .fail(let s):
                self.showError(title: "错误:\n\(s)")
                break
            default:
                break
            }
        }
    }
    ///获取打卡记录和班次数据
    private func loadMyRecords() {
        self.viewModel.listMyRecords { (result) in
            switch result {
            case .ok(let record):
                let model = record as? OOMyAttandanceRecords
                let records = model?.records ?? []
                self.lastRecord = records.last
                var unCheckNumber = 0
                self.schedules.removeAll()
                model?.scheduleInfos?.forEach({ (f) in
                    let info = OOAttandanceMobileScheduleInfo()
                    info.signTime = f.signTime
                    info.signDate = f.signDate
                    info.checkinType = f.checkinType
                    info.signSeq = f.signSeq
                    let anyRecord = records.first { (detail) -> Bool in
                        detail.checkin_type == f.checkinType
                    }
                    if anyRecord != nil {
                        info.checkinStatus = "已打卡"
                        info.recordId = anyRecord?.id
                        info.checkinTime = anyRecord?.signTime
                        unCheckNumber = 0
                    } else {
                        info.checkinStatus = "未打卡"
                        unCheckNumber += 1
                    }
                    self.schedules.append(info)
                })
                DispatchQueue.main.async {
                    if unCheckNumber > 0 {
                        self.needCheckIn = true
                        self.setCheckInBtnEnableStyle()
                    } else {
                        self.needCheckIn = false
                        self.setCheckInBtnDisableStyle()
                    }
                    self.schedulesView.reloadData()
                }
                break
            case .fail(let err):
                DDLogError(err)
                DispatchQueue.main.async {
                    self.needCheckIn = false
                    self.setCheckInBtnDisableStyle()
                }
                break
            default:
                DDLogError("default ..................")
                break
            }
        }
    }

    private func setCheckInBtnDisableStyle() {
        self.checkInBtnView.backgroundColor = UIColor(hex: "#cccccc")
    }
    private func setCheckInBtnEnableStyle() {
        self.checkInBtnView.backgroundColor = base_color
    }

    ///刷新按钮时间
    @objc private func timeTick() {
        let now = Date().toString("HH:mm:ss")
        self.checkInBtnTimeLabel.text = now
    }

}

extension OOAttendanceCheckInNewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.schedules.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "OOAttendanceScheduleViewCell", for: indexPath) as? OOAttendanceScheduleViewCell {
            let s = self.schedules[indexPath.row]
            let isLastRecord = s.recordId == self.lastRecord?.id
            cell.setData(info: s, isLastRecord: isLastRecord)
            return cell
        }
        return UICollectionViewCell()
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let s = self.schedules[indexPath.row]
        if let last = self.lastRecord, last.id == s.recordId {
            self.postCheckinButton(s)
        }
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: ((SCREEN_WIDTH - 52) / 2), height: 64)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 5.0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0.0
    }

}



extension OOAttendanceCheckInNewController: BMKLocationManagerDelegate {

    func bmkLocationManager(_ manager: BMKLocationManager, didUpdate location: BMKLocation?, orError error: Error?) {
        if let loc = location?.location {
            DDLogDebug("当前位置,\(loc.coordinate.latitude),\(loc.coordinate.longitude)")
            //搜索到指定的地点
            let re = BMKReverseGeoCodeSearchOption()
            re.location = CLLocationCoordinate2D(latitude: loc.coordinate.latitude, longitude: loc.coordinate.longitude)
            let _ = searchAddress.reverseGeoCode(re)
        } else {
            DDLogError("没有获取到定位信息！！！！！")
        }
    }


}

extension OOAttendanceCheckInNewController: BMKGeoCodeSearchDelegate {

    /// 计算所有位置是否有一个位置在误差范围内
    func calcErrorRange(_ checkinLocation: CLLocationCoordinate2D) -> (Bool, OOAttandanceWorkPlace?) {
        var result = false
        for item in self.workPlaces {
            let longitude = Double((item.longitude)!)
            let latitude = Double((item.latitude)!)
            let eRange = item.errorRange!
            let theLocation = CLLocationCoordinate2DMake(latitude!, longitude!)
            result = BMKCircleContainsCoordinate(theLocation, checkinLocation, Double(eRange))
            if result == true {
                return (true, item)
            }
        }
        return (false, nil)
    }

    func onGetReverseGeoCodeResult(_ searcher: BMKGeoCodeSearch?, result: BMKReverseGeoCodeSearchResult?, errorCode error: BMKSearchErrorCode) {
        //发送定位的实时位置及名称信息
        if let location = result?.location {
            let calResult = calcErrorRange(location)
            self.locationReceive(bmkResult: result!, isIn: calResult.0, workPlace: calResult.1)
        }
    }

    func onGetGeoCodeResult(_ searcher: BMKGeoCodeSearch!, result: BMKGeoCodeSearchResult!, errorCode error: BMKSearchErrorCode) {
        if Int(error.rawValue) == 0 {
            DDLogDebug("result \(String(describing: result))")
        } else {
            DDLogDebug("result error  errorCode = \(Int(error.rawValue))")
        }

    }
}

