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

import com.tiedup.remake.cells.CampOwnership;
import com.tiedup.remake.cells.CellDataV2;
import com.tiedup.remake.cells.CellRegistryV2;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntitySlaveTrader;
import com.tiedup.remake.prison.PrisonerManager;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.goal.Goal;

/**
 * Goal: Trader idle/patrol behavior.
 *
 * Simplified from TraderManageCampGoal.
 * Removed: prisoner management, maid ordering, complex cleanup.
 * Those are now handled by PrisonerManager and PrisonerService.
 *
 * Responsibilities:
 * - Stay near camp center
 * - Occasionally inspect cells (visual behavior only)
 * - Look professional
 */
public class TraderIdleGoal extends Goal {

    private static final double MAX_WANDER_DISTANCE = 20.0;
    private static final double INSPECTION_DISTANCE = 3.0;
    private static final int INSPECTION_INTERVAL_MIN = 600; // 30 seconds
    private static final int INSPECTION_INTERVAL_MAX = 1200; // 60 seconds
    private static final int MAX_TRAVEL_TIME = 200; // 10 seconds

    private final EntitySlaveTrader trader;
    private final Random random = new Random();

    private CampOwnership.CampData campData;
    private BlockPos campCenter;

    // Inspection state
    private int inspectionCooldown = 0;
    private CellDataV2 inspectionTarget = null;
    private int inspectionLookTime = 0;
    private int travelTime = 0;
    private boolean returningHome = false;

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

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

        // Get camp data
        UUID campId = trader.getCampUUID();
        if (campId == null) {
            return false;
        }

        CampOwnership ownership = CampOwnership.get(level);
        campData = ownership.getCamp(campId);
        if (campData == null || !campData.isAlive()) {
            return false;
        }

        campCenter = campData.getCenter();
        return campCenter != null;
    }

    @Override
    public void tick() {
        if (!(trader.level() instanceof ServerLevel level)) {
            return;
        }

        inspectionCooldown++;

        if (inspectionTarget != null) {
            tickInspection(level);
        } else if (returningHome) {
            tickReturningHome();
        } else {
            tickIdle(level);
        }
    }

    /**
     * Normal idle behavior.
     */
    private void tickIdle(ServerLevel level) {
        // Stay near camp center
        if (campCenter != null) {
            double distance = trader.blockPosition().distSqr(campCenter);
            if (distance > MAX_WANDER_DISTANCE * MAX_WANDER_DISTANCE) {
                // Too far - return home
                trader
                    .getNavigation()
                    .moveTo(
                        campCenter.getX() + 0.5,
                        campCenter.getY(),
                        campCenter.getZ() + 0.5,
                        0.6
                    );
            }
        }

        // Maybe start inspection
        if (inspectionCooldown >= INSPECTION_INTERVAL_MIN) {
            int threshold =
                INSPECTION_INTERVAL_MIN +
                random.nextInt(
                    INSPECTION_INTERVAL_MAX - INSPECTION_INTERVAL_MIN
                );

            if (inspectionCooldown >= threshold) {
                maybeStartInspection(level);
                inspectionCooldown = 0;
            }
        }
    }

    /**
     * Try to start a cell inspection.
     */
    private void maybeStartInspection(ServerLevel level) {
        UUID campId = trader.getCampUUID();
        if (campId == null) {
            return;
        }

        CellRegistryV2 registry = CellRegistryV2.get(level);
        List<CellDataV2> cells = registry.getCellsByCamp(campId);

        if (cells.isEmpty()) {
            return;
        }

        // Pick a random cell
        inspectionTarget = cells.get(random.nextInt(cells.size()));
        inspectionLookTime = 0;
        travelTime = 0;

        TiedUpMod.LOGGER.debug(
            "[TraderIdleGoal] {} starting inspection",
            trader.getNpcName()
        );
    }

    /**
     * Tick inspection behavior.
     */
    private void tickInspection(ServerLevel level) {
        if (inspectionTarget == null) {
            return;
        }

        BlockPos targetPos =
            inspectionTarget.getSpawnPoint() != null
                ? inspectionTarget.getSpawnPoint()
                : inspectionTarget.getCorePos().above();
        double distance = trader
            .position()
            .distanceTo(
                new net.minecraft.world.phys.Vec3(
                    targetPos.getX() + 0.5,
                    targetPos.getY(),
                    targetPos.getZ() + 0.5
                )
            );

        if (distance <= INSPECTION_DISTANCE) {
            // At cell - look around
            inspectionLookTime++;

            // Look at cell
            trader
                .getLookControl()
                .setLookAt(
                    targetPos.getX() + 0.5,
                    targetPos.getY() + 1.0,
                    targetPos.getZ() + 0.5,
                    30.0f,
                    30.0f
                );

            // Done looking after 2-3 seconds
            if (inspectionLookTime >= 40 + random.nextInt(20)) {
                completeInspection();
            }
        } else {
            // Navigate to cell
            travelTime++;

            if (trader.getNavigation().isDone()) {
                trader
                    .getNavigation()
                    .moveTo(
                        targetPos.getX() + 0.5,
                        targetPos.getY(),
                        targetPos.getZ() + 0.5,
                        0.7
                    );
            }

            // Timeout
            if (travelTime > MAX_TRAVEL_TIME) {
                TiedUpMod.LOGGER.debug(
                    "[TraderIdleGoal] Inspection travel timeout"
                );
                cancelInspection();
            }
        }
    }

    /**
     * Complete inspection and return home.
     */
    private void completeInspection() {
        inspectionTarget = null;
        returningHome = true;

        TiedUpMod.LOGGER.debug("[TraderIdleGoal] Inspection complete");
    }

    /**
     * Cancel inspection without completing.
     */
    private void cancelInspection() {
        inspectionTarget = null;
        returningHome = true;
    }

    /**
     * Tick returning home behavior.
     */
    private void tickReturningHome() {
        if (campCenter == null) {
            returningHome = false;
            return;
        }

        double distance = trader
            .position()
            .distanceTo(
                new net.minecraft.world.phys.Vec3(
                    campCenter.getX() + 0.5,
                    campCenter.getY(),
                    campCenter.getZ() + 0.5
                )
            );

        if (distance <= 3.0) {
            // Home
            returningHome = false;
            trader.getNavigation().stop();
        } else if (trader.getNavigation().isDone()) {
            trader
                .getNavigation()
                .moveTo(
                    campCenter.getX() + 0.5,
                    campCenter.getY(),
                    campCenter.getZ() + 0.5,
                    0.6
                );
        }
    }

    @Override
    public boolean canContinueToUse() {
        return canUse();
    }

    @Override
    public void stop() {
        inspectionTarget = null;
        returningHome = false;
        trader.getNavigation().stop();
    }
}
