package top.r3944realms.eroticdungeongame.content.block.blockentity;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.eroticdungeongame.content.block.AbstractSeatBlock;
import top.r3944realms.eroticdungeongame.content.device.SeatType;
import top.r3944realms.eroticdungeongame.content.entity.SeatEntity;
import top.r3944realms.eroticdungeongame.content.register.EDGBlockEntities;
import top.r3944realms.eroticdungeongame.content.util.FurnitureHelper;

import java.util.UUID;

/**
 * 地牢座椅方块实体 - 处理玩家坐在束缚设备上的逻辑
 */
@SuppressWarnings("unused")
public class SeatBlockEntity extends BlockEntity {

    private int seatEntityId;
    private UUID boundPlayerUUID;

    public SeatBlockEntity(BlockPos blockPos, BlockState blockState) {
        super(EDGBlockEntities.SEAT_BLOCK_ENTITY.get(), blockPos, blockState);
    }

    // Getter/Setter 方法使用有意义的名称
    public UUID getBoundPlayerUUID() {
        return this.boundPlayerUUID;
    }

    public void setBoundPlayerUUID(UUID uuid) {
        this.boundPlayerUUID = uuid;
        setChanged();
    }

    public int getSeatEntityId() {
        return this.seatEntityId;
    }

    public void setSeatEntityId(int entityId) {
        this.seatEntityId = entityId;
        setChanged();
    }

    /**
     * 绑定玩家到座椅
     */
    public void bindPlayerToSeat(Level level, BlockPos blockPos, BlockState blockState, Player player) {
        SeatType furnitureType = FurnitureHelper.getSeatType(blockState.getBlock());
        if (furnitureType == null) {
            return;
        }

        Direction direction = blockState.getValue(AbstractSeatBlock.FACING);
        if (furnitureType.isOppositeDirection()) {
            direction = direction.getOpposite();
        }

        // 创建座椅实体
        SeatEntity seatEntity = new SeatEntity(furnitureType.getEntityType(), level);
        double[] seatPosition = calculateSeatPosition(blockPos, direction, furnitureType);

        seatEntity.setPos(seatPosition[0], seatPosition[1], seatPosition[2]);

        // 设置座椅和玩家的朝向
        float yaw = calculateSeatYaw(direction);
        seatEntity.setYRot(yaw);
        player.setYRot(yaw);

        level.addFreshEntity(seatEntity);
        seatEntity.setLinkedBlockPos(blockPos);

        // 更新方块实体数据
        setSeatEntityId(seatEntity.getId());
        setBoundPlayerUUID(player.getUUID());

        // 更新方块状态
        updateBlockState(level, blockPos, blockState, AbstractSeatBlock.OCCUPIED, true);
        updateBlockState(level, blockPos, blockState, AbstractSeatBlock.FLIPPED, false);

        // 让玩家乘坐座椅
        player.startRiding(seatEntity, true);
    }

    /**
     * 翻转座椅方向
     */
    public void flipSeatDirection(Level level, BlockPos blockPos, @NotNull BlockState blockState) {
        Direction direction = blockState.getValue(AbstractSeatBlock.FACING);
        boolean isFlipped = blockState.getValue(AbstractSeatBlock.FLIPPED);

        float yaw = calculateSeatYaw(isFlipped ? direction : direction.getOpposite());

        // 更新实体朝向
        FurnitureHelper.getEntityById(level, getSeatEntityId())
                .filter(e -> e instanceof SeatEntity)
                .ifPresent(seat -> seat.setYRot(yaw));

        // 翻转方块状态
        updateBlockState(level, blockPos, blockState, AbstractSeatBlock.FLIPPED, !isFlipped);
    }

    /**
     * 释放玩家
     */
    public void releasePlayer(@NotNull Level level, BlockPos blockPos) {
        BlockState blockState = level.getBlockState(blockPos);
        updateBlockState(level, blockPos, blockState, AbstractSeatBlock.OCCUPIED, false);
        updateBlockState(level, blockPos, blockState, AbstractSeatBlock.FLIPPED, false);

        // 清理数据
        this.seatEntityId = 0;
        this.boundPlayerUUID = null;
        setChanged();
    }

    /**
     * 计算座椅位置
     */
    @Contract("_, _, _ -> new")
    private double @NotNull [] calculateSeatPosition(@NotNull BlockPos blockPos, @NotNull Direction direction, @NotNull SeatType furnitureType) {
        double x = furnitureType.getOffsetX(blockPos.getX());
        double y = furnitureType.getOffsetY(blockPos.getY());
        double z = furnitureType.getOffsetZ(blockPos.getZ());
        double offset = furnitureType.getGeneralOffset();

        // 根据方向调整位置
        switch (direction) {
            case NORTH -> x -= offset;
            case SOUTH -> x += offset;
            case WEST -> z -= offset;
            case EAST -> z += offset;
        }

        return new double[]{x, y, z};
    }

    /**
     * 计算座椅朝向
     */
    @Contract(pure = true)
    private float calculateSeatYaw(@NotNull Direction direction) {
        return switch (direction) {
            case NORTH -> 180.0f;
            case WEST -> 90.0f;
            case EAST -> 270.0f;
            default -> 0.0f;
        };
    }

    /**
     * 更新多方块结构的状态
     */
    private void updateBlockState(Level level, BlockPos blockPos, @NotNull BlockState blockState,
                                  BooleanProperty property, boolean value) {
        SeatType seatType = FurnitureHelper.getSeatType(blockState.getBlock());
        if (seatType == null) return;

        // 根据家具类型更新相关的方块
        switch (seatType.getFurnitureType()) {
            case NORMAL ->
                    FurnitureHelper.setBlockStates(level, property, value, blockPos);
            case HORIZONTAL_DOUBLE ->
                    FurnitureHelper.setBlockStates(level, property, value, blockPos,
                            blockPos.relative(blockState.getValue(AbstractSeatBlock.FACING)));
            case HORIZONTAL_TRIPLE ->
                    FurnitureHelper.setBlockStates(level, property, value, blockPos,
                            blockPos.relative(blockState.getValue(AbstractSeatBlock.FACING)),
                            blockPos.relative(blockState.getValue(AbstractSeatBlock.FACING).getClockWise()));
            case VERTICAL_DOUBLE ->
                    FurnitureHelper.setBlockStates(level, property, value, blockPos,
                            blockPos.above());
        }
    }

    @Override
    public void saveAdditional(@NotNull CompoundTag compoundTag) {
        super.saveAdditional(compoundTag);
        if (this.boundPlayerUUID != null) {
            compoundTag.putInt("SeatEntityID", this.seatEntityId);
            compoundTag.putUUID("PlayerUUID", this.boundPlayerUUID);
        }
    }

    @Override
    public void load(@NotNull CompoundTag compoundTag) {
        super.load(compoundTag);
        if (compoundTag.contains("SeatEntityID")) {
            this.seatEntityId = compoundTag.getInt("SeatEntityID");
        }
        if (compoundTag.contains("PlayerUUID")) {
            this.boundPlayerUUID = compoundTag.getUUID("PlayerUUID");
        }
    }
}