package models

import "encoding/json"

// ── RPC ──────────────────────────────────────────────────────────────────────

type RPCCommand struct {
	Type string `json:"type"`
	ID   string `json:"id,omitempty"`
	// prompt / steer / follow_up
	Message           string      `json:"message,omitempty"`
	Images            []ChatImage `json:"images,omitempty"`
	StreamingBehavior string      `json:"streamingBehavior,omitempty"`
	// model / thinking
	Provider string          `json:"provider,omitempty"`
	ModelID  string          `json:"modelId,omitempty"`
	Level    json.RawMessage `json:"level,omitempty"`
	// session
	SessionPath string `json:"sessionPath,omitempty"`
	CwdOverride string `json:"cwdOverride,omitempty"`
	Name        string `json:"name,omitempty"`
	// bash
	Command            string `json:"command,omitempty"`
	ExcludeFromContext bool   `json:"excludeFromContext,omitempty"`
}

// RPCResponse mirrors the pi CLI response frame:
//
//	{"type":"response","id":"req_1","command":"get_state","success":true,"data":{...},"error":"..."}
type RPCResponse struct {
	Type    string          `json:"type"`
	ID      string          `json:"id,omitempty"`
	Command string          `json:"command,omitempty"`
	Success bool            `json:"success"`
	Data    json.RawMessage `json:"data,omitempty"`
	Error   string          `json:"error,omitempty"`
}

// Raw event line forwarded to SSE clients as-is
type RPCEvent struct {
	Type string          `json:"type"`
	Raw  json.RawMessage `json:"-"`
}

// ── Chat ─────────────────────────────────────────────────────────────────────

type ChatImage struct {
	MediaType string `json:"mediaType"`
	Data      string `json:"data"` // base64
}

type ChatRequest struct {
	Message           string      `json:"message"`
	Images            []ChatImage `json:"images,omitempty"`
	StreamingBehavior string      `json:"streamingBehavior,omitempty"`
}

type SteerRequest struct {
	Message string `json:"message"`
}

type BashRequest struct {
	Command string `json:"command"`
}

type MessagesRequest struct {
	Path string `json:"path"`
}

// ── Sessions ─────────────────────────────────────────────────────────────────

type SessionSummary struct {
	Path         string `json:"path"`
	Name         string `json:"name,omitempty"`
	FirstMessage string `json:"firstMessage,omitempty"`
	MessageCount int    `json:"messageCount,omitempty"`
	Modified     string `json:"modified,omitempty"`
	Created      string `json:"created,omitempty"`
	Pinned       bool   `json:"pinned,omitempty"`
}

type SessionsResponse struct {
	Sessions []SessionSummary `json:"sessions"`
}

type SessionStateResponse struct {
	IsStreaming bool   `json:"isStreaming"`
	SessionFile string `json:"sessionFile,omitempty"`
}

type LoadSessionRequest struct {
	Path string `json:"path"`
}

type ActivateSessionRequest struct {
	Path string `json:"path"`
}

type DeleteSessionRequest struct {
	Path string `json:"path"`
}

type PinSessionRequest struct {
	Path   string `json:"path"`
	Pinned bool   `json:"pinned"`
}

type NameSessionRequest struct {
	Path string `json:"path"`
	Name string `json:"name"`
}

type HistoryRequest struct {
	Path string `json:"path"`
}

// ── Models ───────────────────────────────────────────────────────────────────

type ModelEntry struct {
	Provider    string `json:"provider"`
	ModelID     string `json:"modelId"`
	DisplayName string `json:"displayName,omitempty"`
	IsDefault   bool   `json:"isDefault,omitempty"`
}

type ModelsResponse struct {
	Models  []ModelEntry `json:"models"`
	Current *ModelEntry  `json:"current,omitempty"`
}

type SetModelRequest struct {
	Provider string `json:"provider"`
	ModelID  string `json:"modelId"`
}

type SetThinkingRequest struct {
	Level json.RawMessage `json:"level"` // string ("high"/"off"...) or number
}

// ── Commands ─────────────────────────────────────────────────────────────────

type SlashCommand struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	Source      string `json:"source"` // builtin | extension | skill | prompt
}

type CommandsResponse struct {
	Commands []SlashCommand `json:"commands"`
}

// ── WebUI Config ──────────────────────────────────────────────────────────────

type AvatarsResponse struct {
	UserAvatarURL  string `json:"userAvatarUrl"`
	AgentAvatarURL string `json:"agentAvatarUrl"`
}

type WebuiConfigResponse struct {
	Key   string `json:"key,omitempty"`
	Value string `json:"value,omitempty"`
	// batch response
	Entries map[string]string `json:"entries,omitempty"`
}

type WebuiConfigSetRequest struct {
	Key   string `json:"key,omitempty"`
	Value string `json:"value,omitempty"`
	// batch
	Entries map[string]string `json:"entries,omitempty"`
}

type WebuiConfigDeleteRequest struct {
	Key string `json:"key"`
}

// ── Settings ──────────────────────────────────────────────────────────────────
// Field names mirror the frontend SettingsData contract (frontend/src/types/events.ts).

type SkillInfo struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	Path        string `json:"path"`
	Source      string `json:"source,omitempty"`
	Scope       string `json:"scope,omitempty"`
	Enabled     bool   `json:"enabled"`
	Toggleable  bool   `json:"toggleable"`
}

type ExtensionInfo struct {
	Name       string   `json:"name"`
	Path       string   `json:"path"`
	Category   string   `json:"category,omitempty"` // local | npm
	Source     string   `json:"source,omitempty"`
	Version    string   `json:"version,omitempty"`
	Enabled    bool     `json:"enabled"`
	Toggleable bool     `json:"toggleable"` // only local extensions can be toggled
	Commands   []string `json:"commands,omitempty"`
}

type MCPTool struct {
	Server      string `json:"server,omitempty"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	Enabled     bool   `json:"enabled"`
}

type MCPServer struct {
	Name             string    `json:"name"`
	Configured       bool      `json:"configured"`
	Enabled          bool      `json:"enabled"`
	ToolCount        int       `json:"toolCount"`
	EnabledToolCount int       `json:"enabledToolCount"`
	Tools            []MCPTool `json:"tools,omitempty"`
}

// SkillToggleRequest / ExtensionToggleRequest identify the target by path.
type SkillToggleRequest struct {
	Path    string `json:"path"`
	Enabled bool   `json:"enabled"`
}

type ExtensionToggleRequest struct {
	Path    string `json:"path"`
	Enabled bool   `json:"enabled"`
}

type MCPServerToggleRequest struct {
	Server  string `json:"server"`
	Enabled bool   `json:"enabled"`
}

type MCPToolToggleRequest struct {
	Server  string `json:"server"`
	Tool    string `json:"tool"`
	Enabled bool   `json:"enabled"`
}

// SystemPromptRequest uses a pointer so a missing field is distinguishable from
// an empty string — guards against accidentally clearing the file.
type SystemPromptRequest struct {
	SystemPrompt *string `json:"systemPrompt"`
}

type ModelsConfigRequest struct {
	ModelsConfig *string `json:"modelsConfig"`
}

type AvatarsSetRequest struct {
	UserAvatarURL  string `json:"userAvatarUrl"`
	AgentAvatarURL string `json:"agentAvatarUrl"`
}

// ── Extension UI ──────────────────────────────────────────────────────────────

type ExtensionUIResponseRequest struct {
	ID       string          `json:"id"`
	Response json.RawMessage `json:"response"`
}

// ── Generic ───────────────────────────────────────────────────────────────────

type OKResponse struct {
	OK bool `json:"ok"`
}

type ErrorResponse struct {
	Error string `json:"error"`
}
