// Package models defines the domain types and API contracts for the
// Control Center Go backend. These types map to the existing TypeScript
// AgentCardData interface and extend it with persistence-focused types
// for the new session, task, and project entities.
//
// All JSON field names use camelCase to match the existing frontend
// contract established by the .NET backend.
package models

import "time"

// ─── Agent Status ──────────────────────────────────────────────────────────────

// AgentStatus represents an agent's operational status.
// Maps to the frontend status values: active, idle, thinking, error.
type AgentStatus string

const (
	AgentStatusActive   AgentStatus = "active"
	AgentStatusIdle     AgentStatus = "idle"
	AgentStatusThinking AgentStatus = "thinking"
	AgentStatusError    AgentStatus = "error"
)

// IsValid reports whether s is a known agent status.
func (s AgentStatus) IsValid() bool {
	switch s {
	case AgentStatusActive, AgentStatusIdle, AgentStatusThinking, AgentStatusError:
		return true
	default:
		return false
	}
}

// ─── Agent ─────────────────────────────────────────────────────────────────────

// AgentCardData is the primary data shape consumed by the Command Hub frontend.
// It matches the TypeScript AgentCardData interface exactly.
type AgentCardData struct {
	ID           string      `json:"id"`
	DisplayName  string      `json:"displayName"`
	Role         string      `json:"role"`
	Status       AgentStatus `json:"status"`
	CurrentTask  *string     `json:"currentTask,omitempty"`
	TaskProgress *int        `json:"taskProgress,omitempty"`
	TaskElapsed  *string     `json:"taskElapsed,omitempty"`
	SessionKey   string      `json:"sessionKey"`
	Channel      string      `json:"channel"`
	LastActivity string      `json:"lastActivity"`
	ErrorMessage *string     `json:"errorMessage,omitempty"`
}

// CreateAgentRequest is the payload for POST /api/agents.
type CreateAgentRequest struct {
	ID          string      `json:"id" validate:"required,min=2,max=64"`
	DisplayName string      `json:"displayName" validate:"required,min=1,max=128"`
	Role        string      `json:"role" validate:"required,min=1,max=256"`
	Status      AgentStatus `json:"status" validate:"required,agentStatus"`
	SessionKey  string      `json:"sessionKey" validate:"required,min=1"`
	Channel     string      `json:"channel" validate:"required,min=1,max=32"`
	CurrentTask *string     `json:"currentTask,omitempty"`
}

// UpdateAgentRequest is the payload for PUT /api/agents/{id}.
type UpdateAgentRequest struct {
	Status         *AgentStatus `json:"status,omitempty" validate:"omitempty,agentStatus"`
	DisplayName    *string      `json:"displayName,omitempty"`
	Role           *string      `json:"role,omitempty"`
	LastActivityAt *string      `json:"lastActivityAt,omitempty"`
	CurrentTask    *string      `json:"currentTask,omitempty"`
	TaskProgress   *int         `json:"taskProgress,omitempty" validate:"omitempty,min=0,max=100"`
	TaskElapsed    *string      `json:"taskElapsed,omitempty"`
	Channel        *string      `json:"channel,omitempty" validate:"omitempty,min=1,max=32"`
	ErrorMessage   *string      `json:"errorMessage,omitempty"`
}

// AgentStatusHistoryEntry represents a point-in-time status change for an agent.
type AgentStatusHistoryEntry struct {
	ID        string      `json:"id"`
	AgentID   string      `json:"agentId"`
	Status    AgentStatus `json:"status"`
	Task      *string     `json:"task,omitempty"`
	Timestamp string      `json:"timestamp"`
}

// ─── Session ───────────────────────────────────────────────────────────────────

// Session represents an active agent session tracked by the system.
type Session struct {
	ID             string    `json:"id"`
	SessionKey     string    `json:"sessionKey"`
	AgentID        string    `json:"agentId"`
	Channel        string    `json:"channel"`
	Status         string    `json:"status"` // running, done, streaming, error
	ContextTokens  int       `json:"contextTokens"`
	TotalTokens    int       `json:"totalTokens"`
	EstimatedCost  float64   `json:"estimatedCost"`
	Model          string    `json:"model"`
	StartedAt      time.Time `json:"startedAt"`
	LastActivityAt time.Time `json:"lastActivityAt"`
}

// ─── Task ───────────────────────────────────────────────────────────────────────

// TaskStatus represents the lifecycle state of a tracked task.
type TaskStatus string

const (
	TaskStatusPending   TaskStatus = "pending"
	TaskStatusRunning   TaskStatus = "running"
	TaskStatusCompleted TaskStatus = "completed"
	TaskStatusFailed    TaskStatus = "failed"
)

// Task represents a tracked task assigned to an agent.
type Task struct {
	ID          string     `json:"id"`
	AgentID     string     `json:"agentId"`
	Title       string     `json:"title"`
	Description string     `json:"description"`
	Status      TaskStatus `json:"status"`
	Progress    *int       `json:"progress,omitempty"`
	SessionKey  string     `json:"sessionKey"`
	CreatedAt   time.Time  `json:"createdAt"`
	UpdatedAt   time.Time  `json:"updatedAt"`
}

// ─── Project ────────────────────────────────────────────────────────────────────

// ProjectStatus represents the lifecycle state of a project.
type ProjectStatus string

const (
	ProjectStatusPlanned   ProjectStatus = "planned"
	ProjectStatusActive    ProjectStatus = "active"
	ProjectStatusPaused    ProjectStatus = "paused"
	ProjectStatusCompleted ProjectStatus = "completed"
)

// Project represents a project tracked in the system.
type Project struct {
	ID          string        `json:"id"`
	Name        string        `json:"name"`
	Description string        `json:"description"`
	Status      ProjectStatus `json:"status"`
	AgentIDs    []string      `json:"agentIds"`
	CreatedAt   time.Time     `json:"createdAt"`
	UpdatedAt   time.Time     `json:"updatedAt"`
}

// ─── Pagination ────────────────────────────────────────────────────────────────

// PaginatedResponse wraps a list response with pagination metadata.
type PaginatedResponse struct {
	Data       any  `json:"data"`
	TotalCount int  `json:"totalCount"`
	Page       int  `json:"page"`
	PageSize   int  `json:"pageSize"`
	HasMore    bool `json:"hasMore"`
}

// ─── Error ─────────────────────────────────────────────────────────────────────

// ErrorResponse is the standard API error envelope.
type ErrorResponse struct {
	Error   string            `json:"error"`
	Details map[string]string `json:"details,omitempty"`
}
