package agentTypes

import (
	"encoding/json"
	"time"
)

type EventType int

func (e EventType) MarshalJSON() ([]byte, error) {
	return json.Marshal(e.String())
}

var eventTypeByName = map[string]EventType{
	"EventText":            EventText,
	"EventTextDone":        EventTextDone,
	"EventSkillResult":     EventSkillResult,
	"EventAgentSelect":     EventAgentSelect,
	"EventAgentResult":     EventAgentResult,
	"EventToolCall":        EventToolCall,
	"EventToolCallStart":   EventToolCallStart,
	"EventToolCallText":    EventToolCallText,
	"EventToolCallEnd":     EventToolCallEnd,
	"EventToolResult":      EventToolResult,
	"EventToolSkipped":     EventToolSkipped,
	"EventToolConfirm":     EventToolConfirm,
	"EventExecError":       EventExecError,
	"EventError":           EventError,
	"EventSummaryGenerate": EventSummaryGenerate,
	"EventDone":            EventDone,
	"EventUserInput":       EventUserInput,
	"EventDaemonLog":       EventDaemonLog,
	"EventConnected":       EventConnected,
}

func (e *EventType) UnmarshalJSON(data []byte) error {
	var s string
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}
	if v, ok := eventTypeByName[s]; ok {
		*e = v
		return nil
	}
	return nil
}

const (
	EventText EventType = iota
	EventTextDone
	EventSkillResult
	EventAgentSelect
	EventAgentResult
	EventToolCall
	EventToolCallStart
	EventToolCallText
	EventToolCallEnd
	EventToolResult
	EventToolSkipped
	EventToolConfirm
	EventExecError
	EventError
	EventSummaryGenerate
	EventDone
	EventUserInput
	EventDaemonLog
	EventConnected
)

func (e EventType) String() string {
	switch e {
	case EventText:
		return "EventText"
	case EventTextDone:
		return "EventTextDone"
	case EventSkillResult:
		return "EventSkillResult"
	case EventAgentSelect:
		return "EventAgentSelect"
	case EventAgentResult:
		return "EventAgentResult"
	case EventToolCall:
		return "EventToolCall"
	case EventToolCallStart:
		return "EventToolCallStart"
	case EventToolCallText:
		return "EventToolCallText"
	case EventToolCallEnd:
		return "EventToolCallEnd"
	case EventToolResult:
		return "EventToolResult"
	case EventToolSkipped:
		return "EventToolSkipped"
	case EventToolConfirm:
		return "EventToolConfirm"
	case EventExecError:
		return "EventExecError"
	case EventError:
		return "EventError"
	case EventSummaryGenerate:
		return "EventSummaryGenerate"
	case EventDone:
		return "EventDone"
	case EventUserInput:
		return "EventUserInput"
	case EventDaemonLog:
		return "EventDaemonLog"
	case EventConnected:
		return "EventConnected"
	default:
		return "EventUnknown"
	}
}

type Event struct {
	Type     EventType     `json:"type"`
	Source   string        `json:"source,omitempty"`
	Text     string        `json:"text,omitempty"`
	ToolName string        `json:"tool_name,omitempty"`
	ToolArgs string        `json:"tool_args,omitempty"`
	ToolID   string        `json:"tool_id,omitempty"`
	Result   string        `json:"result,omitempty"`
	Model    string        `json:"model,omitempty"`
	Usage    *Usage        `json:"usage,omitempty"`
	Duration time.Duration `json:"duration,omitempty"`
	Err      error         `json:"-"`
	ReplyCh  chan bool     `json:"-"`
}
