package com.openosrs.client.api;

import com.openosrs.client.core.ClientCore;
import com.openosrs.client.core.PlayerState;
import com.openosrs.client.api.types.Position;
import com.openosrs.client.api.types.Skill;
import com.openosrs.client.core.bridge.BridgeAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * PlayerAPI - Provides access to player-specific information and state.
 *
 * This API module handles:
 * - Player position and movement
 * - Player stats (hitpoints, prayer, run energy)
 * - Skill levels and experience
 * - Combat state and animations
 */
public class PlayerAPI {
    private static final Logger logger = LoggerFactory.getLogger(PlayerAPI.class);

    private final ClientCore clientCore;
    private final PlayerState playerState;
    private final BridgeAdapter bridgeAdapter;

    public PlayerAPI(ClientCore clientCore, BridgeAdapter bridgeAdapter) {
        this.clientCore = clientCore;
        this.playerState = clientCore.getPlayerState();
        this.bridgeAdapter = bridgeAdapter;
    }

    /**
     * Get the player's current position.
     */
    public Position getPosition() {
        return bridgeAdapter.getPlayerPosition();
    }

    /**
     * Get the player's current hitpoints.
     */
    public int getHitpoints() {
        return bridgeAdapter.getSkillLevel(Skill.HITPOINTS);
    }

    /**
     * Get the player's maximum hitpoints.
     */
    public int getMaxHitpoints() {
        return bridgeAdapter.getSkillRealLevel(Skill.HITPOINTS);
    }

    /**
     * Get the player's current prayer points.
     */
    public int getPrayer() {
        return bridgeAdapter.getSkillLevel(Skill.PRAYER);
    }

    /**
     * Get the player's maximum prayer points.
     */
    public int getMaxPrayer() {
        return bridgeAdapter.getSkillRealLevel(Skill.PRAYER);
    }

    /**
     * Get the player's current run energy (0-100).
     */
    public int getRunEnergy() {
        return bridgeAdapter.getRunEnergy();
    }

    /**
     * Get the player's combat level.
     */
    public int getCombatLevel() {
        return playerState.getCombatLevel();
    }

    /**
     * Get a specific skill level (current level including temporary boosts/drains).
     */
    public int getSkillLevel(Skill skill) {
        return bridgeAdapter.getSkillLevel(skill);
    }

    /**
     * Get boosted skill level (same as getSkillLevel, for clarity).
     */
    public int getBoostedSkillLevel(Skill skill) {
        return bridgeAdapter.getSkillLevel(skill);
    }

    /**
     * Get the real/base skill level (without temporary boosts/drains).
     */
    public int getRealSkillLevel(Skill skill) {
        return bridgeAdapter.getSkillRealLevel(skill);
    }

    /**
     * Get skill experience.
     */
    public int getSkillExperience(Skill skill) {
        return bridgeAdapter.getSkillExperience(skill);
    }

    /**
     * Check if the player is currently in combat.
     */
    public boolean isInCombat() {
        return playerState.isInCombat();
    }

    /**
     * Get the player's current animation ID (-1 if no animation).
     */
    public int getCurrentAnimation() {
        return bridgeAdapter.getCurrentAnimation();
    }

    /**
     * Get the player's username.
     */
    public String getUsername() {
        return bridgeAdapter.getUsername();
    }

    /**
     * Check if the player is moving.
     */
    public boolean isMoving() {
        return bridgeAdapter.isMoving();
    }

    /**
     * Check if the player is idle (not animating, not moving).
     */
    public boolean isIdle() {
        return !isMoving() && getCurrentAnimation() == -1;
    }

    /**
     * Get the player's current facing direction (0-7).
     */
    public int getFacingDirection() {
        return playerState.getFacingDirection();
    }

    /**
     * Check if the player has run mode enabled.
     */
    public boolean isRunModeEnabled() {
        return playerState.isRunModeEnabled();
    }

    /**
     * Get the player's current overhead text (if any).
     */
    public String getOverheadText() {
        return playerState.getOverheadText();
    }

    /**
     * Get the player's total level (sum of all skills).
     */
    public int getTotalLevel() {
        int total = 0;
        for (Skill skill : Skill.values()) {
            total += getRealSkillLevel(skill);
        }
        return total;
    }

    /**
     * Check if the player is at a specific position.
     */
    public boolean isAtPosition(Position position) {
        Position currentPos = getPosition();
        return currentPos != null && currentPos.equals(position);
    }

    /**
     * Get the distance to a specific position.
     */
    public double getDistanceTo(Position position) {
        Position currentPos = getPosition();
        return currentPos != null ? currentPos.distanceTo(position) : Double.MAX_VALUE;
    }

    /**
     * Check if the player is within a certain distance of a position.
     */
    public boolean isWithinDistance(Position position, double maxDistance) {
        return getDistanceTo(position) <= maxDistance;
    }
}
