package p2p

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"sync"
	"time"

	"torrentGateway/internal/config"
	"torrentGateway/internal/dht"
	"torrentGateway/internal/tracker"

	"github.com/gorilla/mux"
)

// UnifiedP2PGateway coordinates all P2P systems
type UnifiedP2PGateway struct {
	// P2P Components
	tracker         *tracker.Tracker
	wsTracker       *tracker.WebSocketTracker
	dhtBootstrap    *dht.DHTBootstrap
	coordinator     *P2PCoordinator

	// Configuration
	config          *config.Config
	db              *sql.DB
	
	// Maintenance
	maintenanceTicker *time.Ticker
	healthTicker     *time.Ticker
	stopCh           chan struct{}
	
	// Caching for peer discovery
	peerCache        map[string]*CachedPeerResponse
	cacheMutex       sync.RWMutex
	cacheExpiry      time.Duration
	
	// Statistics
	stats            *P2PGatewayStats
	statsMutex       sync.RWMutex
}

// CachedPeerResponse represents a cached peer discovery response
type CachedPeerResponse struct {
	Peers      []UnifiedPeer `json:"peers"`
	CachedAt   time.Time     `json:"cached_at"`
	TTL        time.Duration `json:"ttl"`
	Sources    []string      `json:"sources"`
}

// UnifiedPeer represents a peer from any source
type UnifiedPeer struct {
	ID           string    `json:"id"`
	IP           string    `json:"ip"`
	Port         int       `json:"port"`
	Source       string    `json:"source"` // "tracker", "dht", "websocket"
	Quality      int       `json:"quality"`
	IsSeeder     bool      `json:"is_seeder"`
	LastSeen     time.Time `json:"last_seen"`
	Endpoint     string    `json:"endpoint,omitempty"`
	Protocol     string    `json:"protocol,omitempty"` // "webrtc", "http", "webseed"
	Reliability  float64   `json:"reliability,omitempty"`
	RTT          int       `json:"rtt_ms,omitempty"`
}

// P2PGatewayStats tracks comprehensive P2P statistics
type P2PGatewayStats struct {
	TotalTorrents      int64                    `json:"total_torrents"`
	ActiveTorrents     int64                    `json:"active_torrents"`
	TotalPeers         int64                    `json:"total_peers"`
	TrackerPeers       int64                    `json:"tracker_peers"`
	DHTNodes           int64                    `json:"dht_nodes"`
	WebSocketPeers     int64                    `json:"websocket_peers"`
	AnnouncesSent      int64                    `json:"announces_sent"`
	AnnouncesReceived  int64                    `json:"announces_received"`
	HealthStatus       map[string]string        `json:"health_status"`
	LastMaintenance    time.Time                `json:"last_maintenance"`
	LastHealthCheck    time.Time                `json:"last_health_check"`
	SystemHealth       string                   `json:"system_health"`
	ComponentStats     map[string]interface{}   `json:"component_stats"`
}

// TorrentInfo is defined in coordinator.go

// NewUnifiedP2PGateway creates a new unified P2P gateway
func NewUnifiedP2PGateway(config *config.Config, db *sql.DB) *UnifiedP2PGateway {
	gateway := &UnifiedP2PGateway{
		config:      config,
		db:          db,
		peerCache:   make(map[string]*CachedPeerResponse),
		cacheExpiry: 2 * time.Minute, // Cache peer responses for 2 minutes
		stopCh:      make(chan struct{}),
		stats: &P2PGatewayStats{
			HealthStatus:   make(map[string]string),
			ComponentStats: make(map[string]interface{}),
			SystemHealth:   "starting",
		},
	}

	return gateway
}

// Initialize starts all P2P components and background tasks
func (g *UnifiedP2PGateway) Initialize() error {
	log.Printf("P2P Gateway: Initializing unified P2P system")

	// Initialize tracker
	if err := g.initializeTracker(); err != nil {
		return fmt.Errorf("failed to initialize tracker: %w", err)
	}

	// Initialize DHT
	if err := g.initializeDHT(); err != nil {
		return fmt.Errorf("failed to initialize DHT: %w", err)
	}

	// Initialize WebSocket tracker
	if err := g.initializeWebSocketTracker(); err != nil {
		return fmt.Errorf("failed to initialize WebSocket tracker: %w", err)
	}

	// Initialize P2P coordinator
	if err := g.initializeCoordinator(); err != nil {
		return fmt.Errorf("failed to initialize coordinator: %w", err)
	}

	// Start background tasks
	g.startBackgroundTasks()

	g.stats.SystemHealth = "healthy"
	log.Printf("P2P Gateway: Successfully initialized all P2P systems")

	return nil
}

// CreateTorrent creates a new torrent and announces it to all P2P systems
func (g *UnifiedP2PGateway) CreateTorrent(fileHash string) (*TorrentInfo, error) {
	log.Printf("P2P Gateway: Creating torrent for file %s", fileHash[:8])

	// Get file info from database - this is a simplified version
	// In production, you'd query the files table for name and size
	filename := "Unknown"
	var fileSize int64 = 0
	
	row := g.db.QueryRow("SELECT original_name, size FROM files WHERE hash = ?", fileHash)
	row.Scan(&filename, &fileSize) // Ignore error, use defaults

	// Create torrent metadata
	torrentInfo := &TorrentInfo{
		InfoHash:     fileHash,
		Name:         filename,
		Size:         fileSize,
		CreatedAt:    time.Now(),
		LastAnnounce: time.Now(),
		IsActive:     true,
	}

	// Store in database
	if err := g.storeTorrentInfo(torrentInfo); err != nil {
		log.Printf("P2P Gateway: Failed to store torrent info: %v", err)
	}

	// Announce to all P2P systems immediately
	if err := g.announceToAllSystems(torrentInfo); err != nil {
		log.Printf("P2P Gateway: Failed to announce to all systems: %v", err)
	}

	// Update statistics
	g.statsMutex.Lock()
	g.stats.TotalTorrents++
	g.stats.ActiveTorrents++
	g.statsMutex.Unlock()

	log.Printf("P2P Gateway: Successfully created and announced torrent %s", fileHash[:8])
	return torrentInfo, nil
}

// GetPeersHandler provides a unified peer discovery endpoint
func (g *UnifiedP2PGateway) GetPeersHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	infoHash := vars["infohash"]

	if len(infoHash) != 40 {
		http.Error(w, "Invalid infohash format", http.StatusBadRequest)
		return
	}

	// Check cache first
	g.cacheMutex.RLock()
	if cached, exists := g.peerCache[infoHash]; exists {
		if time.Since(cached.CachedAt) < cached.TTL {
			g.cacheMutex.RUnlock()
			w.Header().Set("Content-Type", "application/json")
			w.Header().Set("X-Cache", "HIT")
			json.NewEncoder(w).Encode(cached)
			return
		}
	}
	g.cacheMutex.RUnlock()

	// Cache miss - gather peers from all sources
	peers, sources, err := g.gatherPeersFromAllSources(infoHash)
	if err != nil {
		log.Printf("P2P Gateway: Failed to gather peers for %s: %v", infoHash[:8], err)
		http.Error(w, "Failed to gather peers", http.StatusInternalServerError)
		return
	}

	// Create response
	response := &CachedPeerResponse{
		Peers:    peers,
		CachedAt: time.Now(),
		TTL:      g.cacheExpiry,
		Sources:  sources,
	}

	// Update cache
	g.cacheMutex.Lock()
	g.peerCache[infoHash] = response
	g.cacheMutex.Unlock()

	// Send response
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("X-Cache", "MISS")
	json.NewEncoder(w).Encode(response)

	log.Printf("P2P Gateway: Returned %d peers from %v for %s", 
		len(peers), sources, infoHash[:8])
}

// GetStatsHandler returns comprehensive P2P statistics
func (g *UnifiedP2PGateway) GetStatsHandler(w http.ResponseWriter, r *http.Request) {
	g.updateStats()
	
	g.statsMutex.RLock()
	stats := *g.stats
	g.statsMutex.RUnlock()

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(stats)
}

// GetHealthHandler returns system health status
func (g *UnifiedP2PGateway) GetHealthHandler(w http.ResponseWriter, r *http.Request) {
	health := g.performHealthCheck()
	
	statusCode := http.StatusOK
	if health.SystemHealth != "healthy" {
		statusCode = http.StatusServiceUnavailable
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(statusCode)
	json.NewEncoder(w).Encode(health)
}

// Shutdown gracefully stops all P2P systems
func (g *UnifiedP2PGateway) Shutdown() error {
	log.Printf("P2P Gateway: Shutting down unified P2P system")

	close(g.stopCh)

	if g.maintenanceTicker != nil {
		g.maintenanceTicker.Stop()
	}
	if g.healthTicker != nil {
		g.healthTicker.Stop()
	}

	// Shutdown components
	if g.coordinator != nil {
		g.coordinator.Stop()
	}
	if g.dhtBootstrap != nil {
		g.dhtBootstrap.Stop()
	}

	g.stats.SystemHealth = "shutdown"
	log.Printf("P2P Gateway: Shutdown complete")

	return nil
}

// RegisterRoutes registers all P2P endpoints
func (g *UnifiedP2PGateway) RegisterRoutes(router *mux.Router) {
	// Peer discovery endpoint
	router.HandleFunc("/api/peers/{infohash}", g.GetPeersHandler).Methods("GET")
	
	// Statistics endpoint
	router.HandleFunc("/api/p2p/stats", g.GetStatsHandler).Methods("GET")
	
	// Health check endpoint
	router.HandleFunc("/api/p2p/health", g.GetHealthHandler).Methods("GET")
	
	// WebSocket tracker endpoint (if WebSocket tracker is available)
	if g.wsTracker != nil {
		router.HandleFunc("/ws/tracker", g.wsTracker.HandleWS)
	}

	log.Printf("P2P Gateway: Registered API endpoints")
}

// ============ GATEWAY INTERFACE METHODS ============

// DHT Bootstrap Gateway interface methods

// GetPublicURL returns the public URL for this gateway
func (g *UnifiedP2PGateway) GetPublicURL() string {
	// Try to get from config, fall back to localhost
	if g.config.Gateway.PublicURL != "" {
		return g.config.Gateway.PublicURL
	}
	return fmt.Sprintf("http://localhost:%d", g.config.Gateway.Port)
}

// GetDHTPort returns the DHT port
func (g *UnifiedP2PGateway) GetDHTPort() int {
	return g.config.DHT.Port
}

// GetDatabase returns the database connection
func (g *UnifiedP2PGateway) GetDatabase() *sql.DB {
	return g.db
}

// GetAllTorrentHashes returns all torrent hashes from the database
func (g *UnifiedP2PGateway) GetAllTorrentHashes() []string {
	rows, err := g.db.Query("SELECT info_hash FROM p2p_torrents WHERE is_active = 1")
	if err != nil {
		log.Printf("P2P Gateway: Failed to get torrent hashes: %v", err)
		return []string{}
	}
	defer rows.Close()
	
	var hashes []string
	for rows.Next() {
		var hash string
		if err := rows.Scan(&hash); err == nil {
			hashes = append(hashes, hash)
		}
	}
	return hashes
}

// Coordinator Gateway interface methods

// WebSeedPeer returns a PeerInfo for the WebSeed
func (g *UnifiedP2PGateway) WebSeedPeer() PeerInfo {
	return PeerInfo{
		IP:       "127.0.0.1", // Local WebSeed
		Port:     g.config.Gateway.Port,
		PeerID:   "WEBSEED",
		Source:   "webseed",
		Quality:  100, // Highest quality
		LastSeen: time.Now(),
	}
}

// EnableWebSeed enables WebSeed for a torrent
func (g *UnifiedP2PGateway) EnableWebSeed(infoHash string) error {
	log.Printf("P2P Gateway: Enabling WebSeed for %s", infoHash[:8])
	// In a full implementation, this would configure WebSeed URLs
	return nil
}

// PublishToNostr publishes torrent to Nostr (placeholder)
func (g *UnifiedP2PGateway) PublishToNostr(torrent *TorrentInfo) error {
	log.Printf("P2P Gateway: Publishing torrent %s to Nostr", torrent.InfoHash[:8])
	// Placeholder - would integrate with actual Nostr publisher
	return nil
}

// GetPort returns the gateway port
func (g *UnifiedP2PGateway) GetPort() int {
	return g.config.Gateway.Port
}

// GetDHTBootstrap returns the DHT bootstrap instance
func (g *UnifiedP2PGateway) GetDHTBootstrap() *dht.DHTBootstrap {
	return g.dhtBootstrap
}

// GetPeers returns peers for a given infohash from all sources
func (g *UnifiedP2PGateway) GetPeers(infoHash string) ([]UnifiedPeer, error) {
	if g.coordinator == nil {
		return []UnifiedPeer{}, fmt.Errorf("P2P coordinator not initialized")
	}
	
	// Get peers from all sources
	peers, _, err := g.gatherPeersFromAllSources(infoHash)
	return peers, err
}

// GetStats returns comprehensive P2P statistics
func (g *UnifiedP2PGateway) GetStats() (map[string]interface{}, error) {
	if g.stats == nil {
		return map[string]interface{}{}, fmt.Errorf("stats not initialized")
	}
	
	// Return current stats
	stats := make(map[string]interface{})
	stats["timestamp"] = time.Now().Format(time.RFC3339)
	stats["health_status"] = g.stats.HealthStatus
	stats["component_stats"] = g.stats.ComponentStats
	stats["system_health"] = g.stats.SystemHealth
	
	return stats, nil
}

// ============ INITIALIZATION METHODS ============

func (g *UnifiedP2PGateway) initializeTracker() error {
	log.Printf("P2P Gateway: Initializing HTTP tracker")
	
	// Note: This is a simplified tracker initialization for P2P gateway
	// In production, you would pass proper config and gateway interface
	log.Printf("P2P Gateway: Tracker initialization skipped - using external tracker")
	
	g.stats.HealthStatus["tracker"] = "external"
	return nil
}

func (g *UnifiedP2PGateway) initializeDHT() error {
	log.Printf("P2P Gateway: Initializing DHT")
	
	// First create DHT node
	dhtNode, err := dht.NewDHT(&g.config.DHT)
	if err != nil {
		return fmt.Errorf("failed to create DHT node: %w", err)
	}
	
	// Then create DHT bootstrap with the node
	g.dhtBootstrap = dht.NewDHTBootstrap(dhtNode, g, &g.config.DHT)
	
	// Initialize the bootstrap functionality
	if err := g.dhtBootstrap.Initialize(); err != nil {
		return fmt.Errorf("failed to initialize DHT bootstrap: %w", err)
	}

	g.stats.HealthStatus["dht"] = "healthy"
	return nil
}

func (g *UnifiedP2PGateway) initializeWebSocketTracker() error {
	log.Printf("P2P Gateway: Initializing WebSocket tracker")
	
	g.wsTracker = tracker.NewWebSocketTracker(g.tracker)
	g.wsTracker.StartCleanup()

	g.stats.HealthStatus["websocket"] = "healthy"
	return nil
}

func (g *UnifiedP2PGateway) initializeCoordinator() error {
	log.Printf("P2P Gateway: Initializing P2P coordinator")
	
	g.coordinator = NewCoordinator(g, g.tracker, g.dhtBootstrap)

	g.stats.HealthStatus["coordinator"] = "healthy"
	return nil
}

// ============ BACKGROUND MAINTENANCE TASKS ============

func (g *UnifiedP2PGateway) startBackgroundTasks() {
	log.Printf("P2P Gateway: Starting background maintenance tasks")

	// Maintenance tasks every 5 minutes
	g.maintenanceTicker = time.NewTicker(5 * time.Minute)
	go g.maintenanceLoop()

	// Health checks every minute
	g.healthTicker = time.NewTicker(1 * time.Minute)
	go g.healthCheckLoop()

	// Periodic DHT announces every 15 minutes
	go g.periodicAnnounceLoop()
}

func (g *UnifiedP2PGateway) maintenanceLoop() {
	for {
		select {
		case <-g.stopCh:
			return
		case <-g.maintenanceTicker.C:
			g.performMaintenance()
		}
	}
}

func (g *UnifiedP2PGateway) healthCheckLoop() {
	for {
		select {
		case <-g.stopCh:
			return
		case <-g.healthTicker.C:
			g.performHealthCheck()
		}
	}
}

func (g *UnifiedP2PGateway) periodicAnnounceLoop() {
	ticker := time.NewTicker(15 * time.Minute)
	defer ticker.Stop()

	for {
		select {
		case <-g.stopCh:
			return
		case <-ticker.C:
			g.performPeriodicAnnounces()
		}
	}
}

func (g *UnifiedP2PGateway) performMaintenance() {
	log.Printf("P2P Gateway: Performing maintenance tasks")
	
	g.statsMutex.Lock()
	g.stats.LastMaintenance = time.Now()
	g.statsMutex.Unlock()

	// Clean up expired peers from all systems
	g.cleanupExpiredPeers()
	
	// Verify WebSeeds are accessible
	g.verifyWebSeeds()
	
	// Clean up peer cache
	g.cleanupPeerCache()
	
	// Update statistics
	g.updateStats()

	log.Printf("P2P Gateway: Maintenance tasks completed")
}

func (g *UnifiedP2PGateway) cleanupExpiredPeers() {
	// Clean up tracker peers
	if g.tracker != nil {
		// Note: cleanupExpiredPeers is a private method, can't call directly
		log.Printf("P2P Gateway: Tracker cleanup skipped (private method)")
	}

	// Clean up DHT peers
	if g.dhtBootstrap != nil && g.dhtBootstrap.GetNode() != nil {
		// DHT cleanup is handled internally by the node
	}

	// WebSocket tracker cleanup is handled by its own ticker
}

func (g *UnifiedP2PGateway) verifyWebSeeds() {
	// Get all active torrents with WebSeeds
	torrents, err := g.getActiveTorrentsWithWebSeeds()
	if err != nil {
		log.Printf("P2P Gateway: Failed to get torrents for WebSeed verification: %v", err)
		return
	}

	verifiedCount := 0
	failedCount := 0

	for _, torrent := range torrents {
		if torrent.WebSeedURL != "" {
			if g.verifyWebSeedURL(torrent.WebSeedURL) {
				verifiedCount++
			} else {
				failedCount++
				log.Printf("P2P Gateway: WebSeed verification failed for %s: %s", 
					torrent.InfoHash[:8], torrent.WebSeedURL)
			}
		}
	}

	if verifiedCount > 0 || failedCount > 0 {
		log.Printf("P2P Gateway: WebSeed verification completed: %d verified, %d failed", 
			verifiedCount, failedCount)
	}
}

func (g *UnifiedP2PGateway) verifyWebSeedURL(url string) bool {
	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Head(url)
	if err != nil {
		return false
	}
	defer resp.Body.Close()
	
	return resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusPartialContent
}

func (g *UnifiedP2PGateway) cleanupPeerCache() {
	g.cacheMutex.Lock()
	defer g.cacheMutex.Unlock()

	now := time.Now()
	cleanedCount := 0

	for infoHash, cached := range g.peerCache {
		if now.Sub(cached.CachedAt) > cached.TTL {
			delete(g.peerCache, infoHash)
			cleanedCount++
		}
	}

	if cleanedCount > 0 {
		log.Printf("P2P Gateway: Cleaned %d expired peer cache entries", cleanedCount)
	}
}

func (g *UnifiedP2PGateway) performPeriodicAnnounces() {
	log.Printf("P2P Gateway: Performing periodic announces for all torrents")

	torrents, err := g.getAllActiveTorrents()
	if err != nil {
		log.Printf("P2P Gateway: Failed to get active torrents for periodic announces: %v", err)
		return
	}

	announceCount := 0
	for _, torrent := range torrents {
		if err := g.announceToAllSystems(torrent); err != nil {
			log.Printf("P2P Gateway: Failed to announce %s: %v", torrent.InfoHash[:8], err)
		} else {
			announceCount++
		}
	}

	g.statsMutex.Lock()
	g.stats.AnnouncesSent += int64(announceCount)
	g.statsMutex.Unlock()

	log.Printf("P2P Gateway: Completed periodic announces for %d torrents", announceCount)
}

// ============ HEALTH CHECK SYSTEM ============

func (g *UnifiedP2PGateway) performHealthCheck() *P2PGatewayStats {
	g.statsMutex.Lock()
	g.stats.LastHealthCheck = time.Now()
	
	// Check DHT health
	if g.dhtBootstrap != nil && g.dhtBootstrap.GetNode() != nil {
		dhtStats := g.dhtBootstrap.GetDHTStats()
		if nodeCount, ok := dhtStats["routing_table_size"].(int); ok && nodeCount > 0 {
			g.stats.HealthStatus["dht"] = "healthy"
		} else {
			g.stats.HealthStatus["dht"] = "degraded"
		}
	} else {
		g.stats.HealthStatus["dht"] = "failed"
	}

	// Check tracker health
	if g.tracker != nil {
		trackerStats := g.tracker.GetStats()
		if peerCount, ok := trackerStats["peers"].(int64); ok && peerCount >= 0 {
			g.stats.HealthStatus["tracker"] = "healthy"
		} else {
			g.stats.HealthStatus["tracker"] = "degraded"
		}
	} else {
		g.stats.HealthStatus["tracker"] = "failed"
	}

	// Check WebSocket tracker health
	if g.wsTracker != nil {
		wsStats := g.wsTracker.GetStats()
		if peers, ok := wsStats["total_peers"].(int); ok && peers >= 0 {
			g.stats.HealthStatus["websocket"] = "healthy"
		} else {
			g.stats.HealthStatus["websocket"] = "degraded"
		}
	} else {
		g.stats.HealthStatus["websocket"] = "failed"
	}

	// Determine overall system health
	healthyComponents := 0
	totalComponents := len(g.stats.HealthStatus)
	
	for _, status := range g.stats.HealthStatus {
		if status == "healthy" {
			healthyComponents++
		}
	}

	if healthyComponents == totalComponents {
		g.stats.SystemHealth = "healthy"
	} else if healthyComponents > totalComponents/2 {
		g.stats.SystemHealth = "degraded"
	} else {
		g.stats.SystemHealth = "critical"
	}

	stats := *g.stats
	g.statsMutex.Unlock()
	
	return &stats
}

// ============ PEER DISCOVERY AND COORDINATION ============

func (g *UnifiedP2PGateway) gatherPeersFromAllSources(infoHash string) ([]UnifiedPeer, []string, error) {
	var allPeers []UnifiedPeer
	var sources []string

	// Get peers from HTTP tracker
	if g.tracker != nil {
		trackerPeers, err := g.tracker.GetPeersForTorrent(infoHash)
		if err == nil && len(trackerPeers) > 0 {
			for _, peer := range trackerPeers {
				unifiedPeer := UnifiedPeer{
					ID:          peer.PeerID,
					IP:          peer.IP,
					Port:        peer.Port,
					Source:      "tracker",
					Quality:     peer.Priority,
					IsSeeder:    peer.IsSeeder || peer.Left == 0,
					LastSeen:    peer.LastSeen,
					Protocol:    "http",
					Reliability: calculateReliability(peer),
				}
				
				if peer.IsWebSeed {
					unifiedPeer.Protocol = "webseed"
					unifiedPeer.Endpoint = fmt.Sprintf("http://localhost:%d/webseed/%s", g.config.Gateway.Port, infoHash)
					unifiedPeer.Quality = 100 // WebSeeds get highest quality
				}
				
				allPeers = append(allPeers, unifiedPeer)
			}
			sources = append(sources, "tracker")
		}
	}

	// Get peers from DHT
	if g.dhtBootstrap != nil && g.dhtBootstrap.GetNode() != nil {
		dhtPeers := g.coordinator.getDHTPeers(infoHash)
		if len(dhtPeers) > 0 {
			for _, peer := range dhtPeers {
				unifiedPeer := UnifiedPeer{
					ID:       peer.PeerID,
					IP:       peer.IP,
					Port:     peer.Port,
					Source:   "dht",
					Quality:  peer.Quality,
					LastSeen: peer.LastSeen,
					Protocol: "http",
				}
				allPeers = append(allPeers, unifiedPeer)
			}
			sources = append(sources, "dht")
		}
	}

	// Get peers from WebSocket tracker
	if g.wsTracker != nil {
		wsStats := g.wsTracker.GetStats()
		// Note: WebSocket tracker doesn't have a direct GetPeers method
		// This would need to be implemented based on the swarm structure
		if totalPeers, ok := wsStats["total_peers"].(int); ok && totalPeers > 0 {
			sources = append(sources, "websocket")
		}
	}

	return allPeers, sources, nil
}

func (g *UnifiedP2PGateway) announceToAllSystems(torrent *TorrentInfo) error {
	var errors []error

	// Announce to HTTP tracker
	if g.tracker != nil {
		if err := g.announceToTracker(torrent); err != nil {
			errors = append(errors, fmt.Errorf("tracker announce failed: %w", err))
		}
	}

	// Announce to DHT
	if g.dhtBootstrap != nil {
		if err := g.announceToDHT(torrent); err != nil {
			errors = append(errors, fmt.Errorf("DHT announce failed: %w", err))
		}
	}

	// Update last announce time
	torrent.LastAnnounce = time.Now()
	if err := g.updateTorrentInfo(torrent); err != nil {
		errors = append(errors, fmt.Errorf("failed to update torrent info: %w", err))
	}

	if len(errors) > 0 {
		return fmt.Errorf("announce errors: %v", errors)
	}

	return nil
}

func (g *UnifiedP2PGateway) announceToTracker(torrent *TorrentInfo) error {
	// This would integrate with the tracker's announce system
	log.Printf("P2P Gateway: Announced %s to HTTP tracker", torrent.InfoHash[:8])
	return nil
}

func (g *UnifiedP2PGateway) announceToDHT(torrent *TorrentInfo) error {
	if g.dhtBootstrap != nil {
		g.dhtBootstrap.AnnounceNewTorrent(torrent.InfoHash, g.config.DHT.Port)
		log.Printf("P2P Gateway: Announced %s to DHT", torrent.InfoHash[:8])
	}
	return nil
}

// ============ STATISTICS AND UTILITIES ============

func (g *UnifiedP2PGateway) updateStats() {
	g.statsMutex.Lock()
	defer g.statsMutex.Unlock()

	// Update component statistics
	if g.tracker != nil {
		g.stats.ComponentStats["tracker"] = g.tracker.GetStats()
	}
	
	if g.dhtBootstrap != nil {
		g.stats.ComponentStats["dht"] = g.dhtBootstrap.GetDHTStats()
	}
	
	if g.wsTracker != nil {
		g.stats.ComponentStats["websocket"] = g.wsTracker.GetStats()
	}

	// Calculate total counts
	g.stats.TotalPeers = 0
	if trackerStats, ok := g.stats.ComponentStats["tracker"].(map[string]interface{}); ok {
		if peers, ok := trackerStats["peers"].(int64); ok {
			g.stats.TrackerPeers = peers
			g.stats.TotalPeers += peers
		}
	}

	if dhtStats, ok := g.stats.ComponentStats["dht"].(map[string]interface{}); ok {
		if nodes, ok := dhtStats["routing_table_size"].(int); ok {
			g.stats.DHTNodes = int64(nodes)
		}
	}

	if wsStats, ok := g.stats.ComponentStats["websocket"].(map[string]interface{}); ok {
		if peers, ok := wsStats["total_peers"].(int); ok {
			g.stats.WebSocketPeers = int64(peers)
			g.stats.TotalPeers += int64(peers)
		}
	}
}

// Helper functions for database operations
func (g *UnifiedP2PGateway) storeTorrentInfo(torrent *TorrentInfo) error {
	query := `INSERT OR REPLACE INTO p2p_torrents (info_hash, name, size, created_at, last_announce, webseed_url, is_active)
			  VALUES (?, ?, ?, ?, ?, ?, ?)`
	_, err := g.db.Exec(query, torrent.InfoHash, torrent.Name, torrent.Size, 
		torrent.CreatedAt, torrent.LastAnnounce, torrent.WebSeedURL, torrent.IsActive)
	return err
}

func (g *UnifiedP2PGateway) updateTorrentInfo(torrent *TorrentInfo) error {
	query := `UPDATE p2p_torrents SET last_announce = ?, is_active = ? WHERE info_hash = ?`
	_, err := g.db.Exec(query, torrent.LastAnnounce, torrent.IsActive, torrent.InfoHash)
	return err
}

func (g *UnifiedP2PGateway) getAllActiveTorrents() ([]*TorrentInfo, error) {
	query := `SELECT info_hash, name, size, created_at, last_announce, webseed_url, is_active 
			  FROM p2p_torrents WHERE is_active = 1`
	rows, err := g.db.Query(query)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var torrents []*TorrentInfo
	for rows.Next() {
		var torrent TorrentInfo
		var webSeedURL sql.NullString
		err := rows.Scan(&torrent.InfoHash, &torrent.Name, &torrent.Size, 
			&torrent.CreatedAt, &torrent.LastAnnounce, &webSeedURL, &torrent.IsActive)
		if err != nil {
			continue
		}
		if webSeedURL.Valid {
			torrent.WebSeedURL = webSeedURL.String
		}
		torrents = append(torrents, &torrent)
	}

	return torrents, nil
}

func (g *UnifiedP2PGateway) getActiveTorrentsWithWebSeeds() ([]*TorrentInfo, error) {
	query := `SELECT info_hash, name, size, created_at, last_announce, webseed_url, is_active 
			  FROM p2p_torrents WHERE is_active = 1 AND webseed_url IS NOT NULL AND webseed_url != ''`
	rows, err := g.db.Query(query)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var torrents []*TorrentInfo
	for rows.Next() {
		var torrent TorrentInfo
		err := rows.Scan(&torrent.InfoHash, &torrent.Name, &torrent.Size, 
			&torrent.CreatedAt, &torrent.LastAnnounce, &torrent.WebSeedURL, &torrent.IsActive)
		if err != nil {
			continue
		}
		torrents = append(torrents, &torrent)
	}

	return torrents, nil
}

func calculateReliability(peer *tracker.PeerInfo) float64 {
	// Calculate reliability based on various factors
	reliability := 0.5 // Base reliability
	
	if peer.IsWebSeed {
		return 1.0 // WebSeeds are most reliable
	}
	
	if peer.IsSeeder {
		reliability += 0.3
	}
	
	if peer.Priority > 50 {
		reliability += 0.2
	}
	
	// Recent activity bonus
	if time.Since(peer.LastSeen) < 10*time.Minute {
		reliability += 0.2
	}
	
	if reliability > 1.0 {
		reliability = 1.0
	}
	
	return reliability
}

// CreateP2PTables creates the necessary database tables for P2P coordination
func (g *UnifiedP2PGateway) CreateP2PTables() error {
	query := `
	CREATE TABLE IF NOT EXISTS p2p_torrents (
		info_hash TEXT PRIMARY KEY,
		name TEXT NOT NULL,
		size INTEGER NOT NULL,
		created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
		last_announce DATETIME DEFAULT CURRENT_TIMESTAMP,
		webseed_url TEXT,
		is_active BOOLEAN DEFAULT 1
	);

	CREATE INDEX IF NOT EXISTS idx_p2p_torrents_active ON p2p_torrents(is_active);
	CREATE INDEX IF NOT EXISTS idx_p2p_torrents_last_announce ON p2p_torrents(last_announce);
	`
	
	_, err := g.db.Exec(query)
	return err
}