// Package models содержит общие типы данных pulse-lets-go.
package models

import "time"

// --- NATS: метрика от нижестоящей АТС ---

// NodeMetric — сообщение, публикуемое нодой в NATS каждые 5 сек.
type NodeMetric struct {
	NodeID          string  `json:"node_id"`
	TS              int64   `json:"ts"`     // unix timestamp
	Status          string  `json:"status"` // "ok", "degraded", "down"
	ActiveCalls     int     `json:"active_calls"`
	MaxCalls        int     `json:"max_calls"`
	IdleCPU         float64 `json:"idle_cpu"`              // 0..100 %
	LoadAvg         float64 `json:"load_avg"`              // system load average (1m)
	CallFailureRate float64 `json:"call_failure_rate"`     // 0.0..100.0 %
	SIPGateway      string  `json:"sip_gateway,omitempty"` // SIP-адрес ноды для авто-создания транка
}

// --- In-memory состояние ноды в engine ---

// NodeState — полное состояние ноды в памяти балансировщика.
// Содержит данные последней метрики + поля ручного управления.
type NodeState struct {
	NodeMetric
	Disabled       bool    `json:"disabled"`
	DisabledReason string  `json:"disabled_reason"`
	Score          float64 `json:"score"`
	LethalReason   string  `json:"lethal_reason,omitempty"` // причина, если score = -100
}

// --- Trunk ---

// TrunkType — тип транка.
type TrunkType string

const (
	TrunkIngress  TrunkType = "ingress"
	TrunkBalance  TrunkType = "balance"
	TrunkFallback TrunkType = "fallback"
)

// Trunk — модель транка (из trunks.json).
type Trunk struct {
	ID          string    `json:"id"`
	Name        string    `json:"name"`
	Type        TrunkType `json:"type"`
	NodeID      string    `json:"node_id,omitempty"` // только для balance
	Gateway     string    `json:"gateway"`
	Codecs      []string  `json:"codecs,omitempty"`
	Context     string    `json:"context,omitempty"`
	Enabled     bool      `json:"enabled"`
	Description string    `json:"description,omitempty"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

// --- User ---

// UserRole — роль пользователя.
type UserRole string

const (
	RoleAdmin  UserRole = "admin"
	RoleViewer UserRole = "viewer"
)

// User — модель пользователя (из users.json).
type User struct {
	ID           string    `json:"id"`
	Username     string    `json:"username"`
	PasswordHash string    `json:"password_hash"`
	Role         UserRole  `json:"role"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

// --- Auth ---

// LoginRequest — тело запроса на /api/auth/login.
type LoginRequest struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

// LoginResponse — тело ответа /api/auth/login.
type LoginResponse struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int64  `json:"expires_in"`
}

// --- Routing Rules ---

// RouteRule — правило маршрутизации: CID-based, destination-based, ingress-trunk routing.
// Правила проверяются по порядку Priority (first-match-wins).
// Все непустые Match-поля должны совпасть (AND-логика).
// Пустые Match-поля — не проверяются.
type RouteRule struct {
	ID                string    `json:"id"`
	Name              string    `json:"name"`
	Enabled           bool      `json:"enabled"`
	Priority          int       `json:"priority"`

	// Match conditions — regex, пустая строка = не проверять
	MatchCallerID     string    `json:"match_caller_id,omitempty"`
	MatchDestination  string    `json:"match_destination,omitempty"`
	MatchIngressTrunk string    `json:"match_ingress_trunk,omitempty"`

	// Time-based match — пустые = не проверять
	MatchDaysOfWeek   string    `json:"match_days,omitempty"`      // "1-5" | "1,3,5"
	MatchTimeStart    string    `json:"match_time_start,omitempty"` // "HH:MM"
	MatchTimeEnd      string    `json:"match_time_end,omitempty"`   // "HH:MM"

	// Action
	ActionType        string    `json:"action_type"`   // "node" | "pool" | "auto"
	ActionNodeID      string    `json:"action_node_id,omitempty"`
	ActionPoolIDs     []string  `json:"action_pool_ids,omitempty"`

	Description       string    `json:"description,omitempty"`
	CreatedAt         time.Time `json:"created_at"`
	UpdatedAt         time.Time `json:"updated_at"`
}

// --- /api/route ---

// RouteResponse — ответ на запрос маршрутизации.
type RouteResponse struct {
	// Успех
	NodeID     string  `json:"node_id,omitempty"`
	Score      float64 `json:"score,omitempty"`
	SIPGateway string  `json:"sip_gateway,omitempty"`

	// Какое правило маршрутизации применилось (пустая строка = none)
	MatchedRule string `json:"matched_rule,omitempty"`

	// Fallback
	Fallback bool   `json:"fallback,omitempty"`
	Reason   string `json:"reason,omitempty"`

	// Общая информация о нодах
	Nodes []RouteNodeInfo `json:"nodes,omitempty"`

	// Ошибка
	Error string `json:"error,omitempty"`
}

// RouteNodeInfo — информация о ноде в ответе маршрутизации.
type RouteNodeInfo struct {
	ID     string  `json:"id"`
	Score  float64 `json:"score"`
	Reason string  `json:"reason,omitempty"`
	Status string  `json:"status"`
}

// --- API: Nodes ---

// ToggleNodeRequest — запрос на включение/выключение ноды.
type ToggleNodeRequest struct {
	Disabled bool   `json:"disabled"`
	Reason   string `json:"reason,omitempty"`
}

// NodeInfo — информация о ноде для фронта.
type NodeInfo struct {
	NodeID          string  `json:"node_id"`
	TS              int64   `json:"ts"`
	Status          string  `json:"status"`
	ActiveCalls     int     `json:"active_calls"`
	MaxCalls        int     `json:"max_calls"`
	IdleCPU         float64 `json:"idle_cpu"`
	LoadAvg         float64 `json:"load_avg"`
	CallFailureRate float64 `json:"call_failure_rate"`
	Disabled        bool    `json:"disabled"`
	DisabledReason  string  `json:"disabled_reason,omitempty"`
	Score           float64 `json:"score"`
	LethalReason    string  `json:"lethal_reason,omitempty"`
	IsStale         bool    `json:"is_stale"`
	SecondsAgo      float64 `json:"seconds_ago"`
}

// --- API: Users ---

// CreateUserRequest — запрос на создание пользователя.
type CreateUserRequest struct {
	Username string   `json:"username"`
	Password string   `json:"password"`
	Role     UserRole `json:"role"`
}

// UpdateUserRequest — запрос на обновление пользователя.
type UpdateUserRequest struct {
	Username *string   `json:"username,omitempty"`
	Password *string   `json:"password,omitempty"`
	Role     *UserRole `json:"role,omitempty"`
}

// --- API: Trunks ---

// CreateTrunkRequest — запрос на создание транка.
type CreateTrunkRequest struct {
	Name        string    `json:"name"`
	Type        TrunkType `json:"type"`
	NodeID      string    `json:"node_id,omitempty"`
	Gateway     string    `json:"gateway"`
	Codecs      []string  `json:"codecs,omitempty"`
	Context     string    `json:"context,omitempty"`
	Enabled     bool      `json:"enabled"`
	Description string    `json:"description,omitempty"`
}

// UpdateTrunkRequest — запрос на обновление транка.
type UpdateTrunkRequest struct {
	Name        *string    `json:"name,omitempty"`
	Type        *TrunkType `json:"type,omitempty"`
	NodeID      *string    `json:"node_id,omitempty"`
	Gateway     *string    `json:"gateway,omitempty"`
	Codecs      []string   `json:"codecs,omitempty"`
	Context     *string    `json:"context,omitempty"`
	Enabled     *bool      `json:"enabled,omitempty"`
	Description *string    `json:"description,omitempty"`
}

// --- Monitoring ---

// ZabbixNode — элемент LLD (Low-Level Discovery) для Zabbix.
type ZabbixNode struct {
	NodeID          string  `json:"{#NODE_ID}"`
	Status          string  `json:"{#STATUS}"`
	ActiveCalls     int     `json:"{#ACTIVE_CALLS}"`
	MaxCalls        int     `json:"{#MAX_CALLS}"`
	IdleCPU         float64 `json:"{#IDLE_CPU}"`
	LoadAvg         float64 `json:"{#LOAD_AVG}"`
	CallFailureRate float64 `json:"{#CALL_FAILURE_RATE}"`
	Score           float64 `json:"{#SCORE}"`
	Disabled        bool    `json:"{#DISABLED}"`
	IsStale         bool    `json:"{#IS_STALE}"`
	SecondsAgo      float64 `json:"{#SECONDS_AGO}"`
}

// ZabbixResponse — ответ на запрос Zabbix LLD.
type ZabbixResponse struct {
	Data []ZabbixNode `json:"data"`
}

// --- Balancer ---

// BalancerInfo — состояние балансировщика для дашборда.
type BalancerInfo struct {
	EslConnected   bool   `json:"esl_connected"`
	EslUptimeSec   int64  `json:"esl_uptime_sec,omitempty"`
	EslReconnects  int64  `json:"esl_reconnects,omitempty"`
	NatsConnected  bool   `json:"nats_connected"`
	GatewaysTotal  int    `json:"gateways_total"`
	GatewaysUp     int    `json:"gateways_up"`
	GatewaysDown   int    `json:"gateways_down"`
	FsActiveCalls  int    `json:"fs_active_calls"`
	FsMaxSessions  int    `json:"fs_max_sessions"`
	FsUptime       string `json:"fs_uptime"`
	RouteTotal     int64  `json:"route_total"`
	RouteFallbacks int64  `json:"route_fallbacks"`
	UptimeSec      int64  `json:"uptime_sec"`
	BalanceMode    string `json:"balance_mode"`
}

// --- WebSocket ---

// WsMetricsMessage — сообщение, отправляемое по WebSocket.
type WsMetricsMessage struct {
	Type    string      `json:"type"` // "nodes_update", "balancer_update", "gateway_update", etc
	Payload interface{} `json:"payload"`
}
