package domain

import "time"

// Domain represents a tracked domain with WHOIS and DNS information
type Domain struct {
	ID         string `json:"id" db:"id"`
	DomainName string `json:"domain_name" db:"domain_name"`
	Status     string `json:"status" db:"status"`
	Active     bool   `json:"active" db:"active"`

	// Dates
	ExpiryDate   *time.Time `json:"expiry_date" db:"expiry_date"`
	CreationDate *time.Time `json:"creation_date" db:"creation_date"`
	UpdatedDate  *time.Time `json:"updated_date" db:"updated_date"`

	// Registrar
	RegistrarName    string `json:"registrar_name" db:"registrar_name"`
	RegistrarID      string `json:"registrar_id" db:"registrar_id"`
	RegistrarURL     string `json:"registrar_url" db:"registrar_url"`
	RegistryDomainID string `json:"registry_domain_id" db:"registry_domain_id"`

	// DNS
	DNSSEC      string   `json:"dnssec" db:"dnssec"`
	NameServers []string `json:"name_servers" db:"name_servers"`
	MXRecords   []string `json:"mx_records" db:"mx_records"`
	TXTRecords  []string `json:"txt_records" db:"txt_records"`
	CNAMERecord string   `json:"cname_record" db:"cname_record"`
	SRVRecords  []string `json:"srv_records" db:"srv_records"`

	// IP Addresses
	IPv4Addresses []string `json:"ipv4_addresses" db:"ipv4_addresses"`
	IPv6Addresses []string `json:"ipv6_addresses" db:"ipv6_addresses"`

	// SSL Certificate
	SSLIssuer        string     `json:"ssl_issuer" db:"ssl_issuer"`
	SSLIssuerCountry string     `json:"ssl_issuer_country" db:"ssl_issuer_country"`
	SSLValidFrom     *time.Time `json:"ssl_valid_from" db:"ssl_valid_from"`
	SSLValidTo       *time.Time `json:"ssl_valid_to" db:"ssl_valid_to"`
	SSLSubject       string     `json:"ssl_subject" db:"ssl_subject"`
	SSLFingerprint   string     `json:"ssl_fingerprint" db:"ssl_fingerprint"`
	SSLKeySize       int        `json:"ssl_key_size" db:"ssl_key_size"`
	SSLSignatureAlgo string     `json:"ssl_signature_algo" db:"ssl_signature_algo"`

	// Host Info
	HostCountry string  `json:"host_country" db:"host_country"`
	HostRegion  string  `json:"host_region" db:"host_region"`
	HostCity    string  `json:"host_city" db:"host_city"`
	HostISP     string  `json:"host_isp" db:"host_isp"`
	HostOrg     string  `json:"host_org" db:"host_org"`
	HostAS      string  `json:"host_as" db:"host_as"`
	HostLat     float64 `json:"host_lat" db:"host_lat"`
	HostLon     float64 `json:"host_lon" db:"host_lon"`

	// Valuation
	PurchasePrice float64 `json:"purchase_price" db:"purchase_price"`
	CurrentValue  float64 `json:"current_value" db:"current_value"`
	RenewalCost   float64 `json:"renewal_cost" db:"renewal_cost"`
	AutoRenew     bool    `json:"auto_renew" db:"auto_renew"`

	// Registrant Contact (from WHOIS)
	RegistrantName    string `json:"registrant_name" db:"registrant_name"`
	RegistrantOrg     string `json:"registrant_org" db:"registrant_org"`
	RegistrantStreet  string `json:"registrant_street" db:"registrant_street"`
	RegistrantCity    string `json:"registrant_city" db:"registrant_city"`
	RegistrantState   string `json:"registrant_state" db:"registrant_state"`
	RegistrantCountry string `json:"registrant_country" db:"registrant_country"`
	RegistrantPostal  string `json:"registrant_postal" db:"registrant_postal"`

	// Abuse Contact (from WHOIS)
	AbuseEmail string `json:"abuse_email" db:"abuse_email"`
	AbusePhone string `json:"abuse_phone" db:"abuse_phone"`

	// Metadata
	Tags       []string `json:"tags" db:"tags"`
	Notes      string   `json:"notes" db:"notes"`
	FaviconURL string   `json:"favicon_url" db:"favicon_url"`

	// Ownership
	UserID      string    `json:"user" db:"user"`
	Created     time.Time `json:"created" db:"created"`
	Updated     time.Time `json:"updated" db:"updated"`
	LastChecked time.Time `json:"last_checked" db:"last_checked"`

	// Alert settings
	AlertDaysBefore int  `json:"alert_days_before" db:"alert_days_before"` // Days before expiry to alert
	SSLAlertEnabled bool `json:"ssl_alert_enabled" db:"ssl_alert_enabled"`
}

// DomainHistory tracks changes to a domain over time
type DomainHistory struct {
	ID         string    `json:"id" db:"id"`
	DomainID   string    `json:"domain" db:"domain"`
	ChangeType string    `json:"change_type" db:"change_type"` // expiry, ssl, dns, registrar, ip, etc.
	FieldName  string    `json:"field_name" db:"field_name"`
	OldValue   string    `json:"old_value" db:"old_value"`
	NewValue   string    `json:"new_value" db:"new_value"`
	UserID     string    `json:"user" db:"user"`
	CreatedAt  time.Time `json:"created_at" db:"created_at"`
}

// WHOISData represents parsed WHOIS information
type WHOISData struct {
	DomainName string         `json:"domain_name"`
	Status     []string       `json:"status"`
	DNSSEC     string         `json:"dnssec"`
	Dates      WHOISDates     `json:"dates"`
	Registrar  WHOISRegistrar `json:"registrar"`
	Registrant WHOISContact   `json:"registrant"`
	Abuse      WHOISAbuse     `json:"abuse"`
}

type WHOISDates struct {
	ExpiryDate   *time.Time `json:"expiry_date"`
	CreationDate *time.Time `json:"creation_date"`
	UpdatedDate  *time.Time `json:"updated_date"`
}

type WHOISRegistrar struct {
	Name             string `json:"name"`
	ID               string `json:"id"`
	URL              string `json:"url"`
	RegistryDomainID string `json:"registry_domain_id"`
}

type WHOISContact struct {
	Name         string `json:"name"`
	Organization string `json:"organization"`
	Street       string `json:"street"`
	City         string `json:"city"`
	State        string `json:"state"`
	Country      string `json:"country"`
	PostalCode   string `json:"postal_code"`
}

type WHOISAbuse struct {
	Email string `json:"email"`
	Phone string `json:"phone"`
}

// SSLInfo represents SSL certificate information
type SSLInfo struct {
	Issuer        string    `json:"issuer"`
	IssuerCountry string    `json:"issuer_country"`
	ValidFrom     time.Time `json:"valid_from"`
	ValidTo       time.Time `json:"valid_to"`
	Subject       string    `json:"subject"`
	Fingerprint   string    `json:"fingerprint"`
	KeySize       int       `json:"key_size"`
	SignatureAlgo string    `json:"signature_algo"`
}

// DNSInfo represents DNS records
type DNSInfo struct {
	NameServers []string `json:"name_servers"`
	MXRecords   []string `json:"mx_records"`
	TXTRecords  []string `json:"txt_records"`
	DNSSEC      string   `json:"dnssec"`
}

// HostInfo represents host/geolocation information
type HostInfo struct {
	Country  string  `json:"country"`
	Region   string  `json:"region"`
	City     string  `json:"city"`
	Lat      float64 `json:"lat"`
	Lon      float64 `json:"lon"`
	ISP      string  `json:"isp"`
	Org      string  `json:"org"`
	ASNumber string  `json:"as_number"`
}

// IPInfo represents IP address information
type IPInfo struct {
	IPv4 []string `json:"ipv4"`
	IPv6 []string `json:"ipv6"`
}

// ChangeType constants for domain history
const (
	ChangeTypeExpiry    = "expiry"
	ChangeTypeSSL       = "ssl"
	ChangeTypeDNS       = "dns"
	ChangeTypeRegistrar = "registrar"
	ChangeTypeIP        = "ip"
	ChangeTypeHost      = "host"
	ChangeTypeStatus    = "status"
)

// Domain status constants
const (
	DomainStatusActive   = "active"
	DomainStatusExpiring = "expiring" // Within alert_days_before
	DomainStatusExpired  = "expired"
	DomainStatusUnknown  = "unknown"
	DomainStatusPaused   = "paused"
)

// IsExpiring returns true if the domain is expiring within the alert window
func (d *Domain) IsExpiring() bool {
	if d.ExpiryDate == nil || d.AlertDaysBefore <= 0 {
		return false
	}
	alertDate := time.Now().AddDate(0, 0, d.AlertDaysBefore)
	return d.ExpiryDate.Before(alertDate) && d.ExpiryDate.After(time.Now())
}

// IsExpired returns true if the domain has expired
func (d *Domain) IsExpired() bool {
	if d.ExpiryDate == nil {
		return false
	}
	return d.ExpiryDate.Before(time.Now())
}

// DaysUntilExpiry returns the number of days until expiry
func (d *Domain) DaysUntilExpiry() int {
	if d.ExpiryDate == nil {
		return -1
	}
	return int(time.Until(*d.ExpiryDate).Hours() / 24)
}

// SSLDaysUntilExpiry returns days until SSL expiry
func (d *Domain) SSLDaysUntilExpiry() int {
	if d.SSLValidTo == nil {
		return -1
	}
	return int(time.Until(*d.SSLValidTo).Hours() / 24)
}

// GetStatus returns the current domain status
func (d *Domain) GetStatus() string {
	if !d.Active {
		return DomainStatusPaused
	}
	if d.IsExpired() {
		return DomainStatusExpired
	}
	if d.IsExpiring() {
		return DomainStatusExpiring
	}
	if d.ExpiryDate == nil {
		return DomainStatusUnknown
	}
	return DomainStatusActive
}
