package com.fabledsword.minstrel.api

import com.fabledsword.minstrel.auth.AuthStore
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Rewrites Minstrel-server requests' scheme/host/port to match the
 * current [AuthStore.baseUrl]. Retrofit's `.baseUrl(...)` is read
 * once at Retrofit creation, but AuthStore.baseUrl loads from Room
 * asynchronously — so at injection time the Retrofit instance is
 * frozen pointing at the [AuthStore.DEFAULT_BASE_URL] placeholder.
 *
 * This interceptor closes the gap: Retrofit can stay built with the
 * placeholder forever, and every actual Minstrel-bound request gets
 * retargeted at the live AuthStore value. Lets the user change
 * server URL in Settings without an app relaunch (Phase 11 wiring).
 *
 * Only requests whose host is the [PLACEHOLDER_HOST] sentinel are
 * rewritten. Absolute external URLs — Lidarr-surfaced artwork from
 * artwork.musicbrainz.org / coverartarchive.org, for example — must
 * reach their authored host unchanged; rewriting them to the
 * Minstrel host produced 404s the user saw as missing Discover
 * suggestion covers.
 *
 * No-op when the stored base URL is unparseable (falls through to
 * whatever Retrofit had) — that case shows up as a transport-level
 * error in the caller's normal error path.
 */
@Singleton
class BaseUrlInterceptor @Inject constructor(
    private val authStore: AuthStore,
) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val original = chain.request()
        // Early-bail keeps the no-op path for external URLs cheap
        // (no AuthStore read, no URL parse).
        if (original.url.host != PLACEHOLDER_HOST) return chain.proceed(original)
        // Unparseable baseUrl folds into the same proceed path — keeps
        // detekt's ReturnCount happy by avoiding a second early return.
        val rewritten: HttpUrl = authStore.baseUrl.value.toHttpUrlOrNull()?.let { baseUrl ->
            original.url.newBuilder()
                .scheme(baseUrl.scheme)
                .host(baseUrl.host)
                .port(baseUrl.port)
                .build()
        } ?: original.url
        return chain.proceed(original.newBuilder().url(rewritten).build())
    }

    companion object {
        /** Sentinel host used by Retrofit + every code path that builds
         *  a Minstrel-server URL via the `http://placeholder.invalid/...`
         *  form (see [com.fabledsword.minstrel.shared.resolveServerUrl],
         *  CoverUrls.kt, AlbumRef/TrackRef cover getters). */
        const val PLACEHOLDER_HOST = "placeholder.invalid"
    }
}
