package types

import (
	"crypto/rand"
	"encoding/hex"
	"net"
	"time"
)

// Node represents a client node in the network
type Node struct {
	ID          string    `json:"id"`
	Name        string    `json:"name"`
	PublicKey   string    `json:"public_key"`
	IP          net.IP    `json:"ip"`
	LastSeen    time.Time `json:"last_seen"`
	IsOnline    bool      `json:"is_online"`
	Description string    `json:"description,omitempty"`
	// Subnet routing fields
	IsSubnetRouter bool     `json:"is_subnet_router"`
	Subnets        []string `json:"subnets,omitempty"` // e.g., ["192.168.1.0/24", "10.0.1.0/24"]
}

// Network represents the overall network configuration
type Network struct {
	ID          string    `json:"id"`
	Name        string    `json:"name"`
	CIDR        string    `json:"cidr"`
	PrivateKey  string    `json:"private_key"`
	PublicKey   string    `json:"public_key"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

// Peer represents a peer configuration for WireGuard
type Peer struct {
	PublicKey  string   `json:"public_key"`
	AllowedIPs []string `json:"allowed_ips"`
	Endpoint   string   `json:"endpoint,omitempty"`
	KeepAlive  int      `json:"keep_alive,omitempty"`
	// Subnet routing fields
	IsSubnetRouter bool     `json:"is_subnet_router"`
	Subnets        []string `json:"subnets,omitempty"`
}

// SubnetRoute represents a subnet route advertisement
type SubnetRoute struct {
	NodeID  string   `json:"node_id"`
	NodeName string  `json:"node_name"`
	Subnets []string `json:"subnets"`
	Active  bool     `json:"active"`
}

// Message types for client-controller communication
type MessageType string

const (
	MessageTypeRegister     MessageType = "register"
	MessageTypeUpdate       MessageType = "update"
	MessageTypePeers        MessageType = "peers"
	MessageTypePing         MessageType = "ping"
	MessageTypePong         MessageType = "pong"
	MessageTypeSubnetAdvert MessageType = "subnet_advert"
	MessageTypeSubnetUpdate MessageType = "subnet_update"
)

// Message represents a message between client and controller
type Message struct {
	Type    MessageType `json:"type"`
	Payload interface{} `json:"payload"`
}

// RegisterRequest is sent by client to register with controller
type RegisterRequest struct {
	NodeName   string   `json:"node_name"`
	PublicKey  string   `json:"public_key"`
	Endpoint   string   `json:"endpoint,omitempty"`
	// Subnet routing fields
	IsSubnetRouter bool     `json:"is_subnet_router"`
	Subnets        []string `json:"subnets,omitempty"`
}

// RegisterResponse is sent by controller in response to registration
type RegisterResponse struct {
	NodeID    string `json:"node_id"`
	IP        string `json:"ip"`
	Network   string `json:"network"`
	Peers     []Peer `json:"peers"`
	// Subnet routing fields
	SubnetRoutes []SubnetRoute `json:"subnet_routes,omitempty"`
}

// UpdateRequest is sent by client to update its status
type UpdateRequest struct {
	NodeID   string `json:"node_id"`
	Endpoint string `json:"endpoint,omitempty"`
}

// SubnetAdvertRequest is sent by client to advertise subnets
type SubnetAdvertRequest struct {
	NodeID  string   `json:"node_id"`
	Subnets []string `json:"subnets"`
}

// SubnetUpdateRequest is sent by controller to update subnet routes
type SubnetUpdateRequest struct {
	SubnetRoutes []SubnetRoute `json:"subnet_routes"`
}

// GenerateID generates a random ID
func GenerateID() string {
	bytes := make([]byte, 16)
	rand.Read(bytes)
	return hex.EncodeToString(bytes)
} 