// Package teamworkflow owns the durable Team-to-Workflow association and its
// authoring lifecycle. Workflow Plan source/version persistence remains owned
// by internal/store/planstore.
package teamworkflow

import (
	"time"

	"github.com/tidbcloud/AgentTeam/internal/store/workflow/plan"
)

const (
	AuthoringStateGenerating = "generating"
	AuthoringStateIdle       = "idle"
	AuthoringStateFailed     = "failed"

	StatusDeleted  = "deleted"
	StatusActive   = "active"
	StatusArchived = "archived"

	AvailabilityUnpublished = "unpublished"
	AvailabilityActive      = "active"
	AvailabilityArchived    = "archived"

	// StateFilterAvailable selects every non-deleted relation whose currently
	// published Plan version is executable.
	StateFilterAvailable = "available"
)

// TeamWorkflow is the durable association and authoring state. DeletedAt is a
// tombstone: it intentionally survives Team deletion so its Plan never becomes
// visible as an unowned workspace Plan.
type TeamWorkflow struct {
	ID                  string
	WorkspaceID         string
	TeamID              string
	PlanID              *string
	Revision            int64
	AuthoringState      string
	SourceScopeID       string
	SourceMessageID     string
	RequestedByMemberID string
	ProposalSequence    int64
	ResolutionSequence  int64
	LastErrorCode       string
	LastErrorMessage    string
	ActivatedAt         *time.Time
	DeletedByMemberID   *string
	DeletedAt           *time.Time
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

// View joins one Team Workflow with its optional Plan.
type View struct {
	TeamWorkflow TeamWorkflow
	Plan         *plan.Plan
}

// Status derives the UI lifecycle without duplicating Workflow Plan archive
// state in the Team Workflow row.
func (view View) Status() string {
	if view.TeamWorkflow.DeletedAt != nil {
		return StatusDeleted
	}
	if view.TeamWorkflow.AuthoringState != AuthoringStateIdle {
		return view.TeamWorkflow.AuthoringState
	}
	if view.Plan != nil && view.Plan.ArchivedAt != nil {
		return StatusArchived
	}
	return StatusActive
}

// Availability reports whether an already-published version remains usable.
func (view View) Availability() string {
	if view.Plan == nil || view.Plan.CurrentVersion == nil {
		return AvailabilityUnpublished
	}
	if view.Plan.ArchivedAt != nil {
		return AvailabilityArchived
	}
	return AvailabilityActive
}

func (view View) AuthoringStatus() string {
	return view.TeamWorkflow.AuthoringState
}

func (view View) HasPendingRevision() bool {
	return false
}

type CreateGeneratingParams struct {
	ID                  string
	WorkspaceID         string
	TeamID              string
	SourceScopeID       string
	SourceMessageID     string
	RequestedByMemberID string
	Now                 time.Time
}

type CreateResult struct {
	TeamWorkflow TeamWorkflow
	Replayed     bool
}

type BindPlanParams struct {
	WorkspaceID      string
	TeamID           string
	TeamWorkflowID   string
	PlanID           string
	ExpectedRevision int64
	Now              time.Time
}

// MarkPublishedParams records a directly committed immutable Plan version on
// its Team relation.
type MarkPublishedParams struct {
	WorkspaceID      string
	TeamID           string
	TeamWorkflowID   string
	ExpectedRevision int64
	Now              time.Time
}

// AdvanceAvailabilityRevision records an atomic linked-Plan archive/restore
// transition without duplicating Plan availability in the relation row.
type AdvanceAvailabilityRevisionParams struct {
	WorkspaceID      string
	TeamID           string
	TeamWorkflowID   string
	ExpectedRevision int64
	Now              time.Time
}

type SoftDeleteParams struct {
	WorkspaceID       string
	TeamID            string
	TeamWorkflowID    string
	DeletedByMemberID string
	ExpectedRevision  int64
	Now               time.Time
}

type ListParams struct {
	WorkspaceID     string
	TeamID          string
	State           string
	Search          string
	Limit           int
	BeforeUpdatedAt *time.Time
	BeforeID        string
}
