import { Direction } from "@minecraft/server";
import { isCorrectSoilForCrop, hasWater, isDoubleBlock, isReplaceable, needsSolidBlockBehind, needsSolidBlockBelow } from "./blockProperties";
import { flipDir, getAttachFace, getCardinalDirection, offsetPos, offsetVec } from "./dirUtils";
import { breakBlock, isBlockSolid } from "./miscUtils";
import { McStates } from "../reg/mcStates";
import { SuppStates } from "../reg/suppStates";
//call this! sets waterlogged and break double plants
export function replaceBlock(oldBlock, newBlock) {
    const waterlogged = hasWater(oldBlock);
    oldBlock.dimension.setBlockPermutation(oldBlock.location, newBlock);
    if (waterlogged) {
        const placed = oldBlock.dimension.getBlock(oldBlock.location);
        placed.setWaterlogged(true);
    }
    if (isDoubleBlock(oldBlock.permutation)) {
        //get block below and above. if they are the same as old block then break them
        const blockBelow = offsetPos(oldBlock, Direction.Down);
        const blockAbove = offsetPos(oldBlock, Direction.Up);
        if (blockBelow && blockBelow.typeId == oldBlock.typeId) {
            breakBlock(blockBelow);
        }
        if (blockAbove && blockAbove.typeId == oldBlock.typeId) {
            breakBlock(blockAbove);
        }
    }
}
export function arePlacementRestraintsMet(placementPos, permToVerifyAtPos, level) {
    if (needsSolidBlockBelow(permToVerifyAtPos)) {
        const belowBlock = level.getBlock(offsetVec(placementPos, Direction.Down));
        if (!belowBlock) {
            return false;
        }
        let hasBelow = isCorrectSoilForCrop(permToVerifyAtPos, belowBlock);
        if (hasBelow == undefined) {
            if (!isBlockSolid(belowBlock, Direction.Up)) {
                return false;
            }
        }
        else if (hasBelow == false) {
            return false;
        }
    }
    //TODO
    //too bad for these. we'll do another time
    if (needsSolidBlockBehind(permToVerifyAtPos)) {
        const supportDir = getSupportDirection(permToVerifyAtPos);
        const belowBlock = level.getBlock(offsetVec(placementPos, supportDir));
        if (!belowBlock) {
            return false;
        }
        if (!isBlockSolid(belowBlock, Direction.Up)) {
            return false;
        }
    }
    return true;
}
export function getSupportDirection(perm) {
    const attachFace = getAttachFace(perm);
    if (attachFace != undefined) {
        return flipDir(attachFace); //??
    }
    else {
        const placementPosition = perm.getState("minecraft:placement_position");
        if (placementPosition != undefined) {
            return placementPosition == "bottom" ? Direction.Down : Direction.Up;
        }
        else {
            return getCardinalDirection(perm);
        }
    }
}
export function getPlacementPosition(block, clickedFace, target = isReplaceable) {
    let targetBlock;
    const inFront = offsetPos(block, clickedFace);
    if (target(block)) {
        targetBlock = block;
    }
    else {
        targetBlock = inFront;
        if (!target(targetBlock)) {
            return undefined;
        }
    }
    return targetBlock;
}
function tryPlacingStackable(targetBlock, perm) {
    if (targetBlock.typeId != perm.type.id)
        return false;
    const candles = targetBlock.permutation.getState(McStates.Candles);
    if (candles != undefined) {
        if (candles < 4) {
            targetBlock.setPermutation(targetBlock.permutation.withState(McStates.Candles, candles + 1));
            return true;
        }
    }
    const pickles = targetBlock.permutation.getState(McStates.Pickles);
    if (pickles != undefined) {
        if (pickles < 4) {
            targetBlock.setPermutation(targetBlock.permutation.withState(McStates.Pickles, pickles + 1));
            return true;
        }
    }
    const eggs = targetBlock.permutation.getState(McStates.TurtleEggs);
    if (eggs != undefined) {
        if (eggs != "four_egg") {
            const newEggCount = eggs == "one_egg" ? "two_egg" : eggs == "two_egg" ? "three_egg" : "four_egg";
            targetBlock.setPermutation(targetBlock.permutation.withState(McStates.TurtleEggs, newEggCount));
            return true;
        }
    }
    const growth = targetBlock.permutation.getState(McStates.Growth);
    if (growth != undefined) {
        if (growth < 4) {
            targetBlock.setPermutation(targetBlock.permutation.withState(McStates.Growth, growth + 1));
            return true;
        }
    }
    const height = targetBlock.permutation.getState(McStates.Height);
    if (height != undefined) {
        if (height < 8) {
            targetBlock.setPermutation(targetBlock.permutation.withState(McStates.Height, height + 1));
            return true;
        }
    }
    const candleHolder = targetBlock.permutation.getState(SuppStates.CandleCount);
    if (candleHolder != undefined) {
        if (candleHolder < 4) {
            targetBlock.setPermutation(targetBlock.permutation.withState(SuppStates.CandleCount, candleHolder + 1));
            return true;
        }
    }
    const layerCount = targetBlock.permutation.getState(SuppStates.LayerCount);
    if (layerCount != undefined) {
        if (layerCount < 8) {
            targetBlock.setPermutation(targetBlock.permutation.withState(SuppStates.LayerCount, layerCount + 1));
            return true;
        }
    }
    return false;
}
export function attemptPlacingAt(targetBlock, hitFace, perm) {
    //place on self
    if (tryPlacingStackable(targetBlock, perm)) {
        return true;
    }
    const placementPos = getPlacementPosition(targetBlock, hitFace);
    if (placementPos) {
        //check if it needs solid block below
        if (arePlacementRestraintsMet(placementPos, perm, targetBlock.dimension)) {
        }
        placementPos.setPermutation(perm);
        return true;
    }
    else {
        console.log("Failed to place block");
    }
    return false;
}
