//
//  YearMonthPickerView.swift
//  PhoneManager
//
//  Created by edy on 2025/5/12.
//

import UIKit

enum PickerDateType {
    case start
    case end
}

class YearMonthPickerView: UIView {
    
    var type: PickerDateType = .start {
        didSet {
            reloadData()
        }
    }
    
    // MARK: - Properties
    private var selectedYear: Int = 0
    private var selectedMonth: Int = 0
    private let calendar = Calendar.current
    private var currentYear: Int
    private var currentMonth: Int
    
    var startDate: Date? {
        didSet { reloadData() }
    }
    
    var endDate: Date? {
        didSet { reloadData() }
    }
    
    var onCancel: (() -> Void)?
    var onConfirm: ((_ type: PickerDateType, _ year: Int, _ month: Int) -> Void)?
    
    private let pickerView: UIPickerView = {
        let picker = UIPickerView()
        picker.backgroundColor = .white
        return picker
    }()
    
    private lazy var years: [Int] = {
        Array(1970...currentYear).reversed()
    }()
    
    private lazy var months: [String] = {
        DateFormatter().monthSymbols ?? []
    }()
    
    // MARK: - Initialization
    override init(frame: CGRect) {
        currentYear = calendar.component(.year, from: Date())
        currentMonth = calendar.component(.month, from: Date())
        super.init(frame: frame)
        setupView()
    }
    
    required init?(coder: NSCoder) {
        currentYear = calendar.component(.year, from: Date())
        currentMonth = calendar.component(.month, from: Date())
        super.init(coder: coder)
        setupView()
    }
    
    // MARK: - Public Methods
    func reloadData() {
        configureInitialSelection()
        pickerView.reloadAllComponents()
    }
    
    // MARK: - Setup
    private func setupView() {
        backgroundColor = .white
        layer.cornerRadius = 12
        layer.masksToBounds = true
        
        let buttonContainer = createButtonContainer()
        let stackView = UIStackView(arrangedSubviews: [buttonContainer, pickerView])
        stackView.axis = .vertical
        stackView.spacing = 0
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: topAnchor),
            stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
            stackView.bottomAnchor.constraint(equalTo: bottomAnchor)
        ])
        
        pickerView.delegate = self
        pickerView.dataSource = self
        configureInitialSelection()
    }
    
    private func createButtonContainer() -> UIView {
        let container = UIView()
        container.backgroundColor = UIColor(red: 0.9, green: 0.9, blue: 0.9, alpha: 1)
        container.translatesAutoresizingMaskIntoConstraints = false
        container.heightAnchor.constraint(equalToConstant: 42).isActive = true
        
        let cancelButton = UIButton(type: .system)
        cancelButton.setTitle("Cancel", for: .normal)
        cancelButton.contentHorizontalAlignment = .left
        cancelButton.translatesAutoresizingMaskIntoConstraints = false
        cancelButton.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
        cancelButton.setTitleColor(UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1), for: .normal)
        cancelButton.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        
        let confirmButton = UIButton(type: .system)
        confirmButton.setTitle("Completed", for: .normal)
        confirmButton.contentHorizontalAlignment = .right
        confirmButton.translatesAutoresizingMaskIntoConstraints = false
        confirmButton.addTarget(self, action: #selector(confirmAction), for: .touchUpInside)
        confirmButton.setTitleColor(UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1), for: .normal)
        confirmButton.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        
        [cancelButton, confirmButton].forEach {
            $0.translatesAutoresizingMaskIntoConstraints = false
            container.addSubview($0)
        }
        
        NSLayoutConstraint.activate([
            cancelButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
            cancelButton.centerYAnchor.constraint(equalTo: container.centerYAnchor),
            
            confirmButton.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -16),
            confirmButton.centerYAnchor.constraint(equalTo: container.centerYAnchor)
        ])
        
        return container
    }
    
    private func configureInitialSelection() {
        let targetDate: Date?
        switch type {
        case .start: targetDate = startDate
        case .end: targetDate = endDate
        }
        
        let date = targetDate ?? Date()
        var year = calendar.component(.year, from: date)
        var month = calendar.component(.month, from: date)
        
        // 应用约束条件
        (year, month) = applyConstraints(to: year, month: month)
        
        // 自动滚动到有效位置
        scrollToValidYear(year, month: month)
    }
    
    private func scrollToValidYear(_ year: Int, month: Int) {
        guard let yearIndex = years.firstIndex(of: year) else { return }
        selectedYear = year
        selectedMonth = month - 1
        
        pickerView.selectRow(yearIndex, inComponent: 1, animated: false)
        pickerView.selectRow(selectedMonth, inComponent: 0, animated: false)
    }
    
    // MARK: - Button Actions
    @objc private func cancelAction() {
        onCancel?()
    }
    
    @objc private func confirmAction() {
        // 最终校验
        let (validYear, validMonth) = applyConstraints(to: selectedYear, month: selectedMonth + 1)
        scrollToValidYear(validYear, month: validMonth)
        
        onConfirm?(type, validYear, validMonth)
    }
}

// MARK: - UIPickerView DataSource & Delegate
extension YearMonthPickerView: UIPickerViewDataSource, UIPickerViewDelegate {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 2
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        component == 0 ? 12 : years.count
    }
    
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let label = UILabel()
        label.textAlignment = .center
        
        let year = component == 1 ? years[row] : selectedYear
        let month = component == 0 ? (row + 1) : (selectedMonth + 1)
        
        if component == 0 {
            label.text = months[row]
        } else {
            label.text = "\(years[row])"
        }
        
        label.textColor = isDateValid(year: year, month: month) ? .black : .lightGray
        return label
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 1 {
            selectedYear = years[row]
            adjustMonthSelection()
        } else {
            selectedMonth = row
        }
        
        // 自动修正无效选择
        if !isDateValid(year: selectedYear, month: selectedMonth + 1) {
            let (validYear, validMonth) = applyConstraints(to: selectedYear, month: selectedMonth + 1)
            scrollToValidYear(validYear, month: validMonth)
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        bounds.width / 2
    }
}

// MARK: - Date Validation
extension YearMonthPickerView {
    private func isDateValid(year: Int, month: Int) -> Bool {
        // 检查当前时间限制
        if year > currentYear || (year == currentYear && month > currentMonth) {
            return false
        }
        
        // 检查开始/结束时间约束
        switch type {
        case .start:
            if let endDate = endDate {
                let endYear = calendar.component(.year, from: endDate)
                let endMonth = calendar.component(.month, from: endDate)
                return (year < endYear) || (year == endYear && month <= endMonth)
            }
        case .end:
            if let startDate = startDate {
                let startYear = calendar.component(.year, from: startDate)
                let startMonth = calendar.component(.month, from: startDate)
                return (year > startYear) || (year == startYear && month >= startMonth)
            }
        }
        
        return true
    }
    
    private func applyConstraints(to year: Int, month: Int) -> (year: Int, month: Int) {
        var validYear = year
        var validMonth = month
        
        // 当前时间约束
        validYear = min(validYear, currentYear)
        validMonth = min(validMonth, validYear == currentYear ? currentMonth : 12)
        
        // 开始/结束时间约束
        switch type {
        case .start:
            if let endDate = endDate {
                let endYear = calendar.component(.year, from: endDate)
                let endMonth = calendar.component(.month, from: endDate)
                validYear = min(validYear, endYear)
                validMonth = min(validMonth, validYear == endYear ? endMonth : 12)
            }
        case .end:
            if let startDate = startDate {
                let startYear = calendar.component(.year, from: startDate)
                let startMonth = calendar.component(.month, from: startDate)
                validYear = max(validYear, startYear)
                validMonth = max(validMonth, validYear == startYear ? startMonth : 1)
            }
        }
        
        return (validYear, validMonth)
    }
    
    private func adjustMonthSelection() {
        let maxMonth: Int
        if selectedYear == currentYear {
            maxMonth = currentMonth
        } else if let constraintMonth = getConstraintMonth() {
            maxMonth = (type == .start) ? constraintMonth : 12
        } else {
            maxMonth = 12
        }
        
        if (selectedMonth + 1) > maxMonth {
            selectedMonth = maxMonth - 1
            pickerView.selectRow(selectedMonth, inComponent: 0, animated: true)
        }
    }
    
    private func getConstraintMonth() -> Int? {
        switch type {
        case .start:
            return endDate.flatMap { calendar.component(.month, from: $0) }
        case .end:
            return startDate.flatMap { calendar.component(.month, from: $0) }
        }
    }
}
