/*
 *  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.content.entity.npc.ai.goal;

import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.player.Player;
import top.r3944realms.eroticdungeongame.content.entity.npc.NPCServerPlayer;

import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.function.Predicate;

public class NPCFindTargetGoal extends Goal {
    private final NPCServerPlayer npc;
    private LivingEntity target;
    private final double searchRadius;
    private final int cooldown;
    private int cooldownTicks;

    // 目标过滤条件
    private Predicate<LivingEntity> targetFilter;

    // 优先级排序器（数值越小优先级越高）
    private Comparator<LivingEntity> priorityComparator;

    public NPCFindTargetGoal(NPCServerPlayer npc, double searchRadius, int cooldown) {
        this.npc = npc;
        this.searchRadius = searchRadius;
        this.cooldown = cooldown;
        this.setFlags(EnumSet.of(Flag.LOOK));

        // 默认过滤器：排除自己、死亡、创造模式玩家
        this.targetFilter = entity ->
                entity != npc &&
                        entity.isAlive() &&
                        entity instanceof Player player && !player.isCreative();

        // 默认优先级：距离最近优先级最高（距离越小优先级越高）
        this.priorityComparator = Comparator.comparingDouble(npc::distanceToSqr);
    }

    // 允许自定义过滤条件
    public NPCFindTargetGoal withFilter(Predicate<LivingEntity> filter) {
        this.targetFilter = filter;
        return this;
    }

    // 允许自定义优先级排序器（例如：血量最低、威胁值最高等）
    public NPCFindTargetGoal withPriorityComparator(Comparator<LivingEntity> comparator) {
        this.priorityComparator = comparator;
        return this;
    }

    @Override
    public boolean canUse() {
        // 冷却中不寻找
        if (cooldownTicks-- > 0) return false;

        // 寻找当前优先级最高的目标
        this.target = findHighestPriorityTarget();

        // 找到目标后立即返回 true，准备设置目标
        return this.target != null;
    }

    /**
     * 一旦找到目标，启动后立即停止，不持续占用该 Goal。
     * 这样 NPC 每次只会执行一次“寻找最高优先级目标”的动作，
     * 然后由其他 Goal（如攻击、跟随）来持续处理该目标。
     */
    @Override
    public boolean canContinueToUse() {
        return false; // 找到目标后立即结束，不持续运行
    }

    @Override
    public void start() {
        if (target != null) {
            // 设置 NPC 的攻击目标
            npc.setTarget(target);
            // 重置冷却
            cooldownTicks = cooldown;
        }
    }

    @Override
    public void stop() {
        // 不清除 target，让其他 Goal 决定是否保留
        // 只是本 Goal 停止运行
    }

    @Override
    public void tick() {
        // 由于 canContinueToUse 返回 false，tick 实际上不会被持续调用
        // 但为了保险，依然保留冷却递减逻辑
        if (cooldownTicks > 0) {
            cooldownTicks--;
        }
    }

    /**
     * 查找当前范围内优先级最高的有效目标。
     * 使用 priorityComparator 排序，取第一个（优先级最高）。
     */
    private LivingEntity findHighestPriorityTarget() {
        List<? extends LivingEntity> candidates = npc.level().getEntitiesOfClass(
                LivingEntity.class,
                npc.getBoundingBox().inflate(searchRadius),
                this::isValidTarget
        );

        if (candidates.isEmpty()) {
            return null;
        }

        // 根据优先级排序器找出优先级最高的目标
        // 注意：Comparator 定义的是“优先级高”的排序规则（例如距离近在前、血量低在前）
        return candidates.stream()
                .min(priorityComparator)
                .orElse(null);
    }

    /**
     * 判断实体是否为有效目标。
     */
    private boolean isValidTarget(LivingEntity entity) {
        // 基础检查
        if (entity == npc) return false;
        if (!entity.isAlive()) return false;
        if (entity.isRemoved()) return false;

        // 视线检查（可选，性能消耗较大）
        if (requiresLineOfSight() && !npc.hasLineOfSight(entity)) {
            return false;
        }

        // 应用自定义过滤器
        return targetFilter.test(entity);
    }

    /**
     * 是否需要进行视线检查。
     */
    private boolean requiresLineOfSight() {
        return true; // 可根据需要配置
    }
}