//
//  YHRangeDatePickerView.swift
//  galaxy
//
//  Created by davidhuangA on 2024/8/22.
//  Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//

import UIKit
import FSCalendar

class YHRangeDatePickerView: UIView, FSCalendarDataSource, FSCalendarDelegate, FSCalendarDelegateAppearance {
    
    static let viewH: CGFloat = 508.0
    
    lazy var calendar: FSCalendar = {
//        let calendar = FSCalendar(frame: CGRect(x: 0, y: (navigationController?.navigationBar.frame.maxY)!  + 30, width: view.frame.size.width, height: 510))
        
        let calendar = FSCalendar()
        calendar.locale = NSLocale(localeIdentifier: "zh-CN") as Locale
        calendar.dataSource = self
        calendar.delegate = self
        calendar.pagingEnabled = false
        calendar.allowsMultipleSelection = true
        calendar.rowHeight = 60
        calendar.weekdayHeight = 40
        calendar.locale = Locale(identifier: "zh-CN")
        calendar.scope = .month
        calendar.appearance.headerDateFormat = "yyyy年MM月"
        
        // 隐藏 当日的 图片
        calendar.today = nil
        calendar.register(YHRangeDatePickerCell.self, forCellReuseIdentifier: YHRangeDatePickerCell.cellReuseIdentifier)
        
        // 副标偏移量
        calendar.appearance.subtitleOffset = CGPoint(x: 0, y: 16)
        
        // 头部日期 字体
        calendar.appearance.headerTitleFont = UIFont(name: "PingFangSC-Medium", size: 15)
        
        // 头部日期 颜色
        calendar.appearance.headerTitleColor = UIColor(red: 0.071, green: 0.102, blue: 0.149, alpha: 1)
        
        // 头部week 字体
        calendar.appearance.weekdayFont = UIFont(name: "PingFangSC-Regular", size: 13)
        
        // 头部week 颜色
        calendar.appearance.weekdayTextColor = UIColor(red: 0.071, green: 0.102, blue: 0.149, alpha: 1)
        
        // 日历内容 默认颜色
//        calendar.appearance.titleDefaultColor = UIColor(red: 0.071, green: 0.102, blue: 0.149, alpha: 1)
        
        // 日历内容 字体
        calendar.appearance.titleFont = UIFont(name: "PingFangSC-Medium", size: 16)
        calendar.appearance.subtitleFont = UIFont(name: "PingFangSC-Medium", size: 9)
        
        // 日历内容 选择时 颜色
        calendar.appearance.titleSelectionColor = .white
        calendar.appearance.subtitleSelectionColor = .white
//        calendar.appearance.todayColor = UIColor(red: 0, green: 0.275, blue: 0.706, alpha: 1)
//        calendar.appearance.todaySelectionColor = .white
        
//        calendar.appearance.titleTodayColor = UIColor(red: 0, green: 0.275, blue: 0.706, alpha: 1)
        
        // 非当月日期 颜色
        calendar.appearance.titlePlaceholderColor = UIColor(red: 0.071, green: 0.102, blue: 0.149, alpha: 0.2)
        
        // 日期 横线
        calendar.appearance.separators = .none
        return calendar
    }()
    
    lazy var gregorian: Calendar = {
        let gregorian = Calendar(identifier: .chinese)
        return gregorian
    }()
    
    lazy var dateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        return dateFormatter
    }()
    
    // The start date of the range
    var startDate: Date?
    // The end date of the range
    var endDate: Date?
    
    override init(frame: CGRect) {
        super.init(frame: .zero)
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// MARK: - FSCalendarDataSource
extension YHRangeDatePickerView {
    
    func calendar(_ calendar: FSCalendar, subtitleFor date: Date) -> String? {
        
        if let start = startDate {
            if self.gregorian.compare(start, to: date, toGranularity: .day).rawValue == 0 {
                return "开始"
            }
        }
        
        if let end = endDate {
            if self.gregorian.compare(end, to: date, toGranularity: .day).rawValue == 0 {
                return "结束"
            }
            
        }
        return nil
    }
    
    func calendar(_ calendar: FSCalendar, titleFor date: Date) -> String? {
        return self.gregorian.isDateInToday(date) ? "今" : nil
    }
    
    func minimumDate(for calendar: FSCalendar) -> Date {
        return  self.gregorian.date(byAdding: .day, value: 1, to: Date())!
    }
    
    func maximumDate(for calendar: FSCalendar) -> Date {
        return self.gregorian.date(byAdding: .day, value: 365, to: Date())!
    }
    
    func calendar(_ calendar: FSCalendar, cellFor date: Date, at monthPosition: FSCalendarMonthPosition) -> FSCalendarCell {
        guard let cell: YHRangeDatePickerCell = calendar.dequeueReusableCell(withIdentifier: YHRangeDatePickerCell.cellReuseIdentifier, for: date, at: monthPosition) as? YHRangeDatePickerCell else { return FSCalendarCell() }
        return cell
    }
    
    func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at monthPosition: FSCalendarMonthPosition) {
        configureCell(cell, for: date, at: monthPosition)
    }
    
    func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
        self.calendar.frame.size.height = bounds.height
    }
    
    // MARK: - FSCalendarDelegate
    func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
        return true
    }
    
    func calendar(_ calendar: FSCalendar, shouldDeselect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
        return false
    }
    
    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
        if monthPosition == .next || monthPosition == .previous {
            calendar.setCurrentPage(date, animated: true)
            
            tapOneDate(date)
        } else {
            tapOneDate(date)
        }
        configureVisibleCells()
        
        calendar.reloadData()
    }
    
    func calendar(_ calendar: FSCalendar, didDeselect date: Date, at monthPosition: FSCalendarMonthPosition) {
        let aDate = date
        print("did deselect date \(String(describing: dateFormatter.string(from: aDate)))")
        
        configureVisibleCells()
    }
}

// MARK: - Private methods
private extension YHRangeDatePickerView {
    func setupUI() {
        addSubview(calendar)
        calendar.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(-1)
            make.left.right.equalToSuperview()
            make.height.equalTo(510)
        }
    }
    
    func tapOneDate(_ date: Date) {
        if startDate == nil {
            startDate = date
            YHHUD.flash(message: "选择结束日期")
        } else if endDate == nil {
            // 比较结果
            let comparisonResult = gregorian.compare(startDate!, to: date, toGranularity: .day)

            switch comparisonResult {
            case .orderedAscending:
                print("第一个日期在第二个日期之前")
                endDate = date
            case .orderedDescending:
                print("第一个日期在第二个日期之后")
                endDate = startDate
                startDate = date
            case .orderedSame:
                print("两个日期是同一天")
            }
            
        } else {
            calendar.deselect(startDate!)
            calendar.deselect(endDate!)
            startDate = date
            endDate = nil
            YHHUD.flash(message: "选择结束日期")
        }
        
    }
    
    func configureVisibleCells() {
        for obj in (calendar.visibleCells()) {
            let date: Date? = self.calendar.date(for: obj)
            let position: FSCalendarMonthPosition = self.calendar.monthPosition(for: obj)
            self.configureCell(obj, for: date!, at: position)
        }
    }
    
    func configureCell(_ cell: FSCalendarCell, for date: Date, at position: FSCalendarMonthPosition) {
        let rangeCell = cell as? YHRangeDatePickerCell
        if position != .current {
            rangeCell?.middleLayer.isHidden = true
            rangeCell?.selectionLayer.isHidden = true
            return
        }
        if (startDate != nil) && (endDate != nil) {
            // The date is in the middle of the range
            let isMiddle: Bool = date.compare(startDate!) != date.compare(endDate!)
            rangeCell?.middleLayer.isHidden = !isMiddle
        } else {
            rangeCell?.middleLayer.isHidden = true
        }
        var isSelected = false
        let aDate = date
        isSelected = (startDate != nil) && (gregorian.isDate(aDate, inSameDayAs: startDate!)) || (endDate != nil) && (gregorian.isDate(aDate, inSameDayAs: endDate!))
        
        rangeCell?.selectionLayer.isHidden = !isSelected
    }
}
