package collector

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/nexuscrm/sentry/internal/types"
)

// CRMScraper fetches the /internal/sentry-metrics endpoint on the CRM backend
// and decodes the response into types.AppHealth.
type CRMScraper struct {
	url    string
	token  string
	client *http.Client
}

// NewCRMScraper constructs a scraper with a fixed URL, bearer token, and
// per-request timeout.
func NewCRMScraper(url, token string, timeout time.Duration) *CRMScraper {
	return &CRMScraper{
		url:    url,
		token:  token,
		client: &http.Client{Timeout: timeout},
	}
}

// Scrape issues the GET, validates the status, decodes JSON, and returns
// the result. Any non-200 status or transport error is surfaced to the caller.
func (s *CRMScraper) Scrape(ctx context.Context) (*types.AppHealth, error) {
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, s.url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Authorization", "Bearer "+s.token)
	req.Header.Set("Accept", "application/json")

	resp, err := s.client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("crm scraper: request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("crm scraper: status %d", resp.StatusCode)
	}

	var out types.AppHealth
	if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
		return nil, fmt.Errorf("crm scraper: decode: %w", err)
	}
	return &out, nil
}
