//
//  WdtHourlySummary.swift
//  1Weather
//
//  Created by Demid Merzlyakov on 26.02.2021.
//

import Foundation

struct WdtHourlySummary: Codable {
    public var dateTimeLocal: String
    public var weekDay: String
    public var dayNight: String
    
    public var tempF: String?
    public var apparentTempF: String?
    public var windSpeedKph: String?
    public var windDirection: String?
    public var humidity: String?
    public var precipitationProbability: String?
    public var weatherCode: String?
    
    private enum CodingKeys: String, CodingKey {
        case dateTimeLocal = "time_local"
        case weekDay = "day_of_week_local"
        case dayNight = "day_night"
        
        case tempF = "temp_F"
        case apparentTempF = "apparent_temp_F"
        case windSpeedKph = "wnd_spd_kph"
        case windDirection = "wnd_dir"
        case humidity = "rh_pct"
        case precipitationProbability = "pop"
        case weatherCode = "wx_code"
    }
    
    private static let log = Logger(componentName: "WdtHourlySummary")
    
    public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> HourlyWeather? {
        let log = WdtHourlySummary.log
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        dateFormatter.timeZone = timeZone
        
        guard let date = dateFormatter.date(from: dateTimeLocal) else {
            log.error("Failed to parse date from: \(dateTimeLocal)")
            return nil
        }
        
        var weekDay = WeekDay(rawValue: self.weekDay)
        if weekDay == nil {
            var calendar = Calendar(identifier: .gregorian)
            calendar.timeZone = timeZone
            weekDay = WeekDay(grigorianWeekDayNumber: calendar.component(.weekday, from: date))
        }
        guard let weekDayUnwrapped = weekDay else {
            log.error("Couldn't parse week day: \(self.weekDay)")
            return nil
        }
        
        let isDay = dayNight.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == "day"
        
        var result = HourlyWeather(lastTimeUpdated: updatedAt, date: date, timeZone: timeZone, weekDay: weekDayUnwrapped, isDay: isDay)
        if let weatherCode = self.weatherCode {
            result.type = WdtWeatherCode(rawValue: weatherCode)?.toAppModel() ?? .unknown
        }
        result.temp = Temperature(valueString: tempF, unit: .fahrenheit)
        result.apparentTemp = Temperature(valueString: apparentTempF, unit: .fahrenheit)
        
        result.windSpeed = WindSpeed(valueString: self.windSpeedKph, unit: .kilometersPerHour)
        result.windDirection = WindDirection(rawValue: windDirection ?? "")
        
        if let precipitationProbability = Percent(self.precipitationProbability ?? ""), precipitationProbability >= 0, precipitationProbability <= 100 {
            result.precipitationProbability = precipitationProbability
        }
        
        if let humidity = Percent(self.humidity ?? ""), humidity >= 0, humidity <= 100 {
            result.humidity = humidity
        }
        
        return result
    }
}
