pub mod flowing_trait;
pub mod lava;
pub mod pathfinder;
pub mod physics;
pub mod water;

// Re-export for backward compatibility
pub mod flowing {
    pub use super::flowing_trait::*;
    pub use super::pathfinder::*;
    pub use super::physics::*;
}

use super::{BlockIsReplacing, registry::BlockActionResult};
use crate::block::BlockFuture;
use crate::entity::{EntityBase, player::Player};
use crate::{server::Server, world::World};
use pumpkin_data::BlockDirection;
use pumpkin_data::BlockStateId;
use pumpkin_data::{fluid::Fluid, item::Item};
use pumpkin_protocol::java::server::play::SUseItemOn;
use pumpkin_util::math::position::BlockPos;
use std::sync::Arc;

pub trait FluidBehaviour: Send + Sync {
    fn normal_use<'a>(
        &'a self,
        _fluid: &'a Fluid,
        _player: &'a Player,
        _location: BlockPos,
        _server: &'a Server,
        _world: &'a Arc<World>,
    ) -> BlockFuture<'a, ()> {
        Box::pin(async {})
    }

    fn use_with_item<'a>(
        &'a self,
        _fluid: &'a Fluid,
        _player: &'a Player,
        _location: BlockPos,
        _item: &'a Item,
        _server: &'a Server,
        _world: &'a Arc<World>,
    ) -> BlockFuture<'a, BlockActionResult> {
        Box::pin(async { BlockActionResult::Pass })
    }

    fn placed<'a>(
        &'a self,
        _world: &'a Arc<World>,
        _fluid: &'a Fluid,
        _state_id: BlockStateId,
        _block_pos: &'a BlockPos,
        _old_state_id: BlockStateId,
        _notify: bool,
    ) -> BlockFuture<'a, ()> {
        Box::pin(async {})
    }

    #[expect(clippy::too_many_arguments)]
    fn on_place<'a>(
        &'a self,
        _server: &'a Server,
        _world: &'a Arc<World>,
        fluid: &'a Fluid,
        _face: BlockDirection,
        _block_pos: &'a BlockPos,
        _use_item_on: &'a SUseItemOn,
        _replacing: BlockIsReplacing,
    ) -> BlockFuture<'a, BlockStateId> {
        Box::pin(async { fluid.states[fluid.default_state_index as usize].block_state_id })
    }

    fn get_state_for_neighbour_update<'a>(
        &'a self,
        _world: &'a Arc<World>,
        _fluid: &'a Fluid,
        _block_pos: &'a BlockPos,
        _notify: bool,
    ) -> BlockFuture<'a, BlockStateId> {
        Box::pin(async { BlockStateId::AIR })
    }

    fn on_neighbor_update<'a>(
        &'a self,
        _world: &'a Arc<World>,
        _fluid: &'a Fluid,
        _block_pos: &'a BlockPos,
        _notify: bool,
    ) -> BlockFuture<'a, ()> {
        Box::pin(async {})
    }

    fn on_entity_collision<'a>(&'a self, _entity: &'a dyn EntityBase) -> BlockFuture<'a, ()> {
        Box::pin(async {})
    }

    fn on_scheduled_tick<'a>(
        &'a self,
        _world: &'a Arc<World>,
        _fluid: &'a Fluid,
        _block_pos: &'a BlockPos,
    ) -> BlockFuture<'a, ()> {
        Box::pin(async {})
    }

    fn random_tick<'a>(
        &'a self,
        _fluid: &'a Fluid,
        _world: &'a Arc<World>,
        _block_pos: &'a BlockPos,
    ) -> BlockFuture<'a, ()> {
        Box::pin(async {})
    }

    fn create_legacy_block<'a>(
        &'a self,
        _world: &'a Arc<World>,
        _block_pos: &'a BlockPos,
    ) -> BlockFuture<'a, ()> {
        Box::pin(async {})
    }
}
