package runtime

import (
	"context"
	"time"
)

// Run drives the agent's Receive→LLM→tools→Ack loop until ctx is canceled.
// PollInterval is the idle backoff when the inbox is empty.
//
// Plan §13 lifecycle. Heartbeats already happen inside HandleOne (around the
// LLM call). The loop itself doesn't add an extra heartbeat — the wrapper
// already gives sub-second granularity around the only blocking work.
func (a *Agent) Run(ctx context.Context, pollInterval time.Duration) error {
	if pollInterval <= 0 {
		pollInterval = 50 * time.Millisecond
	}
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		default:
		}
		handled, err := a.HandleOne(ctx)
		if err != nil {
			// Loop-level error is logged via events; return so the spawner
			// can decide to respawn.
			return err
		}
		if !handled {
			select {
			case <-ctx.Done():
				return ctx.Err()
			case <-time.After(pollInterval):
			}
		}
	}
}
