package com.tiedup.remake.v2.blocks;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.v2.V2BlockEntities;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;

/**
 * Pet Bed Block - Used by Master to make pets sit and sleep.
 * Features:
 * - Right-click cycle: Stand -> SIT (wariza) -> SLEEP (curled) -> Stand
 * - SIT: immobilized with animation, no night skip
 * - SLEEP: vanilla sleeping + animation, night skips
 * - Custom OBJ model rendering
 */
public class PetBedBlock extends Block implements EntityBlock {

    public static final DirectionProperty FACING =
        HorizontalDirectionalBlock.FACING;
    public static final BooleanProperty OCCUPIED =
        BlockStateProperties.OCCUPIED;

    // Collision shape (rough approximation of pet bed)
    private static final VoxelShape SHAPE = Block.box(
        1.0,
        0.0,
        1.0,
        15.0,
        6.0,
        15.0
    );

    public PetBedBlock(Properties properties) {
        super(properties);
        this.registerDefaultState(
            this.stateDefinition.any()
                .setValue(FACING, Direction.NORTH)
                .setValue(OCCUPIED, false)
        );
    }

    @Override
    protected void createBlockStateDefinition(
        StateDefinition.Builder<Block, BlockState> builder
    ) {
        builder.add(FACING, OCCUPIED);
    }

    @Override
    public BlockState getStateForPlacement(BlockPlaceContext context) {
        return this.defaultBlockState().setValue(
            FACING,
            context.getHorizontalDirection().getOpposite()
        );
    }

    @Override
    public VoxelShape getShape(
        BlockState state,
        BlockGetter level,
        BlockPos pos,
        CollisionContext context
    ) {
        return SHAPE;
    }

    @Override
    public RenderShape getRenderShape(BlockState state) {
        return RenderShape.ENTITYBLOCK_ANIMATED; // Use block entity renderer
    }

    @Nullable
    @Override
    public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
        return new PetBedBlockEntity(V2BlockEntities.PET_BED.get(), pos, state);
    }

    @Override
    public InteractionResult use(
        BlockState state,
        Level level,
        BlockPos pos,
        Player player,
        InteractionHand hand,
        BlockHitResult hit
    ) {
        if (level.isClientSide) {
            return InteractionResult.CONSUME;
        }

        if (!(player instanceof ServerPlayer sp)) {
            return InteractionResult.PASS;
        }

        // SLEEP -> Stand: player is sleeping, wake them up
        if (sp.isSleeping()) {
            sp.stopSleeping();
            PetBedManager.clearPlayer(sp);
            TiedUpMod.LOGGER.debug(
                "[PetBedBlock] {} woke up from bed at {}",
                player.getName().getString(),
                pos
            );
            return InteractionResult.SUCCESS;
        }

        // SIT -> SLEEP: player is already sitting on this bed
        if (PetBedManager.isOnBed(sp, pos)) {
            sp.startSleeping(pos);
            // FIX: notify server to count this player for night skip
            if (level instanceof ServerLevel sl) {
                sl.updateSleepingPlayerList();
            }
            PetBedManager.setMode(sp, pos, PetBedManager.PetBedMode.SLEEP);
            TiedUpMod.LOGGER.debug(
                "[PetBedBlock] {} started sleeping in bed at {}",
                player.getName().getString(),
                pos
            );
            return InteractionResult.SUCCESS;
        }

        // Check if bed is already occupied by someone else
        BlockEntity be = level.getBlockEntity(pos);
        if (be instanceof PetBedBlockEntity petBed && petBed.isOccupied()) {
            return InteractionResult.FAIL;
        }

        // Stand -> SIT
        PetBedManager.setMode(sp, pos, PetBedManager.PetBedMode.SIT);
        TiedUpMod.LOGGER.debug(
            "[PetBedBlock] {} sat down on bed at {}",
            player.getName().getString(),
            pos
        );
        return InteractionResult.SUCCESS;
    }

    @Override
    public void setBedOccupied(
        BlockState state,
        Level level,
        BlockPos pos,
        net.minecraft.world.entity.LivingEntity sleeper,
        boolean occupied
    ) {
        level.setBlock(pos, state.setValue(OCCUPIED, occupied), 3);
    }

    @Override
    public boolean isBed(
        BlockState state,
        BlockGetter level,
        BlockPos pos,
        @Nullable net.minecraft.world.entity.Entity player
    ) {
        return true;
    }
}
