package direct_access

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

	fetchedfilepb "clio/internal/fetched_file/pocketbase"
	"clio/internal/link"
	"clio/internal/processor"
)

func makeFetchExecutor(store *fetchedfilepb.Store) processor.ExecutorFunc {
	return func(record processor.Record) *processor.ExecutorResult {
		l := record.(*link.Link)

		// Get config from phase_results (set by route_fetcher)
		results := l.GetPhaseResults()
		config, _ := results["fetcher_config"].(map[string]any)

		// Fetch the content and save via store
		fileID, err := fetch(context.Background(), l, config, store)
		if err != nil {
			return &processor.ExecutorResult{
				Error: fmt.Errorf("direct fetch failed: %w", err),
			}
		}

		// Return lightweight metadata
		return &processor.ExecutorResult{
			Data: map[string]interface{}{
				"file_ids":   []string{fileID},
				"file_count": 1,
				"primary_id": fileID,
			},
		}
	}
}

func fetch(ctx context.Context, l *link.Link, config map[string]any, store *fetchedfilepb.Store) (string, error) {
	// Create HTTP request
	req, err := http.NewRequestWithContext(ctx, "GET", l.InitialURL, nil)
	if err != nil {
		return "", fmt.Errorf("creating request: %w", err)
	}

	// TODO: Apply config (headers, timeout, etc.)
	_ = config

	// Fetch content
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", fmt.Errorf("fetching url: %w", err)
	}
	defer resp.Body.Close()

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

	// Read response body into memory
	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("reading response: %w", err)
	}

	// Save file via store abstraction
	fileID, err := store.Create(l.ID, bodyBytes, "page.html")
	if err != nil {
		return "", fmt.Errorf("saving file: %w", err)
	}

	return fileID, nil
}
