package com.openosrs.client.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

/**
 * NetworkState - Manages network connection state and statistics.
 * 
 * Tracks:
 * - Connection status
 * - Network statistics
 * - Latency and throughput
 */
public class NetworkState {
    private static final Logger logger = LoggerFactory.getLogger(NetworkState.class);
    
    private final EventSystem eventSystem;
    private final AtomicBoolean connected = new AtomicBoolean(false);
    private final AtomicLong bytesReceived = new AtomicLong(0);
    private final AtomicLong bytesSent = new AtomicLong(0);
    private final AtomicLong packetsReceived = new AtomicLong(0);
    private final AtomicLong packetsSent = new AtomicLong(0);
    private final AtomicLong lastPing = new AtomicLong(0);
    
    public NetworkState(EventSystem eventSystem) {
        this.eventSystem = eventSystem;
    }
    
    public void initialize() {
        logger.debug("NetworkState initialized");
    }
    
    public void shutdown() {
        setConnected(false);
        logger.debug("NetworkState shutdown");
    }
    
    public void tick() {
        // Network state updates would happen here
        // For now, this is a stub for things like latency monitoring
    }
    
    /**
     * Update connection status.
     */
    public void setConnected(boolean connected) {
        boolean wasConnected = this.connected.getAndSet(connected);
        if (wasConnected != connected) {
            logger.info("Network connection {}", connected ? "established" : "lost");
            eventSystem.fireNetworkStateChanged(connected);
        }
    }
    
    /**
     * Check if connected to the game server.
     */
    public boolean isConnected() {
        return connected.get();
    }
    
    /**
     * Record bytes received.
     */
    public void addBytesReceived(long bytes) {
        bytesReceived.addAndGet(bytes);
    }
    
    /**
     * Record bytes sent.
     */
    public void addBytesSent(long bytes) {
        bytesSent.addAndGet(bytes);
    }
    
    /**
     * Record packet received.
     */
    public void addPacketReceived() {
        packetsReceived.incrementAndGet();
    }
    
    /**
     * Record packet sent.
     */
    public void addPacketSent() {
        packetsSent.incrementAndGet();
    }
    
    /**
     * Update ping/latency.
     */
    public void updatePing(long pingMs) {
        lastPing.set(pingMs);
    }
    
    // Getters for statistics
    
    public long getBytesReceived() {
        return bytesReceived.get();
    }
    
    public long getBytesSent() {
        return bytesSent.get();
    }
    
    public long getPacketsReceived() {
        return packetsReceived.get();
    }
    
    public long getPacketsSent() {
        return packetsSent.get();
    }
    
    public long getLastPing() {
        return lastPing.get();
    }
    
    /**
     * Get network statistics summary.
     */
    public NetworkStats getStats() {
        return new NetworkStats(
            connected.get(),
            bytesReceived.get(),
            bytesSent.get(),
            packetsReceived.get(),
            packetsSent.get(),
            lastPing.get()
        );
    }
    
    /**
     * Network statistics data class.
     */
    public static class NetworkStats {
        private final boolean connected;
        private final long bytesReceived;
        private final long bytesSent;
        private final long packetsReceived;
        private final long packetsSent;
        private final long lastPing;
        
        public NetworkStats(boolean connected, long bytesReceived, long bytesSent,
                           long packetsReceived, long packetsSent, long lastPing) {
            this.connected = connected;
            this.bytesReceived = bytesReceived;
            this.bytesSent = bytesSent;
            this.packetsReceived = packetsReceived;
            this.packetsSent = packetsSent;
            this.lastPing = lastPing;
        }
        
        public boolean isConnected() { return connected; }
        public long getBytesReceived() { return bytesReceived; }
        public long getBytesSent() { return bytesSent; }
        public long getPacketsReceived() { return packetsReceived; }
        public long getPacketsSent() { return packetsSent; }
        public long getLastPing() { return lastPing; }
        
        @Override
        public String toString() {
            return String.format("NetworkStats{connected=%s, rx=%d bytes, tx=%d bytes, ping=%dms}", 
                connected, bytesReceived, bytesSent, lastPing);
        }
    }
}