//
//  yQzCalendarView.swift
//  SpeakEasyLearnEnglish
//
//  Created by edy on 2025/8/1.
//

import UIKit


public protocol yQzCalendarViewDelegate : NSObjectProtocol {
    func calendarView(change date:Date)
    func calendarView(didSelect date:Date )
}


class yQzCalendarView: UIView , UIScrollViewDelegate{

    private let WeekStr = ["Sun" ,"Mon" ,"Tue" ,"Wed" ,"Thu" ,"Fri" ,"Sat"]
    
    private var itemData:[CalendarView] = []
    
    weak open var delegate: (any yQzCalendarViewDelegate)?
    
    var currentData:Date = Date()
    var signList:[String:[SignListModel]]?
    
    func updateData() -> Void {
        var start = currentData.operation(month: -1)
        itemData.forEach { calendar in
            calendar.currentData = start
            start = start.operation(month: 1)
            calendar.signList = signList
        }
        self.layoutIfNeeded()
        self.scrollView.contentOffset = CGPoint(x: scrollView.width, y: 0)
    }
    
    func next() -> Void {
        UIView.animate(withDuration: 0.2) {
            self.scrollView.contentOffset = CGPoint(x: self.scrollView.width * 2, y: 0)
        } completion: { su in
            if su {
                DispatchQueue.main.async {
                    self.currentData = self.currentData.operation(month: 1)
                    self.updateData()
                }
            }
        }
         
    }
    
    func upper() -> Void {
        UIView.animate(withDuration: 0.2) {
            self.scrollView.contentOffset = CGPoint(x: self.scrollView.width * 0, y: 0)
        } completion: { su in
            if su {
                self.currentData = self.currentData.operation(month: -1)
                self.updateData()
            }
        }
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let select = scrollView.contentOffset.x / scrollView.width
        if select < 1 {
            currentData = currentData.operation(month: -1)
            delegate?.calendarView(change: currentData)
            updateData()
        }else if select > 1 {
            currentData = currentData.operation(month: 1)
            delegate?.calendarView(change: currentData)
            updateData()
        }
        Print("select" + "\(select)")
    }
    
    private func setup() -> Void {
        for _ in 0..<3 {
            let callblack = CalendarView.loadNib()
            itemData.append(callblack)
            callblack.WeekStr = WeekStr
            callblack.callblack = {[weak self] date in
                guard let date = date as? String else { return }
                self?.delegate?.calendarView(didSelect: date.date("yyyy-MM-dd") ?? Date())
            }
        }
        scrollView.snp.makeConstraints { make in
            make.bottom.top.equalToSuperview()
            make.left.right.equalToSuperview()
            make.height.equalTo(StackView.snp.height)
        }
        StackView.snp.makeConstraints { make in
            make.left.right.bottom.top.equalToSuperview()
            make.width.equalTo(scrollView.snp.width).multipliedBy(3.0)
        }
        itemData.forEach({StackView.addArrangedSubview($0)})
        self.layoutIfNeeded()
        DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: {
            self.updateData()
        })
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        setup()
    }
 
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    private  lazy var StackView: UIStackView = {
        let stack = UIStackView()
        scrollView.addSubview(stack)
        stack.spacing = 0.01
        stack.distribution = .fillEqually
        stack.alignment = .fill
        return stack
    }()
    
    private lazy var scrollView: UIScrollView = {
        let scroll = UIScrollView()
        scroll.contentInset = UIEdgeInsets()
        scroll.contentInsetAdjustmentBehavior = .never
        self.addSubview(scroll)
        scroll.delegate = self
        scroll.isPagingEnabled = true
        scroll.showsVerticalScrollIndicator = false
        scroll.showsHorizontalScrollIndicator = false
        return scroll
    }()
    
    
}



extension Date {
    /// 获取一月有几天
    func daysOfMonth() -> Int {
        let calendar = Calendar(identifier: .gregorian)
        let components = calendar.dateComponents([.year, .month], from: self)
        let daysInMonth = calendar.range(of: .day, in: .month, for: calendar.date(from: components)!)?.count ?? 0
        return daysInMonth
    }
    
    
    /// 获取今天是星期几（1-7，1代表周日，2代表周一）
    func dayOfWeekInt() -> Int {
        let calendar = Calendar(identifier: .gregorian)
        let weekday = calendar.component(.weekday, from: self)
        return weekday
    }
    
    /// 日期操作
    func operation(year:Int = 0,
                   month:Int = 0,
                   day:Int = 0,
                   houre:Int = 0,
                   minte:Int = 0,
                   second:Int = 0,
                   week:Int = 0) -> Date {
        let calendar = Calendar(identifier: .gregorian)
        let currentDate = self
        var dateComponent:DateComponents = calendar.dateComponents([.year,.month,.day,.hour,.minute,.second,.weekday], from: currentDate)
        dateComponent.year! += year
        dateComponent.month! += month
        dateComponent.day! += day
        dateComponent.hour! += houre
        dateComponent.minute! += minte
        dateComponent.second! += second
        dateComponent.weekday! += week
        guard let toDate = calendar.date(from: dateComponent) else { return self }
        return toDate
    }
    
    func setTm(year:Int? = nil,
               month:Int? = nil,
               day:Int? = nil,
               houre:Int? = nil,
               minte:Int? = nil,
               second:Int? = nil,
               week:Int? = nil) -> Date {
        let calendar = Calendar(identifier: .gregorian)
        let currentDate = self
        var dateComponent:DateComponents = calendar.dateComponents([.year,.month,.day,.hour,.minute,.second,.weekday], from: currentDate)
        if year != nil {
            dateComponent.year! = year ?? 0
        }
        if month != nil {
            dateComponent.month! = month ?? 0
        }
        if day != nil {
            dateComponent.day! = day ?? 0
        }
        if houre != nil {
            dateComponent.hour! = houre ?? 0
        }
        if week != nil {
            dateComponent.weekday! = week ?? 0
        }
        guard let toDate = calendar.date(from: dateComponent) else { return self }
        return toDate
    }
}
