import Foundation

public enum WayfinderProviderDescriptor {
    public static let descriptor: ProviderDescriptor = Self.makeDescriptor()
    private static let credentials = ProviderCredentialAdapter(
        requiresAPIKeyForAPISource: false,
        environmentProjections: [
            .enterpriseHost(WayfinderSettingsReader.baseURLEnvironmentKey),
        ])

    static func makeDescriptor() -> ProviderDescriptor {
        ProviderDescriptor(
            id: .wayfinder,
            credentials: self.credentials,
            config: ProviderConfigCapabilities(supportsEnterpriseHost: true),
            metadata: ProviderMetadata(
                id: .wayfinder,
                displayName: "Wayfinder",
                sessionLabel: "Savings",
                weeklyLabel: "Requests",
                opusLabel: nil,
                supportsOpus: false,
                supportsCredits: false,
                creditsHint: "",
                toggleTitle: "Show Wayfinder usage",
                cliName: "wayfinder",
                defaultEnabled: false,
                widgetSelectable: false,
                debugLogUnavailableMessage: "Wayfinder debug log not yet implemented",
                dashboardURL: WayfinderSettingsReader.dashboardURL(environment: [:]).absoluteString,
                statusPageURL: nil),
            branding: ProviderBranding(
                iconStyle: .init(provider: .wayfinder),
                iconResourceName: "ProviderIcon-wayfinder",
                color: ProviderColor(red: 16 / 255, green: 163 / 255, blue: 127 / 255),
                confettiPalette: [
                    ProviderColor(hex: 0x10A37F),
                    ProviderColor(hex: 0xBD6A13),
                    ProviderColor(hex: 0x0D0D0D),
                ]),
            tokenCost: ProviderTokenCostConfig(
                supportsTokenCost: false,
                noDataMessage: { "Wayfinder savings are reported by its local gateway." }),
            fetchPlan: ProviderFetchPlan(
                sourceModes: [.auto, .api],
                pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [WayfinderGatewayFetchStrategy()] })),
            cli: ProviderCLIConfig(
                name: "wayfinder",
                aliases: ["wayfinder-router"],
                versionDetector: nil))
    }
}

struct WayfinderGatewayFetchStrategy: ProviderFetchStrategy {
    let id = "wayfinder.api"
    let kind: ProviderFetchKind = .apiToken

    func isAvailable(_: ProviderFetchContext) async -> Bool {
        // The gateway's read-only endpoints are unauthenticated; the provider is
        // opt-in (defaultEnabled: false), so no credential gates availability.
        true
    }

    func fetch(_ context: ProviderFetchContext) async throws -> ProviderFetchResult {
        try WayfinderSettingsReader.validateEndpointOverride(environment: context.env)
        let usage = try await WayfinderUsageFetcher.fetchUsage(
            baseURL: WayfinderSettingsReader.baseURL(environment: context.env))
        return self.makeResult(usage: usage.toUsageSnapshot(), sourceLabel: "api")
    }

    func shouldFallback(on _: Error, context _: ProviderFetchContext) -> Bool {
        false
    }
}
