package com.tiedup.remake.personality;

import com.tiedup.remake.cells.CellDataV2;
import com.tiedup.remake.v2.blocks.PetBedBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.CarpetBlock;
import org.jetbrains.annotations.Nullable;

/**
 * Quality of the cell/environment around an NPC's home.
 *
 * <p>Evaluated in a radius around the home position and applies
 * a mood modifier based on living conditions.
 *
 * <ul>
 *   <li>LUXURY: Bed + Carpet + Light > 10 → +5 mood</li>
 *   <li>STANDARD: PetBed OR Bed → +0 mood</li>
 *   <li>DUNGEON: No bed + Light < 5 → -5 mood</li>
 * </ul>
 */
public enum CellQuality {
    /** Bed + Carpet + Light > 10: good living conditions */
    LUXURY(5.0f),

    /** PetBed OR Bed: normal conditions */
    STANDARD(0.0f),

    /** No bed + Light < 5: harsh conditions */
    DUNGEON(-5.0f);

    /** Mood modifier applied when NPC lives in this quality cell */
    public final float moodModifier;

    CellQuality(float moodModifier) {
        this.moodModifier = moodModifier;
    }

    /** Detection radius around home (5 blocks) */
    public static final int DETECTION_RADIUS = 5;

    /** Light level threshold for LUXURY (> 10) */
    public static final int LIGHT_LUXURY_THRESHOLD = 10;

    /** Light level threshold for DUNGEON (< 5) */
    public static final int LIGHT_DUNGEON_THRESHOLD = 5;

    /**
     * Evaluate cell quality around a home position, optionally using CellDataV2 features.
     *
     * <p>When a cell is provided, bed/pet bed detection uses pre-computed flood-fill data
     * instead of scanning blocks. Carpets still require a block scan since they are not
     * tracked by the flood-fill.
     *
     * @param homePos The home block position
     * @param level The world level
     * @param cell Optional CellDataV2 for optimized feature detection
     * @return Evaluated cell quality
     */
    public static CellQuality evaluate(
        BlockPos homePos,
        Level level,
        @Nullable CellDataV2 cell
    ) {
        if (homePos == null || level == null) return STANDARD;

        boolean hasBed = false;
        boolean hasPetBed = false;
        boolean hasCarpet = false;

        if (cell != null) {
            // Use cell features (already detected by flood-fill)
            hasBed = !cell.getBeds().isEmpty();
            hasPetBed = !cell.getPetBeds().isEmpty();
            // Carpets not tracked by flood-fill, still need scan
            for (BlockPos pos : BlockPos.betweenClosed(
                homePos.offset(-DETECTION_RADIUS, -1, -DETECTION_RADIUS),
                homePos.offset(DETECTION_RADIUS, 0, DETECTION_RADIUS)
            )) {
                if (
                    level.getBlockState(pos).getBlock() instanceof CarpetBlock
                ) {
                    hasCarpet = true;
                    break;
                }
            }
        } else {
            // Fallback: full environment scan (no cell link)
            for (BlockPos pos : BlockPos.betweenClosed(
                homePos.offset(-DETECTION_RADIUS, -1, -DETECTION_RADIUS),
                homePos.offset(DETECTION_RADIUS, 2, DETECTION_RADIUS)
            )) {
                Block block = level.getBlockState(pos).getBlock();

                if (block instanceof BedBlock) hasBed = true;
                if (block instanceof PetBedBlock) hasPetBed = true;
                if (block instanceof CarpetBlock) hasCarpet = true;

                // Early exit if we found all luxury requirements
                if (hasBed && hasCarpet) break;
            }
        }

        // Get light level at home position
        int lightLevel = level.getBrightness(LightLayer.BLOCK, homePos);

        // LUXURY: Bed + Carpet + Light > 10
        if (hasBed && hasCarpet && lightLevel > LIGHT_LUXURY_THRESHOLD) {
            return LUXURY;
        }

        // DUNGEON: No bed/pet bed + Light < 5
        if (!hasBed && !hasPetBed && lightLevel < LIGHT_DUNGEON_THRESHOLD) {
            return DUNGEON;
        }

        // STANDARD: Bed or PetBed (or medium light)
        return STANDARD;
    }

    /**
     * Evaluate cell quality around a home position.
     *
     * @param homePos The home block position
     * @param level The world level
     * @return Evaluated cell quality
     */
    public static CellQuality evaluate(BlockPos homePos, Level level) {
        return evaluate(homePos, level, null);
    }
}
