package com.tiedup.remake.personality;

import org.jetbrains.annotations.Nullable;

/**
 * Commands that can be given to NPCs with collar (collar required).
 * All commands are always available - no training tier restrictions.
 */
public enum NpcCommand {
    /** No active command */
    NONE(CommandType.INSTANT, 1.0f),

    // --- Basic Commands ---
    /** Follow the master */
    FOLLOW(CommandType.CONTINUOUS, 0.75f),

    /** Stay in current position */
    STAY(CommandType.CONTINUOUS, 0.80f),

    /** Come to the master */
    COME(CommandType.INSTANT, 0.75f),

    /** Rest in place, speak idle dialogue */
    IDLE(CommandType.CONTINUOUS, 0.90f),

    /** Go to assigned home position */
    GO_HOME(CommandType.INSTANT, 0.85f),

    // --- Pose Commands ---
    /** Sit down */
    SIT(CommandType.INSTANT, 0.70f),

    // HEEL removed - now a FollowDistance mode for FOLLOW command

    /** Kneel position */
    KNEEL(CommandType.INSTANT, 0.60f),

    // --- Job Commands ---
    /** Patrol a defined zone */
    PATROL(CommandType.JOB, 0.65f),

    /** Guard a zone, alert on intruders */
    GUARD(CommandType.JOB, 0.60f),

    /** Pick up an item */
    FETCH(CommandType.INSTANT, 0.55f),

    /** Collect all items in a zone */
    COLLECT(CommandType.JOB, 0.50f),

    // --- Work Commands ---
    /** Farm crops in zone around chest hub */
    FARM(CommandType.JOB, 0.55f),

    /** Cook items using furnace, resources from chest hub */
    COOK(CommandType.JOB, 0.50f),

    /** Transfer items from chest A to chest B */
    TRANSFER(CommandType.JOB, 0.60f),

    /** Shear sheep in zone (requires shears in hand) */
    SHEAR(CommandType.JOB, 0.55f),

    /** Mine blocks in zone (requires pickaxe in hand) */
    MINE(CommandType.JOB, 0.50f),

    /** Breed animals in zone using food from chest hub */
    BREED(CommandType.JOB, 0.60f),

    /** Fish near water using simulated fishing */
    FISH(CommandType.JOB, 0.65f),

    /** Sort items between source and destination chests by category */
    SORT(CommandType.JOB, 0.60f);

    // NOTE: Combat commands (ATTACK, DEFEND, CAPTURE) have been removed.
    // Combat behavior is now determined by the item in the NPC's main hand
    // during FOLLOW command. See ToolMode enum and NpcFollowCommandGoal.

    /** Type of command execution */
    public enum CommandType {
        /** Executes once and completes */
        INSTANT,
        /** Continues until cancelled */
        CONTINUOUS,
        /** Has progress and completion state */
        JOB,
    }

    /**
     * Distance modes for FOLLOW command.
     * Allows configuring how closely the NPC follows.
     */
    public enum FollowDistance {
        /** Far following (6-10 blocks) - original FOLLOW behavior */
        FAR(2.0, 6.0, 10, 1200, 2, false),
        /** Close following (2-4 blocks) - moderate distance */
        CLOSE(1.5, 4.0, 8, 1000, 2, false),
        /** Heel position (1-2 blocks) - stays behind master */
        HEEL(0.8, 2.0, 5, 800, 3, true);

        /** Minimum distance to keep from master */
        public final double minDistance;
        /** Distance at which to start following */
        public final double startDistance;
        /** Ticks between path recalculations */
        public final int pathRecalcInterval;
        /** Ticks between XP awards */
        public final int xpInterval;
        /** XP awarded per interval */
        public final int xpAmount;
        /** Whether to follow behind master (heel behavior) */
        public final boolean followBehind;

        FollowDistance(
            double minDistance,
            double startDistance,
            int pathRecalcInterval,
            int xpInterval,
            int xpAmount,
            boolean followBehind
        ) {
            this.minDistance = minDistance;
            this.startDistance = startDistance;
            this.pathRecalcInterval = pathRecalcInterval;
            this.xpInterval = xpInterval;
            this.xpAmount = xpAmount;
            this.followBehind = followBehind;
        }

        /**
         * Get translation key for this distance mode.
         */
        public String getTranslationKey() {
            return "command.follow.distance." + this.name().toLowerCase();
        }
    }

    /** Command execution type */
    public final CommandType type;

    /** Base success chance (before modifiers) */
    public final float baseSuccessChance;

    NpcCommand(CommandType type, float baseSuccessChance) {
        this.type = type;
        this.baseSuccessChance = baseSuccessChance;
    }

    /**
     * Check if this command requires a target position.
     *
     * @return true if command needs BlockPos
     */
    public boolean requiresPosition() {
        return (
            this == PATROL ||
            this == GUARD ||
            this == COLLECT ||
            this == FARM ||
            this == COOK ||
            this == TRANSFER ||
            this == SHEAR ||
            this == BREED ||
            this == FISH ||
            this == SORT
        );
    }

    /**
     * Check if this command is a work command (uses chest-hub system).
     *
     * @return true if this is a work command
     */
    public boolean isWorkCommand() {
        return (
            this == FARM ||
            this == COOK ||
            this == TRANSFER ||
            this == SHEAR ||
            this == BREED ||
            this == FISH ||
            this == SORT
        );
    }

    /**
     * Check if this command is an active job that consumes rest.
     * Jobs that involve physical labor drain rest over time.
     *
     * @return true if this command drains rest
     */
    public boolean isActiveJob() {
        return this.type == CommandType.JOB;
    }

    /**
     * Check if this command requires a target entity.
     *
     * @return true if command needs entity target
     */
    public boolean requiresEntityTarget() {
        return this == FETCH;
    }

    /**
     * Get XP reward for successful completion.
     *
     * @return XP amount (1-10)
     */
    public int getCompletionXP() {
        return switch (this.type) {
            case INSTANT -> 2;
            case CONTINUOUS -> 2;
            case JOB -> 5;
        };
    }

    /**
     * Get localization key for this command.
     *
     * @return Translation key
     */
    public String getTranslationKey() {
        return "command." + this.name().toLowerCase();
    }

    /**
     * Parse command from string (case-insensitive).
     *
     * @param name Command name
     * @return NpcCommand or NONE if not found
     */
    public static NpcCommand fromString(@Nullable String name) {
        if (name == null || name.isEmpty()) return NONE;
        try {
            return valueOf(name.toUpperCase());
        } catch (IllegalArgumentException e) {
            return NONE;
        }
    }
}
