// Package database provides SQLite storage for BGP routing data.
package database

import (
	"time"

	"github.com/google/uuid"
)

// ASN represents an Autonomous System Number with its metadata including
// handle, description, WHOIS data, and first/last seen timestamps.
type ASN struct {
	ASN         int    `json:"asn"`
	Handle      string `json:"handle"`
	Description string `json:"description"`
	// WHOIS parsed fields
	ASName      string     `json:"as_name,omitempty"`
	OrgName     string     `json:"org_name,omitempty"`
	OrgID       string     `json:"org_id,omitempty"`
	Address     string     `json:"address,omitempty"`
	CountryCode string     `json:"country_code,omitempty"`
	AbuseEmail  string     `json:"abuse_email,omitempty"`
	AbusePhone  string     `json:"abuse_phone,omitempty"`
	TechEmail   string     `json:"tech_email,omitempty"`
	TechPhone   string     `json:"tech_phone,omitempty"`
	RIR         string     `json:"rir,omitempty"` // ARIN, RIPE, APNIC, LACNIC, AFRINIC
	RIRRegDate  *time.Time `json:"rir_registration_date,omitempty"`
	RIRLastMod  *time.Time `json:"rir_last_modified,omitempty"`
	WHOISRaw    string     `json:"whois_raw,omitempty"`
	// Timestamps
	FirstSeen      time.Time  `json:"first_seen"`
	LastSeen       time.Time  `json:"last_seen"`
	WHOISUpdatedAt *time.Time `json:"whois_updated_at,omitempty"`
}

// Prefix represents an IP prefix (CIDR block) with its IP version (4 or 6)
// and first/last seen timestamps.
type Prefix struct {
	ID        uuid.UUID `json:"id"`
	Prefix    string    `json:"prefix"`
	IPVersion int       `json:"ip_version"` // 4 or 6
	FirstSeen time.Time `json:"first_seen"`
	LastSeen  time.Time `json:"last_seen"`
}

// Announcement represents a BGP announcement or withdrawal event,
// containing the prefix, AS path, origin ASN, peer ASN, next hop, and timestamp.
type Announcement struct {
	ID           uuid.UUID `json:"id"`
	PrefixID     uuid.UUID `json:"prefix_id"`
	PeerASN      int       `json:"peer_asn"`
	OriginASN    int       `json:"origin_asn"`
	Path         string    `json:"path"` // JSON-encoded AS path
	NextHop      string    `json:"next_hop"`
	Timestamp    time.Time `json:"timestamp"`
	IsWithdrawal bool      `json:"is_withdrawal"`
}

// ASNPeering represents a peering relationship between two ASNs,
// stored with the lower ASN as ASA and the higher as ASB.
type ASNPeering struct {
	ID        uuid.UUID `json:"id"`
	ASA       int       `json:"as_a"`
	ASB       int       `json:"as_b"`
	FirstSeen time.Time `json:"first_seen"`
	LastSeen  time.Time `json:"last_seen"`
}

// LiveRoute represents a route in the live routing table
type LiveRoute struct {
	ID          uuid.UUID `json:"id"`
	Prefix      string    `json:"prefix"`
	MaskLength  int       `json:"mask_length"`
	IPVersion   int       `json:"ip_version"`
	OriginASN   int       `json:"origin_asn"`
	PeerIP      string    `json:"peer_ip"`
	ASPath      []int     `json:"as_path"`
	NextHop     string    `json:"next_hop"`
	LastUpdated time.Time `json:"last_updated"`
	// IPv4 range fields for fast lookups (nil for IPv6)
	V4IPStart *uint32 `json:"v4_ip_start,omitempty"`
	V4IPEnd   *uint32 `json:"v4_ip_end,omitempty"`
}

// PrefixDistribution represents the distribution of prefixes by mask length
type PrefixDistribution struct {
	MaskLength int `json:"mask_length"`
	Count      int `json:"count"`
}

// ASInfo represents AS information for an IP lookup (legacy format)
type ASInfo struct {
	ASN         int       `json:"asn"`
	Handle      string    `json:"handle"`
	Description string    `json:"description"`
	Prefix      string    `json:"prefix"`
	LastUpdated time.Time `json:"last_updated"`
	Age         string    `json:"age"`
}

// IPInfo represents comprehensive IP information for the /ip endpoint
type IPInfo struct {
	IP         string   `json:"ip"`
	PTR        []string `json:"ptr,omitempty"`
	Netblock   string   `json:"netblock"`
	MaskLength int      `json:"mask_length"`
	IPVersion  int      `json:"ip_version"`
	NumPeers   int      `json:"num_peers"`
	// AS information
	ASN         int    `json:"asn"`
	ASName      string `json:"as_name,omitempty"`
	Handle      string `json:"handle,omitempty"`
	Description string `json:"description,omitempty"`
	OrgName     string `json:"org_name,omitempty"`
	OrgID       string `json:"org_id,omitempty"`
	Address     string `json:"address,omitempty"`
	CountryCode string `json:"country_code,omitempty"`
	AbuseEmail  string `json:"abuse_email,omitempty"`
	RIR         string `json:"rir,omitempty"`
	// Timestamps
	FirstSeen time.Time `json:"first_seen"`
	LastSeen  time.Time `json:"last_seen"`
	// Indicates if WHOIS data needs refresh (not serialized)
	NeedsWHOISRefresh bool `json:"-"`
}

// LiveRouteDeletion represents parameters for deleting a live route
type LiveRouteDeletion struct {
	Prefix    string
	OriginASN int
	PeerIP    string
	IPVersion int
}

// PeerUpdate represents parameters for updating a peer
type PeerUpdate struct {
	PeerIP      string
	PeerASN     int
	MessageType string
	Timestamp   time.Time
}

// ASNWHOISUpdate contains WHOIS data for updating an ASN record.
type ASNWHOISUpdate struct {
	ASN         int
	ASName      string
	OrgName     string
	OrgID       string
	Address     string
	CountryCode string
	AbuseEmail  string
	AbusePhone  string
	TechEmail   string
	TechPhone   string
	RIR         string
	RIRRegDate  *time.Time
	RIRLastMod  *time.Time
	WHOISRaw    string
}
