package proxy

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"net/http"

	"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/auth"
)

// Client is responsible for making requests to the Healthcare API
type Client struct {
	googleAuth *auth.GoogleClient
	projectID  string
	location   string
	dataset    string
	dicomStore string
}

// NewClient creates a new Healthcare API client
// Hanya menerima cfg.Google struct instead of all cfg.Config
func NewClient(googleAuth *auth.GoogleClient, googleConfig struct {
	ProjectID       string `mapstructure:"project_id"`
	Location        string `mapstructure:"location"`
	Dataset         string `mapstructure:"dataset"`
	DicomStore      string `mapstructure:"dicom_store"`
	CredentialsPath string `mapstructure:"credentials_path"`
}) *Client {
	return &Client{
		googleAuth: googleAuth,
		projectID:  googleConfig.ProjectID,
		location:   googleConfig.Location,
		dataset:    googleConfig.Dataset,
		dicomStore: googleConfig.DicomStore,
	}
}

// Response represents the HTTP response from the Healthcare API
type Response struct {
	StatusCode int
	Headers    map[string]string
	Body       []byte
}

// ForwardRequest forwards a request to Google Healthcare API
func (c *Client) ForwardRequest(ctx context.Context, method, path string, headers map[string]string, body []byte) (*Response, error) {
	token, err := c.googleAuth.GetAccessToken()
	if err != nil {
		return nil, fmt.Errorf("failed to get access token: %w", err)
	}

	// Build URL - Simplified to exactly match OHIF's expected structure
	baseURL := fmt.Sprintf("https://healthcare.googleapis.com/v1/projects/%s/locations/%s/datasets/%s/dicomStores/%s/dicomWeb",
		c.projectID, c.location, c.dataset, c.dicomStore)

	// Ensure path starts with /
	if len(path) > 0 && path[0] != '/' {
		path = "/" + path
	}

	fullURL := baseURL + path

	// Log the full URL for debugging
	fmt.Printf("Requesting URL: %s\n", fullURL)

	// Create request
	req, err := http.NewRequestWithContext(ctx, method, fullURL, bytes.NewReader(body))
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	// Set headers
	for k, v := range headers {
		// Skip setting certain headers that might cause issues
		if k == "Host" || k == "Content-Length" {
			continue
		}
		req.Header.Set(k, v)
	}

	// Set auth header
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))

	// Make request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to execute request: %w", err)
	}
	defer resp.Body.Close()

	// Read response body
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read response body: %w", err)
	}

	// Collect response headers
	respHeaders := make(map[string]string)
	for k, v := range resp.Header {
		if len(v) > 0 {
			respHeaders[k] = v[0]
		}
	}

	return &Response{
		StatusCode: resp.StatusCode,
		Headers:    respHeaders,
		Body:       respBody,
	}, nil
}
