import Foundation

// Dummy. Replace with some sort of database access or similar
// to fetch the current price.
func Price(for style: Style) -> Double {
    switch style {
    case .croissant:
        return 1.23
    case .naan:
        return 0.87
    case .pumpernickel:
        return 0.64
    case .rye:
        return 0.62
    }
}

public struct Receipt: Codable, CustomStringConvertible {
    public private(set) var items: [Item]
    public let orderDate: Date

    func lineItem(for item: Item) -> Double {
        return Double(item.amount) * Price(for: item.style)
    }
    
    var total: Double {
        return items.reduce(0.0) { return $0 + lineItem(for: $1) }
    }

    public var description: String {
        func line(for item: Item) -> String {
            return "\(item.amount) \(item.style.rawValue.uppercased()) @ \(Price(for: item.style)) = \(lineItem(for: item))"
        }
        var result = "Receipt for Order on \(orderDate)\n"
        result += "---------\n"

        _ = items.map { result += line(for: $0) + "\n"} 

        result += "---------\n"
        result += "Total: \(total)\n\n"
        return result
    }

    public init(with items: [Item] = []) {
        self.items = items
        orderDate = Date()
    }

    public mutating func add(item: Item) {
        items.append(item)
    }

    static func receipt(for items: [Item]) -> Receipt {
        return Receipt(with: items)
    }
}