//
//  Date.swift
//  Kalker

import Foundation

struct DateComponentUnitFormatter {
    
    private struct DateComponentUnitFormat {
        let unit: Calendar.Component
        
        let singularUnit: String
        let pluralUnit: String
        
        let futureSingular: String
        let pastSingular: String
    }
    
    private let formats: [DateComponentUnitFormat] = [
        
        DateComponentUnitFormat(unit: .month,
                                singularUnit: "miesiąc",
                                pluralUnit: "miesiące",
                                futureSingular: "W przyszłym miesiącu",
                                pastSingular: "Miesiąc temu"),
        
        DateComponentUnitFormat(unit: .weekOfYear,
                                singularUnit: "tydzień",
                                pluralUnit: "tygodnie",
                                futureSingular: "W przyszłym tygodniu",
                                pastSingular: "Tydzień temu"),
        
        DateComponentUnitFormat(unit: .day,
                                singularUnit: "dzień",
                                pluralUnit: "dni",
                                futureSingular: "Jutro",
                                pastSingular: "Wczoraj"),
        
        DateComponentUnitFormat(unit: .hour,
                                singularUnit: "godzinę",
                                pluralUnit: "godziny",
                                futureSingular: "Za godzinę",
                                pastSingular: "Godzinę temu"),
        
        DateComponentUnitFormat(unit: .minute,
                                singularUnit: "minutę",
                                pluralUnit: "minut",
                                futureSingular: "Za minutę",
                                pastSingular: "Minutę temu"),
        
        DateComponentUnitFormat(unit: .second,
                                singularUnit: "sekundę",
                                pluralUnit: "sekund",
                                futureSingular: "Teraz",
                                pastSingular: "Teraz"),
        
        ]
    
    func string(forDateComponents dateComponents: DateComponents, useNumericDates: Bool) -> String {
        for format in self.formats {
            let unitValue: Int
            
            switch format.unit {
            case .month:
                unitValue = dateComponents.month ?? 0
            case .weekOfYear:
                unitValue = dateComponents.weekOfYear ?? 0
            case .day:
                unitValue = dateComponents.day ?? 0
            case .hour:
                unitValue = dateComponents.hour ?? 0
            case .minute:
                unitValue = dateComponents.minute ?? 0
            case .second:
                unitValue = dateComponents.second ?? 0
            default:
                assertionFailure("Date does not have requried components")
                return ""
            }
            
            switch unitValue {
            case 2 ..< Int.max:
                return "\(unitValue) \(format.pluralUnit) temu"
            case 1:
                return useNumericDates ? "\(unitValue) \(format.singularUnit) temu" : format.pastSingular
            case -1:
                return useNumericDates ? "\(-unitValue) \(format.singularUnit)" : format.futureSingular
            case Int.min ..< -1:
                return "\(-unitValue) \(format.pluralUnit)"
            default:
                break
            }
        }
        
        return "Teraz"
    }
}

extension Date {
    
    func timeAgo(useNumericDates: Bool = false, startDate: Date) -> String {
        let calendar = Calendar.current
        let unitFlags: Set<Calendar.Component> = [.minute, .hour, .day, .weekOfYear, .month, .second]
        let components = calendar.dateComponents(unitFlags, from: self, to: startDate)
        
        let formatter = DateComponentUnitFormatter()
        return formatter.string(forDateComponents: components, useNumericDates: useNumericDates)
    }
    
    func timeAgoSinceNow(useNumericDates: Bool = false) -> String {
        
        let calendar = Calendar.current
        let unitFlags: Set<Calendar.Component> = [.minute, .hour, .day, .weekOfYear, .month, .second]
        let now = Date()
        let components = calendar.dateComponents(unitFlags, from: self, to: now)
        
        let formatter = DateComponentUnitFormatter()
        return formatter.string(forDateComponents: components, useNumericDates: useNumericDates)
    }
}

func ageFromDate(date: String) -> Int {
    
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "dd.mm.yyyy"
    let d = dateFormatter.date(from: date)
    
    let dateOfBirth = d
    let today = Date()
    let gregorian = NSCalendar(identifier: NSCalendar.Identifier.gregorian)
    let age = gregorian?.components([.month, .day, .year], from: dateOfBirth!, to: today, options:[])
    
    return age!.year!
}


