//
//  YHDatePickView.swift
//  galaxy
//
//  Created by EDY on 2024/1/30.
//  Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//

/* 使用例子
 YHDatePickView.show(type: .yyyymmdd) { date in
     let arr = date.components(separatedBy: YHDatePickView.separator)
     // [yyyy, mm, dd] eg ["2024", "01", "20"]
     print(date)
 }
 */

import UIKit

enum YHDateType: Int {
    case yyyymmdd = 0
    case yyyymm = 1
    case yyyy = 2
    case timeForAppointHK = 3
}

class YHDatePickView: UIView {
    var backDate: ((String) -> Void)?
    var dismissBlock: (() -> Void)?
    var centerView: UIView!
    var titleLabel: UILabel!
    var closeButton: UIButton!
    var sureButton: UIButton!
    var lineView: UIView!
    var pickerView: UIPickerView!
    var lastIsTaday: Bool = false {
        didSet {
            guard let type = type else { return }
            var index = self.currentDateCom.year! - self.dateCom.year!
            if index > 99 {
                index = 0
            }
            switch type {
            case .yyyymmdd:
                pickerView.selectRow(99 - index, inComponent: 0, animated: true)
                pickerView.selectRow(self.dateCom.month! - 1, inComponent: 1, animated: true)
                pickerView.selectRow(self.dateCom.day! - 1, inComponent: 2, animated: true)
            case .yyyymm:
                pickerView.selectRow(99 - index, inComponent: 0, animated: true)
                pickerView.selectRow(self.dateCom.month! - 1, inComponent: 1, animated: true)
            case .yyyy:
                pickerView.selectRow(99 - index, inComponent: 0, animated: true)
            case .timeForAppointHK:
//                pickerView.selectRow(Int(arrTimeForAppointHK.count / 2), inComponent: 0, animated: true)
                handleDefaultTime()
            }
        }
    }
    
    var defaultTime: String = "" {
        didSet {
            handleDefaultTime()
        }
    }
    
    private var currentDateCom: DateComponents = Calendar.current.dateComponents([.year, .month, .day], from: Date())
    var dateCom: DateComponents = Calendar.current.dateComponents([.year, .month, .day], from: Date())
    // 日期分割符 eg: 2024-01-01
    static let separator: String = "-"
    
    // 固定参数值
    private var arrTimeForAppointHK: [String] = ["09:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00"]
        
    var title: String = "" {
        didSet {
            titleLabel.text = title
        }
    }
    var type: YHDateType? {
        didSet {
            guard let type = type else { return }
            switch type {
            case .yyyymmdd:
                pickerView.reloadAllComponents()
            case .yyyymm:
                pickerView.reloadAllComponents()
            case .yyyy:
                pickerView.reloadAllComponents()
            case .timeForAppointHK:
                pickerView.reloadAllComponents()
            }
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = UIColor(white: 0.5, alpha: 0.1)
        let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        tap.delegate = self
        addGestureRecognizer(tap)
        setView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setView() {
        backgroundColor = UIColor(hex: 0x0000, alpha: 0.5)
        centerView = {
            let view = UIView()
            view.backgroundColor = .white
            return view
        }()
        addSubview(centerView)
        centerView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(322)
        }
        
        titleLabel = {
            let label = UILabel()
            label.text = title
            label.font = UIFont.PFSC_M(ofSize: 17)
            label.textColor = UIColor.mainTextColor
            label.textAlignment = .center
            return label
        }()
        centerView.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.top.equalTo(16)
            make.height.equalTo(21)
            make.width.equalTo(200)
            make.centerX.equalToSuperview()
        }
        
        closeButton = {
            let button = UIButton(type: .custom)
            button.titleLabel?.font = UIFont.PFSC_M(ofSize: 14)
            button.contentHorizontalAlignment = .center
            button.setTitle("取消", for: .normal)
            button.setTitleColor( UIColor.mainTextColor, for: .normal)
            button.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
            return button
        }()
        centerView.addSubview(closeButton)
        closeButton.snp.makeConstraints { make in
            make.left.equalTo(21)
            make.height.equalTo(20)
            make.width.equalTo(30)
            make.top.equalTo(18)
        }
        
        sureButton = {
            let button = UIButton(type: .custom)
            button.titleLabel?.font = UIFont.PFSC_M(ofSize: 14)
            button.contentHorizontalAlignment = .center
            button.setTitle("确定", for: .normal)
            button.setTitleColor( UIColor.brandMainColor, for: .normal)
            button.addTarget(self, action: #selector(sure), for: .touchUpInside)
            return button
        }()
        centerView.addSubview(sureButton)
        sureButton.snp.makeConstraints { make in
            make.right.equalTo(-21)
            make.height.equalTo(20)
            make.width.equalTo(30)
            make.top.equalTo(18)
        }
        
        sureButton.YH_clickEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        
        lineView = {
            let view = UIView()
            view.backgroundColor = UIColor.separatorColor
            return view
        }()
        centerView.addSubview(lineView)
        lineView.snp.makeConstraints { make in
            make.left.equalTo(18)
            make.top.equalTo(52)
            make.height.equalTo(1)
            make.right.equalTo(-18)
        }
        
        pickerView = {
            let picker = UIPickerView()
            picker.delegate = self
            picker.dataSource = self
            picker.backgroundColor = UIColor.clear
            picker.clipsToBounds = true
            return picker
        }()
        centerView.addSubview(pickerView)
        pickerView.snp.makeConstraints { make in
            make.left.equalTo(16)
            make.top.equalTo(68)
            make.height.equalTo(220)
            make.right.equalTo(-16)
        }
        
        centerView.layoutIfNeeded()
        let corner = UIRectCorner(rawValue: UIRectCorner.topLeft.rawValue | UIRectCorner.topRight.rawValue)
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corner, cornerRadii: CGSize(width: kCornerRadius6, height: kCornerRadius6))
        let layer = CAShapeLayer()
        layer.frame = centerView.bounds
        layer.path = path.cgPath
        centerView.layer.mask = layer
    }
    
    @objc private func handleTap(_ sender: AnyObject?) {
        dismiss()
    }
    
    static func show(type: YHDateType, title: String? = nil, lastIsTaday: Bool = false, currentDay: String = "", callBack: @escaping ((String) -> Void), dismiss: (() -> Void)? = nil) {
        let view = YHDatePickView(frame: CGRect(x: 0, y: 0, width: KScreenWidth, height: KScreenHeight))
        view.type = type
        view.backDate = callBack
        view.dismissBlock = dismiss
        view.title = title ?? ""
        let dateFormatter = DateFormatter()
        switch type {
        case .yyyymmdd:
            dateFormatter.dateFormat = "yyyy-MM-dd"
        case .yyyymm:
            dateFormatter.dateFormat = "yyyy-MM"
        case .yyyy:
            dateFormatter.dateFormat = "yyyy"
        case .timeForAppointHK:
            dateFormatter.dateFormat = "yyyy"
        }
        
        if type == .timeForAppointHK {
            view.defaultTime = currentDay
        } else {
            if currentDay != "", let date = dateFormatter.date(from: currentDay) {
                view.dateCom = Calendar.current.dateComponents([.year, .month, .day], from: date)
            }
        }
       
        view.lastIsTaday = lastIsTaday
        let window = UIApplication.shared.yhKeyWindow()
        window?.addSubview(view)
    }
    
    @objc func dismiss() {
        if self.dismissBlock != nil {
            self.dismissBlock!()
        }
        removeFromSuperview()
    }
    
    @objc func sure() {
        guard let type = type else { return }
        var date = ""
        switch type {
        case .yyyymmdd:
            date = String(format: "%02ld%@%02ld%@%02ld", (self.currentDateCom.year!) + self.pickerView.selectedRow(inComponent: 0) - 99, Self.separator, self.pickerView.selectedRow(inComponent: 1) + 1, Self.separator, self.pickerView.selectedRow(inComponent: 2) + 1)
        case .yyyymm:
            date = String(format: "%02ld%@%02ld", (self.currentDateCom.year!) + self.pickerView.selectedRow(inComponent: 0) - 99, Self.separator, self.pickerView.selectedRow(inComponent: 1) + 1)
        case .yyyy:
            date = String(format: "%02ld", (self.currentDateCom.year!) + self.pickerView.selectedRow(inComponent: 0) - 99)
        case .timeForAppointHK:
            date = arrTimeForAppointHK[self.pickerView.selectedRow(inComponent: 0)]
        }
        if self.backDate != nil {
            self.backDate!(date)
        }
        dismiss()
    }
    
    func handleDefaultTime() {
        if type == .timeForAppointHK {
            var targetIndex: Int = -1
            if !defaultTime.isEmpty {
                for (index, item) in arrTimeForAppointHK.enumerated() {
                    if item == defaultTime {
                        targetIndex = index
                        break
                    }
                }
                
                if targetIndex > -1 {
//                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
//                        self.pickerView.selectRow(targetIndex, inComponent: 0, animated: true)
//                    }
                    
                    DispatchQueue.main.async {
                        self.pickerView.selectRow(targetIndex, inComponent: 0, animated: true)
                    }
                }
            }
        }
    }
}

extension YHDatePickView: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if touch.view == self {
            return true
        }
        return false
    }
}

extension YHDatePickView: UIPickerViewDelegate, UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        guard let type = type else { return 3 }
        switch type {
        case .yyyymmdd:
            return 3
        case .yyyymm:
            return 2
        case .yyyy:
            return 1
        case .timeForAppointHK:
            return 1
        }
    }
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if component == 0 {
            if let type = type, type == .timeForAppointHK {
                return arrTimeForAppointHK.count
            }
            if lastIsTaday {
                return 100
            }
            return 200
        } else if component == 1 {
            if self.pickerView.selectedRow(inComponent: 0) == 99 {
                if lastIsTaday {
                    return self.currentDateCom.month!
                }
            }
            return 12
        } else {
            let year: Int = pickerView.selectedRow(inComponent: 0) + currentDateCom.year!
            if type == .yyyy {
                return 0
            }
            if self.pickerView.selectedRow(inComponent: 0) == 99 && self.pickerView.selectedRow(inComponent: 1) == self.currentDateCom.month! - 1 {
                if lastIsTaday {
                    return self.currentDateCom.day!
                }
            }
            let month: Int = pickerView.selectedRow(inComponent: 1) + 1
            let days: Int = howManyDays(inThisYear: year, withMonth: month)
            return days
        }
    }
    
    private func howManyDays(inThisYear year: Int, withMonth month: Int) -> Int {
        if (month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12) {
            return 31
        }
        if (month == 4) || (month == 6) || (month == 9) || (month == 11) {
            return 30
        }
        if (year % 4 == 1) || (year % 4 == 2) || (year % 4 == 3) {
            return 28
        }
        if year % 400 == 0 {
            return 29
        }
        if year % 100 == 0 {
            return 28
        }
        return 29
    }
    
    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        guard let type = type else { return KScreenWidth / 3 }
        switch type {
        case .yyyymmdd:
            return KScreenWidth / 3
        case .yyyymm:
            return KScreenWidth / 2
        case .yyyy:
            return KScreenWidth
        case .timeForAppointHK:
            return KScreenWidth
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 44
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if #available(iOS 14.0, *), pickerView.subviews.count > 1 {
            pickerView.subviews[1].backgroundColor = UIColor.brandMainColor6
        }
        if component == 0 {
            if let type = type, type == .timeForAppointHK {
                return arrTimeForAppointHK[row]
            }
            return "\((currentDateCom.year!) + row - 99)"
        } else if component == 1 {
            return "\(row + 1)"
        } else {
            return "\(row + 1)"
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 0 || component == 1, self.type == .yyyymmdd {
            pickerView.reloadComponent(1)
            pickerView.reloadComponent(2)
        }
        
        if self.type == .yyyymm {
            pickerView.reloadComponent(1)
        }
    }
}
