/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.core.compat.maid.barin;

import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task.MaidCheckRateTask;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.google.common.collect.ImmutableMap;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.RandomSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.entity.ai.behavior.BlockPosTracker;
import net.minecraft.world.entity.ai.behavior.EntityTracker;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.schedule.Activity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.eroticdungeongame.api.EroticDungeonGameApi;
import top.r3944realms.eroticdungeongame.content.item.FilterItem;
import top.r3944realms.eroticdungeongame.core.compat.maid.bauble.DungeonFilterBauble;
import top.r3944realms.eroticdungeongame.core.compat.maid.extra.ChatBabbles;
import top.r3944realms.eroticdungeongame.core.compat.maid.task.BindPlayerToDeviceTask;
import top.r3944realms.superleadrope.api.SuperLeadRopeApi;
import top.r3944realms.superleadrope.core.register.SLPItems;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;

public class FindPlayerNearWorkPos extends MaidCheckRateTask {
    private final RandomSource random = RandomSource.create();
    private static final int MAX_DELAY_TIME = 10;
    private static final int SEARCH_RADIUS = 20; // 搜索半径
    private static final int MAX_PLAYER_DISTANCE = 10; // 最大玩家距离
    private static final int WORK_AREA_RADIUS = 15; // 工作区域半径
    private static final int LEASH_DISTANCE = 2;

    private int searchCooldown = 0;
    private Player targetPlayer = null;
    private DungeonFilterBauble currentBauble = null;
    private int returnToWorkPosTimer = 0;
    private int costToApproachToPlayer = 0;

    public FindPlayerNearWorkPos() {
        super(ImmutableMap.of());
        this.setMaxCheckRate(MAX_DELAY_TIME);
    }


    @Override
    protected boolean checkExtraStartConditions(@NotNull ServerLevel level, @NotNull EntityMaid maid) {
        if (!super.checkExtraStartConditions(level, maid)) {
            return false;
        }

        if (maid.getScheduleDetail() != Activity.WORK) {
            return false;
        }
        Optional<DungeonFilterBauble> baubleOpt = DungeonFilterBauble.getFirstFilterBaubleOpt(maid);
        if (baubleOpt.isEmpty()) {
            return false;
        }

        if (!maid.getItemInHand(InteractionHand.MAIN_HAND).is(SLPItems.SUPER_LEAD_ROPE.get())) {
            ItemStack superLeadItem = BindPlayerToDeviceTask.getSuperLeadItem(maid);
            // 遍历女仆的所有物品栏槽位（不包括装备槽）
            handleItem(maid);
        }

        if (!maid.getItemInHand(InteractionHand.MAIN_HAND).is(SLPItems.SUPER_LEAD_ROPE.get())) {
            return false;
        }

        if (!maid.canBrainMoving()) {
            return false;
        }



        currentBauble = baubleOpt.get();

        // 检查是否有工作点
        if (currentBauble.workPos == null) {
            return false;
        }

        maid.setHomeModeEnable(true);
        maid.getSchedulePos().setHomeModeEnable(maid, currentBauble.workPos);

        // 检查女仆是否在工作区域内
        double distanceToWorkPos = currentBauble.getDistanceToWorkPos(maid);
        if (distanceToWorkPos > WORK_AREA_RADIUS) {
            // 如果女仆离开工作区域，尝试返回
            if (returnToWorkPosTimer <= 0) {
                maid.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET);
                BehaviorUtils.setWalkAndLookTargetMemories(maid,
                        new BlockPosTracker(currentBauble.workPos), 1.0f, 2);
                returnToWorkPosTimer = 20; // 5秒后重试
            } else {
                returnToWorkPosTimer--;
            }
            return false;
        }

        // 重置返回计时器
        returnToWorkPosTimer = 0;

        // 检查冷却
        if (searchCooldown > 0) {
            searchCooldown--;
            return false;
        }

        return true;
    }

    public static void handleItem(@NotNull EntityMaid maid) {
        for (int slot = 0; slot < maid.getAvailableInv(false).getSlots(); slot++) {
            ItemStack stackInSlot = maid.getAvailableInv(false).getStackInSlot(slot);

            // 检查是否是拴绳
            if (stackInSlot.getItem() == SLPItems.SUPER_LEAD_ROPE.get()) {
                // 获取当前主手的物品
                ItemStack mainHandItem = maid.getMainHandItem();

                if (mainHandItem.isEmpty()) {
                    // 如果主手为空，直接设置
                    maid.setItemInHand(InteractionHand.MAIN_HAND, stackInSlot.copy());
                    maid.getAvailableInv(false).setStackInSlot(slot, ItemStack.EMPTY);
                } else {
                    // 如果主手有物品，交换两者
                    maid.setItemInHand(InteractionHand.MAIN_HAND, stackInSlot.copy());
                    maid.getAvailableInv(false).setStackInSlot(slot, mainHandItem.copy());
                }
            }
        }
    }

    @Override
    protected void start(@NotNull ServerLevel level, @NotNull EntityMaid maid, long gameTime) {
        // 重置搜索冷却
        searchCooldown = 20; // 1秒冷却

        if (currentBauble == null || currentBauble.workPos == null) {
            return;
        }
        AtomicBoolean isIdle = new AtomicBoolean(true);
        // 寻找工作点附近的玩家
        findNearestPlayerNearWorkPos(level, maid, currentBauble.workPos, this::filterPlayer)
                .ifPresent(player -> {
                    this.targetPlayer = player;
                    maid.getBrain().setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, player);
                    maid.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, new EntityTracker(player, true));
                    maid.getChatBubbleManager().addChatBubble(ChatBabbles.createTextChatBubbleData(20, ChatBabbles.getRandomBabbleComponent("find", maid)));
                    // 如果玩家在可互动范围内，走过去
                    if (maid.distanceToSqr(player) < MAX_PLAYER_DISTANCE * MAX_PLAYER_DISTANCE) {
                        isIdle.set(false);
                        BehaviorUtils.setWalkAndLookTargetMemories(maid, player, 0.6f, 2);
                    }

                    // 触发饰品事件
                    if (currentBauble != null) {
                        currentBauble.onPlayerFound(maid, player);
                    }
                });
        if (isIdle.get()) {
            maid.getChatBubbleManager().addChatBubble(ChatBabbles.createTextChatBubbleData(40, ChatBabbles.getRandomBabbleComponent("idle", maid)));
        }
        costToApproachToPlayer = 400;
    }


    /**
     * 玩家过滤逻辑
     */
    private boolean filterPlayer(ServerPlayer player) {
        if (SuperLeadRopeApi.getLeashHelper().getLeashedHelper(player).isLeashed()) {
            return false;
        }
        if (EroticDungeonGameApi.isInDevice(player)) {
            return false;
        }
        if (currentBauble == null) {
            return false;
        }

        // 检查白名单
        if (currentBauble.whitelist.contains(player.getUUID().toString())) {
            return true;
        }

        // 检查黑名单
        if (currentBauble.blacklist.contains(player.getUUID().toString())) {
            return false;
        }

        // 根据过滤模式判断
        return switch (currentBauble.filterMode) {
            case WHITELIST -> {
                // 检查标签
                for (String tag : currentBauble.tags) {
                    if (!player.getTags().contains(tag)) {
                        yield false;
                    }
                }
                // 检查队伍
                if (!currentBauble.teams.isEmpty() &&
                        (player.getTeam() == null || !currentBauble.teams.contains(player.getTeam().getName()))) {
                    yield false;
                }
                // 检查游戏模式
                yield currentBauble.gameModes.contains(FilterItem.getPlayerGameMode(player));
            }
            case BLACKLIST -> {
                // 检查标签
                for (String tag : currentBauble.tags) {
                    if (player.getTags().contains(tag)) {
                        yield false;
                    }
                }
                // 检查队伍
                if (!currentBauble.teams.isEmpty() &&
                        player.getTeam() != null &&
                        currentBauble.teams.contains(player.getTeam().getName())) {
                    yield false;
                }
                // 检查游戏模式
                yield !currentBauble.gameModes.contains(FilterItem.getPlayerGameMode(player));
            }
        };
    }

    @Override
    protected boolean canStillUse(@NotNull ServerLevel level, @NotNull EntityMaid maid, long gameTime) {
        if (targetPlayer == null || !targetPlayer.isAlive()) {
            return false;
        }

        if (!maid.getItemInHand(InteractionHand.MAIN_HAND).is(SLPItems.SUPER_LEAD_ROPE.get())) {
            return false;
        }

        // 检查玩家状态
        if (SuperLeadRopeApi.getLeashHelper().getLeashedHelper(targetPlayer).isLeashed()) {
            return false;
        }
        if (EroticDungeonGameApi.isInDevice(targetPlayer)) {
            return false;
        }
        // 检查工作点是否存在
        return currentBauble != null && currentBauble.workPos != null && targetPlayer.distanceToSqr(currentBauble.workPos.getCenter()) < MAX_PLAYER_DISTANCE * MAX_PLAYER_DISTANCE;
    }

    @Override
    protected void tick(@NotNull ServerLevel level, @NotNull EntityMaid maid, long gameTime) {
        if (targetPlayer == null || !targetPlayer.isAlive() || currentBauble == null) {
            return;
        }
        // 更新注视目标
        maid.getBrain().setMemory(MemoryModuleType.LOOK_TARGET,
                new EntityTracker(targetPlayer, true));
        if (costToApproachToPlayer > 0) {
            // 如果玩家移动了，更新行走目标
            if (maid.distanceToSqr(targetPlayer) < MAX_PLAYER_DISTANCE * MAX_PLAYER_DISTANCE) {
                if (maid.tickCount % 40 == 0) {
                    maid.getChatBubbleManager().addChatBubble(ChatBabbles.createTextChatBubbleData(20, ChatBabbles.getRandomBabbleComponent("toward", maid)));
                }
                BehaviorUtils.setWalkAndLookTargetMemories(maid, targetPlayer, 0.6f, 2);
            }

            //添加拴绳
            if (maid.distanceToSqr(targetPlayer) < LEASH_DISTANCE * LEASH_DISTANCE) {
                SuperLeadRopeApi.getLeashHelper().getLeashedHelper(targetPlayer).attachLeash(maid, 2.0d, 1.0d, 200);
                ItemStack itemInHand = maid.getItemInHand(InteractionHand.MAIN_HAND);
                itemInHand.hurtAndBreak(1, maid, i -> {});
                maid.playSound(SLPSoundEvents.LEAD_TIED.get());
                maid.swing(InteractionHand.MAIN_HAND);
            }

            // 周期性触发饰品效果
            if (maid.tickCount % 20 == 0) {

                currentBauble.onPlayerNearby(maid, targetPlayer);
            }
            costToApproachToPlayer--;
        }

    }

    @Override
    protected void stop(@NotNull ServerLevel level, @NotNull EntityMaid maid, long gameTime) {
        // 清理记忆
        maid.getBrain().eraseMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER);
        maid.getBrain().eraseMemory(MemoryModuleType.LOOK_TARGET);
        maid.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET);

        // 触发饰品事件
        if (currentBauble != null) {
            currentBauble.onPlayerLost(maid);
        }

        targetPlayer = null;
        currentBauble = null;
    }

    protected boolean timedOut(long gameTime) {
        return costToApproachToPlayer <= 0;
    }

    /**
     * 寻找工作点附近最近符合条件的玩家
     */
    private Optional<ServerPlayer> findNearestPlayerNearWorkPos(
            ServerLevel level,
            EntityMaid maid,
            BlockPos workPos,
            Predicate<ServerPlayer> filter) {

        // 在工作点周围创建搜索区域
        AABB searchArea = new AABB(workPos).inflate(SEARCH_RADIUS);

        // 获取区域内的所有玩家
        List<ServerPlayer> players = level.getEntitiesOfClass(
                ServerPlayer.class,
                searchArea,
                player -> player.isAlive() && !player.isSpectator()
        );

        // 按距离工作点的距离排序
        return players.stream()
                .filter(filter)
                .min(Comparator.comparingDouble(player ->
                        player.distanceToSqr(workPos.getX(),
                                workPos.getY(),
                                workPos.getZ())));
    }

    public Player getTargetPlayer() {
        return targetPlayer;
    }
}