package brief

import (
	"context"

	"github.com/yan1h/agent-coding-workflow/internal/infra/git"
)

// RepoOrientation 是仓库的轻量定向信息：当前分支、最近若干提交摘要、脏文件路径。
// 用于给 agent 一个"我现在在哪个分支、最近发生了什么、工作树是否干净"的速览。
type RepoOrientation struct {
	Branch        string
	RecentCommits []string
	DirtyFiles    []string
}

// IsEmpty 报告该定向信息是否完全为空（无分支、无提交、无脏文件）。
func (o RepoOrientation) IsEmpty() bool {
	return o.Branch == "" && len(o.RecentCommits) == 0 && len(o.DirtyFiles) == 0
}

// RepoOrienter 是 brief 对 git 的窄接口：给定目录返回有界的仓库定向信息。
// 让 brief 可在没有真实仓库的情况下被单测（注入 fake orienter）。
type RepoOrienter interface {
	Orient(ctx context.Context, dir, branch string, maxCommits, maxDirty int) RepoOrientation
}

// gitClient 是 orienter 对 git.Runner 的最小子集。*git.DefaultRunner 直接满足。
type gitClient interface {
	Log(ctx context.Context, dir string, n int) ([]git.Commit, error)
	Status(ctx context.Context, dir string) ([]git.FileStatus, error)
}

// gitOrienter 是 RepoOrienter 的生产实现，基于 infra/git 的 Log + Status。
// 设计为"尽力而为且永不致命"：任何 git 调用失败只产生部分/空的定向信息，
// 不返回 error，从而不会拖垮整份简报（git 失败不应阻塞 prompt 注入）。
type gitOrienter struct{ g gitClient }

// NewRepoOrienter 用给定 git runner 构造 RepoOrienter。
func NewRepoOrienter(g gitClient) RepoOrienter { return &gitOrienter{g: g} }

func (o *gitOrienter) Orient(ctx context.Context, dir, branch string, maxCommits, maxDirty int) RepoOrientation {
	out := RepoOrientation{Branch: branch}
	if dir == "" || o.g == nil {
		return out
	}
	if maxCommits > 0 {
		if commits, err := o.g.Log(ctx, dir, maxCommits); err == nil {
			for _, c := range commits {
				short := c.Hash
				if len(short) > 8 {
					short = short[:8]
				}
				out.RecentCommits = append(out.RecentCommits, short+" "+c.Subject)
			}
		}
	}
	if maxDirty > 0 {
		if files, err := o.g.Status(ctx, dir); err == nil {
			for i, f := range files {
				if i >= maxDirty {
					break
				}
				out.DirtyFiles = append(out.DirtyFiles, f.Path)
			}
		}
	}
	return out
}
