// File Path: monorepo/cloud/maplepress-backend/internal/domain/site/site.go
package site

import (
	"time"

	"github.com/gocql/gocql"
)

// Site represents a WordPress site registered in the system
type Site struct {
	// Core Identity
	ID       gocql.UUID `json:"id"`
	TenantID gocql.UUID `json:"tenant_id"`

	// Site Information
	SiteURL string `json:"site_url"` // Full URL: https://example.com
	Domain  string `json:"domain"`   // Extracted: example.com

	// Authentication
	APIKeyHash     string `json:"-"`                 // SHA-256 hash, never exposed in JSON
	APIKeyPrefix   string `json:"api_key_prefix"`    // "live_sk_a1b2" for display
	APIKeyLastFour string `json:"api_key_last_four"` // Last 4 chars for display

	// Status & Verification
	Status            string `json:"status"` // active, inactive, pending, suspended, archived
	IsVerified        bool   `json:"is_verified"`
	VerificationToken string `json:"-"` // Never exposed

	// Search & Indexing
	SearchIndexName   string    `json:"search_index_name"`
	TotalPagesIndexed int64     `json:"total_pages_indexed"` // All-time total for stats
	LastIndexedAt     time.Time `json:"last_indexed_at,omitempty"`

	// Plugin Info
	PluginVersion string `json:"plugin_version,omitempty"`

	// Usage Tracking (for billing) - no quotas/limits
	StorageUsedBytes    int64     `json:"storage_used_bytes"`    // Current storage usage
	SearchRequestsCount int64     `json:"search_requests_count"` // Monthly search count
	MonthlyPagesIndexed int64     `json:"monthly_pages_indexed"` // Monthly indexing count
	LastResetAt         time.Time `json:"last_reset_at"`         // Last monthly reset

	// Metadata (optional fields)
	Language string `json:"language,omitempty"` // ISO 639-1
	Timezone string `json:"timezone,omitempty"` // IANA timezone
	Notes    string `json:"notes,omitempty"`

	// Audit
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`

	// CWE-359: IP address tracking for GDPR compliance (90-day expiration)
	CreatedFromIPAddress    string    `json:"-"` // Encrypted IP address, never exposed in JSON
	CreatedFromIPTimestamp  time.Time `json:"-"` // For 90-day expiration tracking
	ModifiedFromIPAddress   string    `json:"-"` // Encrypted IP address, never exposed in JSON
	ModifiedFromIPTimestamp time.Time `json:"-"` // For 90-day expiration tracking
}

// Status constants
const (
	StatusPending   = "pending"   // Site created, awaiting verification
	StatusActive    = "active"    // Site verified and operational
	StatusInactive  = "inactive"  // User temporarily disabled
	StatusSuspended = "suspended" // Suspended due to violation or non-payment
	StatusArchived  = "archived"  // Soft deleted
)


// NewSite creates a new Site entity with defaults
func NewSite(tenantID gocql.UUID, domain, siteURL string, apiKeyHash, apiKeyPrefix, apiKeyLastFour string, encryptedIP string) *Site {
	now := time.Now()
	siteID := gocql.TimeUUID()

	return &Site{
		ID:                siteID,
		TenantID:          tenantID,
		Domain:            domain,
		SiteURL:           siteURL,
		APIKeyHash:        apiKeyHash,
		APIKeyPrefix:      apiKeyPrefix,
		APIKeyLastFour:    apiKeyLastFour,
		Status:            StatusPending,
		IsVerified:        false,
		VerificationToken: "", // Set by caller
		SearchIndexName:   "site_" + siteID.String(),
		TotalPagesIndexed: 0,
		PluginVersion:     "",

		// Usage tracking (no quotas/limits)
		StorageUsedBytes:    0,
		SearchRequestsCount: 0,
		MonthlyPagesIndexed: 0,
		LastResetAt:         now,

		Language:  "",
		Timezone:  "",
		Notes:     "",
		CreatedAt: now,
		UpdatedAt: now,

		// CWE-359: Encrypted IP address tracking for GDPR compliance
		CreatedFromIPAddress:    encryptedIP,
		CreatedFromIPTimestamp:  now,
		ModifiedFromIPAddress:   encryptedIP,
		ModifiedFromIPTimestamp: now,
	}
}

// IsActive checks if the site is active and verified
func (s *Site) IsActive() bool {
	return s.Status == StatusActive && s.IsVerified
}

// IsTestMode checks if the site is using a test API key
func (s *Site) IsTestMode() bool {
	// Check if API key prefix starts with "test_sk_"
	return len(s.APIKeyPrefix) >= 7 && s.APIKeyPrefix[:7] == "test_sk"
}

// RequiresVerification checks if the site requires verification
// Test mode sites skip verification for development
func (s *Site) RequiresVerification() bool {
	return !s.IsTestMode()
}

// CanAccessAPI checks if the site can access the API
// More lenient than IsActive - allows pending sites for initial setup
func (s *Site) CanAccessAPI() bool {
	// Allow active sites (fully verified)
	if s.Status == StatusActive {
		return true
	}
	// Allow pending sites (waiting for verification) for initial setup
	if s.Status == StatusPending {
		return true
	}
	// Block inactive, suspended, or archived sites
	return false
}


// IncrementSearchCount increments the search request counter
func (s *Site) IncrementSearchCount() {
	s.SearchRequestsCount++
	s.UpdatedAt = time.Now()
}

// IncrementPageCount increments the indexed page counter (lifetime total)
func (s *Site) IncrementPageCount() {
	s.TotalPagesIndexed++
	s.UpdatedAt = time.Now()
}

// IncrementMonthlyPageCount increments both lifetime and monthly page counters
func (s *Site) IncrementMonthlyPageCount(count int64) {
	s.TotalPagesIndexed += count
	s.MonthlyPagesIndexed += count
	s.LastIndexedAt = time.Now()
	s.UpdatedAt = time.Now()
}

// UpdateStorageUsed updates the storage usage
func (s *Site) UpdateStorageUsed(bytes int64) {
	s.StorageUsedBytes = bytes
	s.UpdatedAt = time.Now()
}

// Verify marks the site as verified
func (s *Site) Verify() {
	s.IsVerified = true
	s.Status = StatusActive
	s.VerificationToken = "" // Clear token after verification
	s.UpdatedAt = time.Now()
}

// ResetMonthlyUsage resets monthly usage counters for billing cycles
func (s *Site) ResetMonthlyUsage() {
	now := time.Now()

	// Reset usage counters (no quotas)
	s.SearchRequestsCount = 0
	s.MonthlyPagesIndexed = 0
	s.LastResetAt = now

	s.UpdatedAt = now
}
