package pierre

import (
	"context"
	"fmt"
	"log"

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

func (s *Service) MakeReview(ctx context.Context, organisation string, repo string, prID int) error {
	// Fetch Diff using positional args from shared RepoArgs
	diff, err := s.git.GetDiff(ctx, organisation, repo, prID)
	defer diff.Close()
	if err != nil {
		return fmt.Errorf("error fetching diff: %w", err)
	}

	// Run Logic
	comments, err := s.judgePR(ctx, diff)
	if err != nil {
		return fmt.Errorf("error judging PR: %w", err)
	}

	// ---------- Sanity‑check step (always enabled) ----------
	headSHA, err := s.git.GetPRHeadSHA(ctx, organisation, repo, prID)
	if err != nil {
		log.Printf("warning: could not fetch PR head SHA (%v); skipping sanity check", err)
	} else {
		filtered := []Comment{}
		for _, c := range comments {
			// Retrieve full file content at the PR head
			fileContent, fErr := s.git.GetFileContent(ctx, organisation, repo, c.File, headSHA)
			if fErr != nil {
				log.Printf("failed to fetch file %s: %v – keeping original comment", c.File, fErr)
				filtered = append(filtered, c)
				continue
			}

			// Build a simple sanity‑check prompt
			systemPrompt := `You are a senior software architect. Given the full source code of a file and a review comment that refers to it, decide whether the comment is useful. Return JSON with fields "useful" (bool) and "reason" (short explanation, ≤2 sentences).`
			userPrompt := fmt.Sprintf("File content:\n%s\n\nComment:\n%s", fileContent, c.Message)

			type sanityResult struct {
				Useful bool   `json:"useful"`
				Reason string `json:"reason"`
			}
			var res sanityResult
			if err := s.chat.GenerateStructured(ctx, []chatter.Message{{Role: chatter.RoleSystem, Content: systemPrompt}, {Role: chatter.RoleUser, Content: userPrompt}}, &res); err != nil {
				log.Printf("sanity check error for %s:%d: %v – keeping comment", c.File, c.Line, err)
				filtered = append(filtered, c)
				continue
			}
			if res.Useful {
				// Optionally annotate the comment with the reason for debugging
				c.Message = fmt.Sprintf("%s (Reason: %s)", c.Message, res.Reason)
				filtered = append(filtered, c)
			} else {
				log.Printf("comment on %s:%d discarded: %s", c.File, c.Line, res.Reason)
			}
		}
		comments = filtered
	}

	fmt.Printf("Analysis complete. Found %d issues.\n---\n", len(comments))

	model := s.chat.GetProviderName()

	for _, c := range comments {
		c.Message = fmt.Sprintf("%s (Generated by: %s)", c.Message, model)

		// Normal mode: print to stdout and post the comment to the VCS.
		fmt.Printf("File: %s\nLine: %d\nMessage: %s\n%s\n",
			c.File, c.Line, c.Message, "---")

		if s.disableComments {
			if err := s.git.AddComment(ctx, organisation, repo, prID, c); err != nil {
				log.Printf("Failed to add comment: %v", err)
			}
		}
	}

	return nil
}
