package bitbucket

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log/slog"
	"net/http"
	"strconv"
	"strings"

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

func (b *BitbucketAdapter) GetDiff(ctx context.Context, projectKey, repositorySlug string, pullRequestID int) (diff io.ReadCloser, err error) {
	slog.Debug("Bitbucket GetDiff start", "project", projectKey, "repo", repositorySlug, "pr", pullRequestID)
	r, err := b.CreateRequest(
		ctx,
		http.MethodGet,
		nil,
		"/projects/", projectKey, "repos", repositorySlug, "pull-requests", fmt.Sprintf("%d.diff", pullRequestID),
	)
	if err != nil {
		return
	}

	response, err := http.DefaultClient.Do(r)
	if err != nil {
		return
	}

	if response.StatusCode != http.StatusOK {
		sb := &strings.Builder{}
		io.Copy(sb, response.Body)
		err = fmt.Errorf("error while fetching bitbucket diff status %d, body %s", response.StatusCode, sb.String())
	}

	diff = response.Body
	return
}

func (b *BitbucketAdapter) GetPR(ctx context.Context, projectKey, repositorySlug string, pullRequestID int) (pr PullRequest, err error) {
	slog.Debug("Bitbucket GetPR start", "project", projectKey, "repo", repositorySlug, "pr", pullRequestID)
	r, err := b.CreateRequest(
		ctx,
		http.MethodGet,
		nil,
		"/projects/", projectKey, "repos", repositorySlug, "pull-requests", strconv.Itoa(pullRequestID),
	)

	response, err := http.DefaultClient.Do(r)
	if err != nil {
		return
	}
	defer response.Body.Close() // Add this

	err = json.NewDecoder(response.Body).Decode(&pr)
	if err != nil {
		slog.Error("Bitbucket GetPR decode error", "err", err)
		return
	}
	slog.Info("Bitbucket GetPR success", "id", pullRequestID)

	return
}

func (b *BitbucketAdapter) AddComment(ctx context.Context, owner, repo string, prID int, comment pierre.Comment) (err error) {
	slog.Debug("Bitbucket AddComment start", "owner", owner, "repo", repo, "pr", prID, "file", comment.File, "line", comment.Line)
	// pr, err := b.GetPR(ctx, owner, repo, prID)
	// if err != nil {
	// 	return
	// }

	commentDTO := Comment{
		Content: comment.Message,
		Anchor: Anchor{
			Path:     comment.File,
			Line:     comment.Line,
			LineType: "ADDED",
			FileType: "TO",
			DiffType: "EFFECTIVE",
			// FromHash: pr.ToRef.LatestCommit,
			// ToHash:   pr.FromRef.LatestCommit,
		},
	}

	r, err := b.CreateRequest(ctx,
		http.MethodPost,
		commentDTO,
		"/projects/", owner, "/repos/", repo, "/pull-requests/", strconv.Itoa(prID), "/comments",
	)
	if err != nil {
		return
	}

	response, err := http.DefaultClient.Do(r)
	if err != nil {
		return err
	}
	defer response.Body.Close() // Add this

	if response.StatusCode >= 300 || response.StatusCode < 200 {
		sb := &strings.Builder{}
		io.Copy(sb, response.Body)
		err = fmt.Errorf("error while creating comment staus %d, body %s", response.StatusCode, sb.String())
		slog.Error("Bitbucket AddComment failed", "status", response.StatusCode, "err", err)
	} else {
		slog.Info("Bitbucket AddComment succeeded", "pr", prID)
	}

	return err
}
