package com.tiedup.remake.entities.ai.trader.goals;

import com.tiedup.remake.cells.CellRegistryV2;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntitySlaveTrader;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.prison.PrisonerManager;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.AABB;

/**
 * Goal: Trader selling behavior.
 *
 * Simplified from TraderSellCaptiveGoal.
 * Detects potential buyers and initiates trade dialogue.
 *
 * Responsibilities:
 * - Detect players holding trade tokens nearby
 * - Look at and approach potential buyers
 * - Initiate trade dialogue
 */
public class TraderSellGoal extends Goal {

    private static final double DETECTION_RADIUS = 8.0;
    private static final double INTERACTION_DISTANCE = 4.0;
    private static final int PITCH_COOLDOWN = 100; // 5 seconds

    private final EntitySlaveTrader trader;

    private Player potentialBuyer;
    private int pitchCooldown = 0;
    private boolean hasGreeted = false;

    public TraderSellGoal(EntitySlaveTrader trader) {
        this.trader = trader;
        this.setFlags(EnumSet.of(Flag.LOOK));
    }

    @Override
    public boolean canUse() {
        if (trader.isTiedUp()) {
            return false;
        }
        if (trader.getTarget() != null) {
            return false;
        }
        if (!(trader.level() instanceof ServerLevel level)) {
            return false;
        }

        // Find potential buyer
        potentialBuyer = findTokenHolderNearby(level);
        if (potentialBuyer == null) {
            return false;
        }

        // Must have prisoners to sell
        if (!hasPrisonersToSell(level)) {
            return false;
        }

        return true;
    }

    /**
     * Find a player holding a trade token nearby.
     */
    private Player findTokenHolderNearby(ServerLevel level) {
        AABB searchBox = trader.getBoundingBox().inflate(DETECTION_RADIUS);
        List<Player> players = level.getEntitiesOfClass(
            Player.class,
            searchBox
        );

        for (Player player : players) {
            if (player.isSpectator()) continue;

            // Check for token in hands
            ItemStack mainHand = player.getMainHandItem();
            ItemStack offHand = player.getOffhandItem();

            if (isTradeToken(mainHand) || isTradeToken(offHand)) {
                return player;
            }
        }

        return null;
    }

    /**
     * Check if item is a trade token.
     */
    private boolean isTradeToken(ItemStack stack) {
        if (stack.isEmpty()) return false;
        return stack.getItem() == ModItems.TOKEN.get();
    }

    /**
     * Check if trader has prisoners to sell.
     */
    private boolean hasPrisonersToSell(ServerLevel level) {
        UUID campId = trader.getCampUUID();
        if (campId == null) {
            return false;
        }

        PrisonerManager manager = PrisonerManager.get(level);
        return manager.getPrisonerCountInCamp(campId) > 0;
    }

    @Override
    public void start() {
        hasGreeted = false;

        TiedUpMod.LOGGER.debug(
            "[TraderSellGoal] {} detected buyer: {}",
            trader.getNpcName(),
            potentialBuyer.getName().getString()
        );
    }

    @Override
    public void tick() {
        if (potentialBuyer == null) {
            return;
        }

        pitchCooldown--;

        // Look at buyer
        trader.getLookControl().setLookAt(potentialBuyer, 30.0f, 30.0f);

        // Check distance
        double distance = trader.distanceTo(potentialBuyer);

        if (distance <= INTERACTION_DISTANCE) {
            // Close enough - greet/pitch
            if (!hasGreeted && pitchCooldown <= 0) {
                greetBuyer();
                hasGreeted = true;
                pitchCooldown = PITCH_COOLDOWN;
            }
        } else if (distance <= DETECTION_RADIUS) {
            // Approach buyer slowly
            if (trader.getNavigation().isDone()) {
                trader.getNavigation().moveTo(potentialBuyer, 0.5);
            }
        }
    }

    /**
     * Greet potential buyer.
     */
    private void greetBuyer() {
        if (potentialBuyer == null) {
            return;
        }
        if (!(trader.level() instanceof ServerLevel level)) {
            return;
        }

        UUID campId = trader.getCampUUID();
        if (campId == null) {
            return;
        }

        int prisonerCount = PrisonerManager.get(level).getPrisonerCountInCamp(
            campId
        );

        // Send greeting message
        String greeting =
            prisonerCount == 1
                ? "Interested in my merchandise? I have one fine specimen available."
                : String.format(
                      "Interested in my merchandise? I have %d specimens available.",
                      prisonerCount
                  );

        potentialBuyer.sendSystemMessage(
            Component.translatable(
                "goal.tiedup.trader_sell.greeting", trader.getNpcName(), greeting
            ).withStyle(net.minecraft.ChatFormatting.GOLD)
        );

        potentialBuyer.sendSystemMessage(
            Component.translatable("goal.tiedup.trader_sell.browse_hint").withStyle(
                net.minecraft.ChatFormatting.GRAY
            )
        );

        TiedUpMod.LOGGER.debug(
            "[TraderSellGoal] {} greeted {}",
            trader.getNpcName(),
            potentialBuyer.getName().getString()
        );
    }

    @Override
    public boolean canContinueToUse() {
        if (trader.isTiedUp()) {
            return false;
        }
        if (trader.getTarget() != null) {
            return false;
        }
        if (potentialBuyer == null || !potentialBuyer.isAlive()) {
            return false;
        }

        // Check if still holding token
        ItemStack mainHand = potentialBuyer.getMainHandItem();
        ItemStack offHand = potentialBuyer.getOffhandItem();
        if (!isTradeToken(mainHand) && !isTradeToken(offHand)) {
            return false;
        }

        // Check distance
        double distance = trader.distanceTo(potentialBuyer);
        return distance <= DETECTION_RADIUS * 1.5;
    }

    @Override
    public void stop() {
        potentialBuyer = null;
        hasGreeted = false;
        trader.getNavigation().stop();

        TiedUpMod.LOGGER.debug("[TraderSellGoal] Stopped");
    }
}
