package model

import "time"

// ExcursionPhase tracks where the hero is within a mini-adventure session.
// The lifecycle is: Out → Wild → Return → (back to road, phase cleared).
type ExcursionPhase string

const (
	ExcursionNone   ExcursionPhase = ""
	ExcursionOut    ExcursionPhase = "out"    // moving off-road into the forest
	ExcursionWild   ExcursionPhase = "wild"   // in the wilderness (encounters happen here)
	ExcursionReturn ExcursionPhase = "return" // returning to the road (encounters still possible)
)

// RestKind discriminates the context of a StateResting period.
type RestKind string

const (
	RestKindNone            RestKind = ""
	RestKindTown            RestKind = "town"
	RestKindRoadside        RestKind = "roadside"
	RestKindAdventureInline RestKind = "adventure_inline"
)

// ExcursionSession holds the live state of an active mini-adventure (off-road excursion).
// When Phase == ExcursionNone the session is inactive and all other fields are zero-valued.
type ExcursionSession struct {
	Phase     ExcursionPhase
	StartedAt time.Time

	// OutUntil marks the end of the out phase (hero reached full depth); derived from depth/speed.
	OutUntil time.Time
	// WildUntil marks the end of the wild phase; once reached the hero begins returning.
	WildUntil time.Time
	// ReturnUntil marks the deadline for the return phase; once reached the hero is back on road.
	ReturnUntil time.Time

	// DepthWorldUnits is the max perpendicular distance from the road spine for this session.
	DepthWorldUnits float64

	// RoadFreezeWaypoint / RoadFreezeFraction capture road progress at the moment the hero
	// left the road, so it can be restored exactly when the excursion ends.
	RoadFreezeWaypoint  int
	RoadFreezeFraction  float64
}

// Active reports whether an excursion session is in progress.
func (s *ExcursionSession) Active() bool {
	return s.Phase != ExcursionNone
}

// ExcursionPersisted is the JSON-serialisable subset of ExcursionSession stored in the
// heroes.town_pause JSONB column so that reconnect / offline catch-up can resume mid-adventure.
type ExcursionPersisted struct {
	Phase              string     `json:"phase,omitempty"`
	StartedAt          *time.Time `json:"startedAt,omitempty"`
	OutUntil           *time.Time `json:"outUntil,omitempty"`
	WildUntil          *time.Time `json:"wildUntil,omitempty"`
	ReturnUntil        *time.Time `json:"returnUntil,omitempty"`
	DepthWorldUnits    float64    `json:"depthWorldUnits,omitempty"`
	RoadFreezeWaypoint int        `json:"roadFreezeWaypoint,omitempty"`
	RoadFreezeFraction float64    `json:"roadFreezeFraction,omitempty"`
}
