package models

import (
	"encoding/json"
	"time"
)

// Task is a scheduled, one-shot, or webhook-triggered job that creates a
// service channel and runs a completion (prompt task), instantiates a
// workflow, relays a payload without LLM involvement (action task), or
// executes a built-in Go function (system task).
type Task struct {
	ID          string  `json:"id" db:"id"`
	OwnerID     string  `json:"owner_id" db:"owner_id"`
	TeamID      *string `json:"team_id,omitempty" db:"team_id"`
	Name        string  `json:"name" db:"name"`
	Description string  `json:"description" db:"description"`
	Scope       string  `json:"scope" db:"scope"` // personal | team | global

	// What to run
	TaskType       string           `json:"task_type" db:"task_type"` // prompt | workflow | action | system
	SystemFunction string           `json:"system_function,omitempty" db:"system_function"`
	PersonaID   *string          `json:"persona_id,omitempty" db:"persona_id"`
	ModelID     string           `json:"model_id" db:"model_id"`
	SystemPrompt string          `json:"system_prompt" db:"system_prompt"`
	UserPrompt  string           `json:"user_prompt" db:"user_prompt"`
	WorkflowID  *string          `json:"workflow_id,omitempty" db:"workflow_id"`
	ToolGrants  json.RawMessage  `json:"tool_grants,omitempty" db:"tool_grants"`

	// Schedule
	Schedule string `json:"schedule" db:"schedule"` // cron expression, "once", or "webhook"
	Timezone string `json:"timezone" db:"timezone"`
	IsActive bool   `json:"is_active" db:"is_active"`

	// Webhook trigger (inbound)
	TriggerToken string `json:"trigger_token,omitempty" db:"trigger_token"`

	// Execution policy
	MaxTokens    int    `json:"max_tokens" db:"max_tokens"`
	MaxToolCalls int    `json:"max_tool_calls" db:"max_tool_calls"`
	MaxWallClock int    `json:"max_wall_clock" db:"max_wall_clock"` // seconds
	OutputMode   string `json:"output_mode" db:"output_mode"`       // channel | note | webhook
	OutputChannelID *string `json:"output_channel_id,omitempty" db:"output_channel_id"`
	WebhookURL    string `json:"webhook_url" db:"webhook_url"`
	WebhookSecret string `json:"webhook_secret,omitempty" db:"webhook_secret"`

	// Provider routing
	ProviderConfigID *string `json:"provider_config_id,omitempty" db:"provider_config_id"`

	// Notifications
	NotifyOnComplete bool `json:"notify_on_complete" db:"notify_on_complete"`
	NotifyOnFailure  bool `json:"notify_on_failure" db:"notify_on_failure"`

	// Bookkeeping
	LastRunAt  *time.Time `json:"last_run_at,omitempty" db:"last_run_at"`
	NextRunAt  *time.Time `json:"next_run_at,omitempty" db:"next_run_at"`
	RunCount   int        `json:"run_count" db:"run_count"`
	CreatedAt  time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt  time.Time  `json:"updated_at" db:"updated_at"`
}

// TaskPatch contains optional fields for updating a task.
type TaskPatch struct {
	Name             *string          `json:"name,omitempty"`
	Description      *string          `json:"description,omitempty"`
	PersonaID        *string          `json:"persona_id,omitempty"`
	ModelID          *string          `json:"model_id,omitempty"`
	SystemPrompt     *string          `json:"system_prompt,omitempty"`
	UserPrompt       *string          `json:"user_prompt,omitempty"`
	WorkflowID       *string          `json:"workflow_id,omitempty"`
	ToolGrants       *json.RawMessage `json:"tool_grants,omitempty"`
	Schedule         *string          `json:"schedule,omitempty"`
	Timezone         *string          `json:"timezone,omitempty"`
	IsActive         *bool            `json:"is_active,omitempty"`
	MaxTokens        *int             `json:"max_tokens,omitempty"`
	MaxToolCalls     *int             `json:"max_tool_calls,omitempty"`
	MaxWallClock     *int             `json:"max_wall_clock,omitempty"`
	OutputMode       *string          `json:"output_mode,omitempty"`
	OutputChannelID  *string          `json:"output_channel_id,omitempty"`
	WebhookURL       *string          `json:"webhook_url,omitempty"`
	ProviderConfigID *string          `json:"provider_config_id,omitempty"`
	NotifyOnComplete *bool            `json:"notify_on_complete,omitempty"`
	NotifyOnFailure  *bool            `json:"notify_on_failure,omitempty"`
}

// TaskRun records a single execution of a task.
type TaskRun struct {
	ID              string     `json:"id" db:"id"`
	TaskID          string     `json:"task_id" db:"task_id"`
	ChannelID       *string    `json:"channel_id,omitempty" db:"channel_id"`
	Status          string     `json:"status" db:"status"` // queued | running | completed | failed | budget_exceeded | cancelled
	TriggerPayload  string     `json:"trigger_payload,omitempty" db:"trigger_payload"`
	StartedAt       time.Time  `json:"started_at" db:"started_at"`
	CompletedAt     *time.Time `json:"completed_at,omitempty" db:"completed_at"`
	TokensUsed      int        `json:"tokens_used" db:"tokens_used"`
	ToolCalls       int        `json:"tool_calls" db:"tool_calls"`
	WallClock       int        `json:"wall_clock" db:"wall_clock"` // seconds
	Error           string     `json:"error,omitempty" db:"error"`
}
