package com.tiedup.remake.entities.master.components;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.entities.ai.master.MasterState;
import com.tiedup.remake.entities.ai.master.PetTask;
import javax.annotation.Nullable;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.Item;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.registries.ForgeRegistries;

/**
 * MasterTaskManager - Manages pet tasks, engagement cadence, and cold shoulder.
 *
 * Extracted from EntityMaster to reduce class size and isolate task-tracking
 * concerns from the entity lifecycle.
 *
 * Features:
 * - Task lifecycle: assign, watch, complete, fail, clear
 * - Fetch item give handling (item validation + dialogue)
 * - Engagement cadence: anti-spam gap + anti-drought boost
 * - Cold shoulder: timed ignore of pet interactions
 * - Full NBT persistence
 */
public class MasterTaskManager {

    // CONSTANTS

    /** Engagement cadence: minimum gap between actions (30s) */
    private static final int MIN_ENGAGEMENT_GAP = 600;

    /** Engagement cadence: force action if idle too long (90s) */
    private static final int MAX_IDLE_BEFORE_BOOST = 1800;

    /** NBT keys */
    private static final String NBT_CURRENT_TASK = "CurrentTask";
    private static final String NBT_TASK_START_POS = "TaskStartPos";
    private static final String NBT_REQUESTED_ITEM = "RequestedItem";
    private static final String NBT_LAST_ENGAGEMENT = "LastEngagementTime";
    private static final String NBT_COLD_SHOULDER_UNTIL = "ColdShoulderUntil";

    // FIELDS

    /** Back-reference to the owning entity */
    private final EntityMaster master;

    /** Currently active task (null if no task) */
    @Nullable
    private PetTask currentTask = null;

    /** Start position for WAIT_HERE task */
    @Nullable
    private Vec3 taskStartPosition = null;

    /** Requested item for FETCH_ITEM task */
    @Nullable
    private Item requestedItem = null;

    /** Last time the master performed an engagement action */
    private long lastEngagementTime = 0;

    /** Game time until cold shoulder ends (0 = not active) */
    private long coldShoulderUntil = 0;

    // CONSTRUCTOR

    public MasterTaskManager(EntityMaster master) {
        this.master = master;
    }

    // TASK MANAGEMENT

    /**
     * Check if there is an active task.
     */
    public boolean hasActiveTask() {
        return currentTask != null;
    }

    /**
     * Get the current active task.
     */
    @Nullable
    public PetTask getCurrentTask() {
        return currentTask;
    }

    /**
     * Set the active task.
     */
    public void setActiveTask(PetTask task) {
        this.currentTask = task;
        TiedUpMod.LOGGER.debug(
            "[MasterTaskManager] {} set active task: {}",
            master.getDamselName(),
            task
        );
    }

    /**
     * Clear the active task and associated data.
     */
    public void clearActiveTask() {
        TiedUpMod.LOGGER.debug(
            "[MasterTaskManager] {} cleared task: {}",
            master.getDamselName(),
            currentTask
        );
        this.currentTask = null;
        this.taskStartPosition = null;
        this.requestedItem = null;
    }

    /**
     * Get the task start position (for WAIT_HERE task).
     */
    @Nullable
    public Vec3 getTaskStartPosition() {
        return taskStartPosition;
    }

    /**
     * Set the task start position (for WAIT_HERE task).
     */
    public void setTaskStartPosition(Vec3 position) {
        this.taskStartPosition = position;
    }

    /**
     * Get the requested item (for FETCH_ITEM task).
     */
    @Nullable
    public Item getRequestedItem() {
        return requestedItem;
    }

    /**
     * Set the requested item (for FETCH_ITEM task).
     */
    public void setRequestedItem(Item item) {
        this.requestedItem = item;
    }

    /**
     * Handle item being given by pet for FETCH_ITEM task.
     * Called from interaction handling.
     *
     * @param item The item being given
     * @return true if the item was accepted and task completed
     */
    public boolean handleFetchItemGive(Item item) {
        if (
            currentTask != PetTask.FETCH_ITEM && currentTask != PetTask.DEMAND
        ) {
            return false;
        }

        if (requestedItem == null) {
            return false;
        }

        if (item == requestedItem) {
            ServerPlayer pet = master.getPetPlayer();
            if (pet != null) {
                // Task completed successfully - use appropriate dialogue
                String successDialogue =
                    currentTask == PetTask.DEMAND
                        ? "petplay.demand_success"
                        : "petplay.fetch_success";
                com.tiedup.remake.dialogue.DialogueBridge.talkTo(
                    master,
                    pet,
                    successDialogue
                );
                TiedUpMod.LOGGER.info(
                    "[MasterTaskManager] {} received requested item from {}",
                    master.getDamselName(),
                    pet.getName().getString()
                );
            }

            // Clear task and return to following
            clearActiveTask();
            master.setMasterState(MasterState.FOLLOWING);
            return true;
        }

        // Wrong item
        ServerPlayer pet = master.getPetPlayer();
        if (pet != null) {
            com.tiedup.remake.dialogue.DialogueBridge.talkTo(
                master,
                pet,
                "petplay.fetch_wrong"
            );
        }
        return false;
    }

    // ENGAGEMENT CADENCE SYSTEM

    /**
     * Mark that an engagement action just occurred.
     * Called by goals when they start an action (task, event, idle behavior, etc.)
     */
    public void markEngagement() {
        lastEngagementTime = master.level().getGameTime();
    }

    /**
     * Get a multiplier for engagement chance based on time since last action.
     * Returns 0.0 if too soon (anti-spam), 5.0 if idle too long (anti-drought), 1.0 normally.
     */
    public float getEngagementMultiplier() {
        long idle = master.level().getGameTime() - lastEngagementTime;
        if (idle < MIN_ENGAGEMENT_GAP) return 0.0f; // Suppress if recent
        if (idle > MAX_IDLE_BEFORE_BOOST) return 5.0f; // Boost if idle too long
        return 1.0f;
    }

    // COLD SHOULDER

    /**
     * Check if the master is giving the cold shoulder (ignoring pet).
     */
    public boolean isGivingColdShoulder() {
        return (
            coldShoulderUntil > 0 &&
            master.level().getGameTime() < coldShoulderUntil
        );
    }

    /**
     * Start cold shoulder punishment - ignore pet interactions for duration.
     * @param durationTicks How long to ignore the pet
     */
    public void startColdShoulder(int durationTicks) {
        coldShoulderUntil = master.level().getGameTime() + durationTicks;
    }

    // NBT SERIALIZATION

    /**
     * Save task manager state to NBT.
     */
    public void save(CompoundTag tag) {
        if (currentTask != null) {
            tag.putString(NBT_CURRENT_TASK, currentTask.name());
        }
        if (taskStartPosition != null) {
            tag.putDouble(NBT_TASK_START_POS + "X", taskStartPosition.x);
            tag.putDouble(NBT_TASK_START_POS + "Y", taskStartPosition.y);
            tag.putDouble(NBT_TASK_START_POS + "Z", taskStartPosition.z);
        }
        if (requestedItem != null) {
            ResourceLocation requestedItemKey = ForgeRegistries.ITEMS.getKey(
                requestedItem
            );
            if (requestedItemKey != null) {
                tag.putString(NBT_REQUESTED_ITEM, requestedItemKey.toString());
            } else {
                TiedUpMod.LOGGER.warn(
                    "[MasterTaskManager] Unregistered requestedItem {}, falling back to iron_ingot",
                    requestedItem
                );
                tag.putString(NBT_REQUESTED_ITEM, "minecraft:iron_ingot");
            }
        }
        tag.putLong(NBT_LAST_ENGAGEMENT, lastEngagementTime);
        tag.putLong(NBT_COLD_SHOULDER_UNTIL, coldShoulderUntil);
    }

    /**
     * Load task manager state from NBT.
     */
    public void load(CompoundTag tag) {
        if (tag.contains(NBT_CURRENT_TASK)) {
            try {
                currentTask = PetTask.valueOf(tag.getString(NBT_CURRENT_TASK));
            } catch (IllegalArgumentException e) {
                currentTask = null;
            }
        }
        if (tag.contains(NBT_TASK_START_POS + "X")) {
            taskStartPosition = new Vec3(
                tag.getDouble(NBT_TASK_START_POS + "X"),
                tag.getDouble(NBT_TASK_START_POS + "Y"),
                tag.getDouble(NBT_TASK_START_POS + "Z")
            );
        }
        if (tag.contains(NBT_REQUESTED_ITEM)) {
            requestedItem = ForgeRegistries.ITEMS.getValue(
                ResourceLocation.tryParse(tag.getString(NBT_REQUESTED_ITEM))
            );
        }
        if (tag.contains(NBT_LAST_ENGAGEMENT)) {
            lastEngagementTime = tag.getLong(NBT_LAST_ENGAGEMENT);
        }
        if (tag.contains(NBT_COLD_SHOULDER_UNTIL)) {
            coldShoulderUntil = tag.getLong(NBT_COLD_SHOULDER_UNTIL);
        }
    }
}
