// Package vcs abstracts the git-host (VCS) REST API the platform uses to open
// and merge pull requests. v1 ships a Gitea-first implementation (gitea.go)
// targeting the self-hosted host git.jerryyan.net; other hosts return an
// Unimplemented error from the RepoRef parser / provider.
//
// The provider is intentionally narrow: only the verbs the change-request
// merge gate needs (CreatePR / GetPR / Comment / Merge / ListIssues). Secrets
// (the platform Gitea token) are held by the concrete provider, never passed
// through the interface.
package vcs

import "context"

// Provider is the git-host API surface consumed by the changerequest service.
type Provider interface {
	// CreatePR opens a pull request from in.Head into in.Base.
	CreatePR(ctx context.Context, in CreatePRInput) (*PullRequest, error)
	// GetPR fetches a single PR by its host-side index/number, including a
	// best-effort CI state derived from the head commit's combined status.
	GetPR(ctx context.Context, repo RepoRef, number int64) (*PullRequest, error)
	// Comment posts a comment on the PR (Gitea treats PRs as issues for comments).
	Comment(ctx context.Context, repo RepoRef, number int64, body string) error
	// Merge merges the PR via in.Method, returning the resulting merge commit SHA.
	Merge(ctx context.Context, repo RepoRef, number int64, in MergeInput) (mergeSHA string, err error)
	// ListIssues lists repository issues (not PRs) for orientation / linking.
	ListIssues(ctx context.Context, repo RepoRef, opts IssueListOptions) ([]Issue, error)
}

// RepoRef identifies a repository on the host as owner/name. Derived from a
// workspace's GitRemoteURL by ParseRepoRef.
type RepoRef struct {
	Owner string
	Name  string
}

// CreatePRInput is the input to Provider.CreatePR.
type CreatePRInput struct {
	Repo  RepoRef
	Head  string // source branch
	Base  string // target branch
	Title string
	Body  string
}

// MergeInput controls how Provider.Merge merges the PR.
type MergeInput struct {
	Method  string // "merge" | "squash" | "rebase"
	Title   string // merge commit title (optional)
	Message string // merge commit message body (optional)
}

// PullRequest is the host's view of a PR mapped to platform fields.
type PullRequest struct {
	Number         int64
	State          string // "open" | "closed" (Gitea: PR closed covers merged too)
	Mergeable      bool
	Merged         bool
	MergeCommitSHA string
	HTMLURL        string
	CIState        string // "unknown" | "pending" | "success" | "failure"
}

// Issue is a minimal host issue projection.
type Issue struct {
	Number  int64
	Title   string
	State   string
	HTMLURL string
}

// IssueListOptions filters ListIssues. State empty => host default ("open").
type IssueListOptions struct {
	State string // "open" | "closed" | "all"
	Limit int
}
