package bitbucket

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

	"git.schreifuchs.ch/schreifuchs/pierre-bot/internal/gitadapters/baseadapter"
)

type BitbucketAdapter struct {
	baseadapter.Rest
}

func NewBitbucket(baseURL string, bearerToken string) *BitbucketAdapter {
	baseURL, _ = strings.CutSuffix(baseURL, "/")
	baseURL += "/rest/api/1.0"

	return &BitbucketAdapter{
		Rest: baseadapter.NewRest(baseURL, bearerToken),
	}
}

// GetFileContent returns the raw file content at the given ref (commit SHA) or HEAD if ref is empty.
func (b *BitbucketAdapter) GetFileContent(ctx context.Context, projectKey, repositorySlug, path, ref string) (string, error) {
	// Use the Rest helper to build the base URL, then add the "at" query param if needed.
	r, err := b.CreateRequest(ctx, http.MethodGet, nil,
		"/projects/", projectKey, "repos", repositorySlug, "raw", path)
	if err != nil {
		return "", err
	}
	if ref != "" {
		q := r.URL.Query()
		q.Set("at", ref)
		r.URL.RawQuery = q.Encode()
	}

	resp, err := http.DefaultClient.Do(r)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		sb := &strings.Builder{}
		io.Copy(sb, resp.Body)
		return "", fmt.Errorf("error fetching file %s status %d, body %s", path, resp.StatusCode, sb.String())
	}
	content, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(content), nil
}

// GetPRHeadSHA fetches the PR and returns the SHA of the source (to) branch.
func (b *BitbucketAdapter) GetPRHeadSHA(ctx context.Context, projectKey, repositorySlug string, pullRequestID int) (string, error) {
	pr, err := b.GetPR(ctx, projectKey, repositorySlug, pullRequestID)
	if err != nil {
		return "", err
	}
	return pr.ToRef.LatestCommit, nil
}
