//
//  Filter.swift
//  LeCountdown
//
//  Created by Laurent Morvillier on 20/02/2023.
//

import Foundation

enum Filter: Identifiable, Hashable {
    
    case none
    case year(_ year: Int)
    case month(_ month: Month)
    
    var predicate: NSPredicate {
        switch self {
        case .none:
            return NSPredicate(value: true)
        case .year(let year):
            return NSPredicate(format: "start >= %@ AND end < %@", year.startOfYear, (year + 1).startOfYear)
        case .month(let month):
            return NSPredicate(format: "start >= %@ AND end < %@", month.start, month.end)
        }
    }
    
    var localizedString: String {
        switch self {
        case .none: return NSLocalizedString("All", comment: "")
        case .year(let year): return "\(year)"
        case .month(let month): return month.localizedString
        }
    }
    
    var id: String { localizedString }
    
    static func == (lhs: Filter, rhs: Filter) -> Bool {
        return lhs.id == rhs.id
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(self.id)
    }
}

fileprivate extension Int {
    
    var startOfYear: NSDate {
        let components: DateComponents = DateComponents(year: self)
        if let date = Calendar.current.date(from: components) {
            return date as NSDate
        }
        return NSDate()
    }
    
}

struct Month {
    
    var month: Int
    var year: Int
    
    var start: NSDate {
        let components: DateComponents = DateComponents(year: self.year, month: self.month)
        if let date = Calendar.current.date(from: components) {
            return date as NSDate
        }
        return NSDate()
    }
    
    var end: NSDate {
        let start = self.start as Date
        if let end = Calendar.current.date(byAdding: .month, value: 1, to: start) {
            return end as NSDate
        }
        return NSDate()
    }
    
    var localizedString: String {
        let components = DateComponents(year: self.year, month: self.month)
        if let date = Calendar.current.date(from: components) {
            return Date.monthYearFormatter.string(from: date)
        }
        return "invalid date"
    }
    
}
