package com.openosrs.client.core;

import com.openosrs.client.core.bridge.RuneLiteBridge;
import com.openosrs.client.core.bridge.BridgeAdapter;

import net.runelite.api.Client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ClientCore - Central hub for managing game state and core client functionality.
 *
 * This class maintains the essential game state that agents need access to:
 * - Player state and position
 * - World objects and NPCs
 * - Inventory and equipment
 * - Game settings and preferences
 *
 * All state is designed to be thread-safe for concurrent agent access.
 */
public class ClientCore {
    private static final Logger logger = LoggerFactory.getLogger(ClientCore.class);

    // Core state management
    private final AtomicBoolean initialized = new AtomicBoolean(false);
    private final AtomicInteger gameState = new AtomicInteger(GameStateConstants.STARTUP);

    // Game world state
    private final WorldState worldState;
    private final PlayerState playerState;
    private final InventoryState inventoryState;
    private final InterfaceState interfaceState;
    private final NetworkState networkState;
    private final LoginState loginState;
    private final LoginScreen loginScreen;

    // Bridge components for RuneLite integration
    private final RuneLiteBridge runeLiteBridge;
    private final BridgeAdapter bridgeAdapter;

    // Configuration and settings
    private final ClientConfiguration configuration;

    // Event system for notifying agents of state changes
    private final EventSystem eventSystem;

    public ClientCore() {
        logger.debug("Initializing ClientCore");

        this.configuration = new ClientConfiguration();
        this.eventSystem = new EventSystem();

        // Initialize bridge components
        this.runeLiteBridge = new RuneLiteBridge(this);
        this.bridgeAdapter = new BridgeAdapter(this, runeLiteBridge);

        // Initialize state managers
        this.worldState = new WorldState(eventSystem);
        this.playerState = new PlayerState(eventSystem);
        this.inventoryState = new InventoryState(eventSystem);
        this.interfaceState = new InterfaceState(eventSystem);
        this.networkState = new NetworkState(eventSystem);
        this.loginState = new LoginState(eventSystem);
        this.loginScreen = new LoginScreen(this);

        logger.debug("ClientCore components created");
    }

    /**
     * Initialize the client core and all subsystems.
     */
    public void initialize() {
        if (initialized.get()) {
            logger.warn("ClientCore already initialized");
            return;
        }

        logger.info("Initializing ClientCore subsystems");

        try {
            // Initialize configuration
            configuration.load();

            // Initialize state managers
            worldState.initialize();
            playerState.initialize();
            inventoryState.initialize();
            interfaceState.initialize();
            networkState.initialize();
            loginState.initialize();
            loginScreen.initialize();

            // Initialize event system
            eventSystem.initialize();

            setGameState(GameStateConstants.INITIALIZED);
            initialized.set(true);

            logger.info("ClientCore initialization complete");

        } catch (Exception e) {
            logger.error("Failed to initialize ClientCore", e);
            throw new RuntimeException("ClientCore initialization failed", e);
        }
    }

    /**
     * Shutdown the client core and clean up resources.
     */
    public void shutdown() {
        if (!initialized.get()) {
            logger.warn("ClientCore not initialized, nothing to shutdown");
            return;
        }

        logger.info("Shutting down ClientCore");

        try {
            setGameState(GameStateConstants.SHUTTING_DOWN);

            networkState.shutdown();
            interfaceState.shutdown();
            inventoryState.shutdown();
            playerState.shutdown();
            worldState.shutdown();
            loginState.shutdown();
            loginScreen.shutdown();
            eventSystem.shutdown();

            setGameState(GameStateConstants.SHUTDOWN);
            initialized.set(false);

            logger.info("ClientCore shutdown complete");

        } catch (Exception e) {
            logger.error("Error during ClientCore shutdown", e);
        }
    }

    /**
     * Update the game state and notify listeners.
     */
    public void setGameState(int newState) {
        int oldState = gameState.getAndSet(newState);
        if (oldState != newState) {
            logger.debug("Game state changed: {} -> {}", oldState, newState);
            eventSystem.fireGameStateChanged(oldState, newState);
        }
    }

    /**
     * Get the current game state.
     */
    public int getGameState() {
        return gameState.get();
    }

    /**
     * Check if the core is initialized and ready for use.
     */
    public boolean isInitialized() {
        return initialized.get();
    }

    // Accessors for state managers
    public WorldState getWorldState() { return worldState; }
    public PlayerState getPlayerState() { return playerState; }
    public InventoryState getInventoryState() { return inventoryState; }
    public InterfaceState getInterfaceState() { return interfaceState; }
    public NetworkState getNetworkState() { return networkState; }
    public LoginState getLoginState() { return loginState; }
    public LoginScreen getLoginScreen() { return loginScreen; }
    public ClientConfiguration getConfiguration() { return configuration; }
    public EventSystem getEventSystem() { return eventSystem; }

    // Bridge accessors
    public RuneLiteBridge getRuneLiteBridge() { return runeLiteBridge; }
    public BridgeAdapter getBridgeAdapter() { return bridgeAdapter; }

    /**
     * Perform a game tick update - called by the game engine.
     */
    public void tick() {
        if (!initialized.get()) {
            return;
        }

        try {
            // Update bridge from RuneLite if available
            if (runeLiteBridge.isActive()) {
                bridgeAdapter.updateFromBridge();
            }

            // Update all state managers
            worldState.tick();
            playerState.tick();
            inventoryState.tick();
            interfaceState.tick();
            networkState.tick();
            loginState.tick();

            // Fire tick event for agents
            eventSystem.fireGameTick();

        } catch (Exception e) {
            logger.error("Error during client core tick", e);
        }
    }

    /**
     * Constants for game states.
     */
    public static class GameStateConstants {
        public static final int STARTUP = 0;
        public static final int INITIALIZED = 1;
        public static final int CONNECTING = 2;
        public static final int CONNECTED = 3;
        public static final int LOGGED_IN = 4;
        public static final int IN_GAME = 5;
        public static final int LOGGING_OUT = 6;
        public static final int DISCONNECTED = 7;
        public static final int SHUTTING_DOWN = 8;
        public static final int SHUTDOWN = 9;
        public static final int ERROR = -1;
    }
}
