package platform

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strings"
	"time"
)

// FetchOAuthConfig pulls the provider coordinates from the cdrop backend's
// /api/auth/config. The desktop reuses the same OAuth client as the web app
// (the client_id published there) and runs its own loopback PKCE flow against
// the provider, instead of the browser's in-page redirect + /api/auth/exchange
// proxy. apiBase is the backend origin, e.g. https://drop.commilitia.net.
func FetchOAuthConfig(ctx context.Context, apiBase string) (OAuthConfig, error) {
	endpoint := strings.TrimRight(apiBase, "/") + "/api/auth/config"
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
	if err != nil {
		return OAuthConfig{}, fmt.Errorf("oauth: build config request: %w", err)
	}
	req.Header.Set("Accept", "application/json")

	client := &http.Client{Timeout: 15 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return OAuthConfig{}, fmt.Errorf("oauth: fetch config: %w", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return OAuthConfig{}, fmt.Errorf("oauth: config endpoint status %d", resp.StatusCode)
	}

	var c struct {
		AuthorizeURL string `json:"authorize_url"`
		TokenURL     string `json:"token_url"`
		ClientID     string `json:"client_id"`
		Scopes       string `json:"scopes"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&c); err != nil {
		return OAuthConfig{}, fmt.Errorf("oauth: decode config: %w", err)
	}

	cfg := OAuthConfig{
		AuthorizeURL: c.AuthorizeURL,
		TokenURL:     c.TokenURL,
		ClientID:     c.ClientID,
		Scopes:       c.Scopes,
	}
	if cfg.AuthorizeURL == "" || cfg.TokenURL == "" || cfg.ClientID == "" {
		return OAuthConfig{}, errors.New("oauth: backend config missing authorize_url / token_url / client_id")
	}
	return cfg, nil
}
