package agent

import "time"

// Project visibility enum. Mirrors the projects.visibility CHECK constraint
// introduced by migration 00243_projects.sql: 'private' restricts access to
// the owner plus explicit grants; 'workspace' additionally allows any active
// workspace member to view/files/reviews without an edit path.
const (
	ProjectVisibilityPrivate   = "private"
	ProjectVisibilityWorkspace = "workspace"
)

// ProjectGrant role enum. Mirrors the project_grants.role CHECK constraint.
// The implicit "owner" role is intentionally NOT a persisted grant value —
// it is derived from projects.owner_user_id and surfaced only via
// ProjectRoleOwner for in-memory authorization checks.
const (
	ProjectRoleOwner  = "owner"
	ProjectRoleManage = "manage"
	ProjectRoleView   = "view"
)

// Project is the workspace-scoped, machine-attached resource that groups
// reviews + files for one workspace target. The model is plain — no field
// tags — because DTO conversion lives in internal/api/dto/converter, mirroring
// the ReviewContext pattern.
//
// MachineID and RootPath are immutable after create: a Project is bound to a
// single (machine, root_path) tuple for its lifetime. Visibility and the
// name/description metadata are mutable via UpdateProjectParams.
type Project struct {
	ID              string
	WorkspaceID     string
	MachineID       string
	RootPath        string
	Name            string
	Description     string
	Visibility      string
	CurrentRole     string
	OwnerUserID     string
	CreatedByUserID string
	UpdatedByUserID string
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

type ProjectListOptions struct {
	Limit             int
	Query             string
	MachineIDs        []string
	ExcludeMachineIDs []string
	CursorUpdatedAt   time.Time
	CursorID          string
}

type ProjectPage struct {
	Projects []Project
	HasMore  bool
}

// ProjectGrant is one persisted non-owner access grant on a Project. Owner
// access is never written here — see ProjectRoleOwner.
type ProjectGrant struct {
	ProjectID string
	MemberID  string
	Role      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

// CreateProjectParams is the input to Project creation. WorkspaceID,
// MachineID, and RootPath are required; Visibility defaults to 'private';
// Name/Description may be empty. OwnerUserID is NOT set by the caller —
// the store resolves it from the authenticating user via
// access.LoadHumanWorkspaceMember.
type CreateProjectParams struct {
	WorkspaceID string
	MachineID   string
	RootPath    string
	Name        string
	Description string
	Visibility  string
}

// UpdateProjectParams is the input to Project metadata mutation. Each
// pointer field is optional; nil means "preserve existing". MachineID and
// RootPath are intentionally absent — they are immutable. OwnerUserID is
// absent for the same reason; owner transfer is out of C2a scope.
type UpdateProjectParams struct {
	Name        *string
	Description *string
	Visibility  *string
}

// GetOrCreateProjectParams is the input to Project get-or-create. WorkspaceID
// is required for the ForUser path (the human caller scopes the workspace);
// the ForAgent path overrides it with the authenticated agent's workspace.
// MachineID defaults to the authenticated agent's machine when empty.
type GetOrCreateProjectParams struct {
	WorkspaceID string
	MachineID   string
	RootPath    string
	Name        string
	Description string
}
