// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: GPL-3.0-or-later

package xyz.apiote.bimba.czwek.api

import android.content.Context
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import xyz.apiote.bimba.czwek.R
import xyz.apiote.bimba.czwek.api.transitous.api.RoutingApi
import xyz.apiote.bimba.czwek.repo.Colour
import xyz.apiote.bimba.czwek.repo.CongestionLevel
import xyz.apiote.bimba.czwek.repo.Event
import xyz.apiote.bimba.czwek.repo.Journey
import xyz.apiote.bimba.czwek.repo.Leg
import xyz.apiote.bimba.czwek.repo.LineStub
import xyz.apiote.bimba.czwek.repo.LineType
import xyz.apiote.bimba.czwek.repo.OccupancyStatus
import xyz.apiote.bimba.czwek.repo.Place
import xyz.apiote.bimba.czwek.repo.Position
import xyz.apiote.bimba.czwek.repo.TrafficResponseException
import xyz.apiote.bimba.czwek.repo.Vehicle
import xyz.apiote.bimba.czwek.units.Metre
import xyz.apiote.bimba.czwek.units.Mps
import xyz.apiote.bimba.czwek.units.Second
import java.time.ZoneId

suspend fun getJourney(from: Place, to: Place, context: Context): List<Journey> {
	if (!isNetworkAvailable(context)) {
		throw TrafficResponseException(0, "", Error(0, R.string.error_offline, R.drawable.error_net))
	}

	return withContext(Dispatchers.IO) {
		Log.d("Journeys", "from: ${from.planString()}")
		Log.d("Journeys", "to: ${to.planString()}")
		val response = RoutingApi().plan(from.planString(), to.planString(), maxTransfers = null)
		Log.d("Journeys", "${response.itineraries}")
		response.itineraries.map {
			val legs: List<Leg> = it.legs.map {
				Leg(
					Event(
						it.tripId ?: "",
						null,
						Time.fromOffsetTime(it.startTime, ZoneId.systemDefault()),
						0u,
						it.realTime,
						Vehicle(
							it.tripId ?: "",
							Position(0.0, 0.0),
							0u,
							Mps(0),
							LineStub(
								it.routeShortName ?: "", // TODO is it nullable, yes e.g. for transit
								LineType.fromTransitous2(it.mode),
								Colour.fromHex(it.routeColor)
							),
							it.headsign ?: "",  // TODO is it nullable, yes e.g. for transit
							CongestionLevel.UNKNOWN,
							OccupancyStatus.UNKNOWN
						),
						boarding = 0xffu,
						alerts = emptyList(),
						exact = true,
						terminusArrival = false
					),
					Event(
						it.tripId ?: "",
						Time.fromOffsetTime(it.endTime, ZoneId.systemDefault()),
						null,
						0u,
						it.realTime,
						Vehicle(
							it.tripId ?: "",
							Position(0.0, 0.0),
							0u,
							Mps(0),
							LineStub(
								it.routeShortName ?: "", // TODO is it nullable, yes e.g. for transit
								LineType.fromTransitous2(it.mode),
								Colour.fromHex(it.routeColor)
							),
							it.headsign ?: "",  // TODO is it nullable, yes e.g. for transit
							CongestionLevel.UNKNOWN,
							OccupancyStatus.UNKNOWN
						),
						boarding = 0xffu,
						alerts = emptyList(),
						exact = true,
						terminusArrival = false
					),
					Place(it.from),
					Place(it.to),
					it.agencyName,
					it.distance?.toDouble()?.let { Metre(it) },
					Second(it.duration),
					(it.intermediateStops ?: emptyList()).map { Place(it) },
					/*it.legGeometry,
					it.rental,
					it.steps,*/
				)
			}
			Journey(
				it.startTime.atZoneSameInstant(ZoneId.systemDefault()), it.endTime.atZoneSameInstant(
					ZoneId.systemDefault()
				), legs
			)
		}
	}

}