package common

import (
	"slices"

	"src.opensuse.org/autogits/common/gitea-generated/models"
)

type PRReviews struct {
	reviews   []*models.PullReview
	reviewers []string
}

func FetchGiteaReviews(rf GiteaReviewFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) {
	reviews, err := rf.GetPullRequestReviews(org, repo, no)
	if err != nil {
		return nil, err
	}

	return &PRReviews{
		reviews:   reviews,
		reviewers: reviewers,
	}, nil
}

func (r *PRReviews) IsApproved() bool {
	goodReview := false

	for _, reviewer := range r.reviewers {
		goodReview = false
		for _, review := range r.reviews {
			if review.User.UserName == reviewer && review.State == ReviewStateApproved && !review.Stale && !review.Dismissed {
				goodReview = true
				break
			}
		}

		if !goodReview {
			break
		}
	}

	return goodReview
}

func (r *PRReviews) HasPendingReviewBy(reviewer string) bool {
	if !slices.Contains(r.reviewers, reviewer) {
		return false
	}

	isPending := false
	for _, r := range r.reviews {
		if r.User.UserName == reviewer && !r.Stale {
			switch r.State {
			case ReviewStateApproved:
				fallthrough
			case ReviewStateRequestChanges:
				return false
			case ReviewStateRequestReview:
				fallthrough
			case ReviewStatePending:
				isPending = true
			}
		}
	}

	return isPending
}

func (r *PRReviews) IsReviewedBy(reviewer string) bool {
	if !slices.Contains(r.reviewers, reviewer) {
		return false
	}

	for _, r := range r.reviews {
		if r.User.UserName == reviewer && !r.Stale {
			switch r.State {
			case ReviewStateApproved:
				return true
			case ReviewStateRequestChanges:
				return true
			}
		}
	}

	return false
}
