diff --git a/FuelBoard/ContentView.swift b/FuelBoard/ContentView.swift index 600b13b..e19a6de 100644 --- a/FuelBoard/ContentView.swift +++ b/FuelBoard/ContentView.swift @@ -36,15 +36,32 @@ struct ContentView: View { } } - /// The price reference every row's delta + RAG compares against. - /// Cheapest mode → the cheapest station in the pool (best value). - /// Closest mode → the CLOSEST station: deltas answer "is it worth leaving - /// the station nearest to me?" (+X.Xp pricier / -X.Xp cheaper). + /// The price reference every row's delta + RAG compares against — the + /// "best" of the current pool. In BOTH modes that is the CHEAPEST station + /// within the chosen miles radius (the stations you'd actually consider). + /// Cheapest mode's pool already is the radius; Closest mode lists the + /// whole country nearest-first (so it never empties), but best value is + /// still judged against what's practically reachable, so deltas stay local. + /// Fallback: if the radius has no stations, use the pool minimum. private var baselinePrice: Double? { - if sortMode == .closest { - return sortedStations.first?.prices[selectedFuel] + let pool = poolStations + if sortMode == .closest, let location { + let radiusKM = Double(stationLimit) * 1.60934 // chosen miles → km + let within = pool.filter { + $0.distanceKM(to: location.lat, lng2: location.lng) <= radiusKM + } + if let localMin = within.compactMap({ $0.prices[selectedFuel] }).min() { + return localMin + } } - return poolStations.compactMap { $0.prices[selectedFuel] }.min() + return pool.compactMap { $0.prices[selectedFuel] }.min() + } + + /// The "best" station — the cheapest in the pool — gets the TOP badge. + /// First occurrence in display order wins on price ties. + private var topStationID: String? { + guard let baselinePrice else { return nil } + return displayedStations.first { $0.prices[selectedFuel] == baselinePrice }?.id } private var displayedStations: [FuelStation] { @@ -94,6 +111,7 @@ struct ContentView: View { sortMode: $sortMode, stationLimit: $stationLimit, baselinePrice: baselinePrice, + topStationID: topStationID, location: location, favouriteIDs: favouriteIDs, onToggleFavourite: toggleFavourite, diff --git a/FuelBoard/StationsView.swift b/FuelBoard/StationsView.swift index b7156f4..a2bf92e 100644 --- a/FuelBoard/StationsView.swift +++ b/FuelBoard/StationsView.swift @@ -10,6 +10,7 @@ struct StationsView: View { @Binding var sortMode: SortMode @Binding var stationLimit: Int let baselinePrice: Double? + let topStationID: String? let location: Coordinate? let favouriteIDs: Set var onToggleFavourite: (FuelStation) -> Void = { _ in } @@ -28,7 +29,7 @@ struct StationsView: View { Section { if let location { if sortMode == .closest { - Text("Closest \(selectedFuel.displayName) stations — tap a station for directions.") + Text("Closest \(selectedFuel.displayName) stations — nearest first, best value within \(stationLimit) miles.") .font(.footnote) .foregroundStyle(.secondary) } else { @@ -105,13 +106,13 @@ struct StationsView: View { Text("No \(selectedFuel.displayName) stations found.") .foregroundStyle(.secondary) } else { - ForEach(Array(stations.prefix(visibleCount).enumerated()), id: \.element.id) { index, station in + ForEach(Array(stations.prefix(visibleCount)), id: \.id) { station in StationRow( station: station, fuel: selectedFuel, location: location, baselinePrice: baselinePrice, - isTopResult: index == 0, + isTopResult: station.id == topStationID, isFavourite: favouriteIDs.contains(station.id), onToggleFavourite: { onToggleFavourite(station) } )