import Foundation

struct CabinClass: OptionSet, Hashable, Sendable {
    let rawValue: Int

    static let economy     = CabinClass(rawValue: 1 << 0)
    static let premiumEcon = CabinClass(rawValue: 1 << 1)
    static let business    = CabinClass(rawValue: 1 << 2)
    static let first       = CabinClass(rawValue: 1 << 3)

    /// Parse from validity.php "classes" string like "0111".
    /// Position 0 = First, 1 = Business, 2 = PremEcon, 3 = Economy.
    static func from(classesString: String) -> CabinClass {
        var result = CabinClass()
        let chars = Array(classesString)
        guard chars.count >= 4 else { return result }
        if chars[0] == "1" { result.insert(.first) }
        if chars[1] == "1" { result.insert(.business) }
        if chars[2] == "1" { result.insert(.premiumEcon) }
        if chars[3] == "1" { result.insert(.economy) }
        return result
    }

    /// Parse from rt<id>.json `clss` bitmask integer.
    /// Bit mapping: 1 = economy, 2 = premEcon, 4 = business, 8 = first.
    static func from(bitmask: Int) -> CabinClass {
        CabinClass(rawValue: bitmask)
    }

    var labels: [String] {
        var result: [String] = []
        if contains(.first) { result.append("F") }
        if contains(.business) { result.append("J") }
        if contains(.premiumEcon) { result.append("W") }
        if contains(.economy) { result.append("Y") }
        return result
    }
}

struct Route: Identifiable, Hashable, Sendable {
    var id: String { destinationAirport.id }
    let destinationAirport: Airport
    let durationMinutes: Int
    let distanceMiles: Int
    let monthsBitmask: Int
    let cabinClasses: CabinClass
    let latitude: Double
    let longitude: Double

    func availableIn(month: Int) -> Bool {
        guard month >= 1, month <= 12 else { return false }
        return monthsBitmask & (1 << (month - 1)) != 0
    }
}

struct RouteAirline: Identifiable, Sendable {
    var id: String { airline.id }
    let airline: Airline
    let distanceMiles: Int
    let durationMinutes: Int
    let monthsBitmask: Int
}
