/*
 * Copyright (c) 2026 盐灯水母
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package com.remains_cave.block;

import com.mojang.serialization.MapCodec;
import com.remains_cave.block.entity.ChallengeAltarBlockEntity;
import com.remains_cave.dungeon.tomb.ChallengeManager;
import com.remains_cave.dungeon.tomb.ChallengeType;
import com.remains_cave.item.ModItems;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.ItemInteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ChallengeAltarBlock extends HorizontalDirectionalBlock implements EntityBlock {
    public static final EnumProperty<ChallengeType> TYPE = EnumProperty.create("type", ChallengeType.class);
    public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
    public static final BooleanProperty OPEN = BooleanProperty.create("open"); //开放状态

    public ChallengeAltarBlock(Properties properties) {
        super(properties
                .strength(-1.0f, 1200.0f)
                .noLootTable()
                .noOcclusion()
                .isViewBlocking((state, level, pos) -> false)
                .sound(SoundType.VAULT)
                .lightLevel(state -> state.getValue(ACTIVE) ? 12 : 6)
        );
        this.registerDefaultState(this.stateDefinition.any()
                .setValue(FACING, Direction.NORTH)
                .setValue(TYPE, ChallengeType.NONE)
                .setValue(ACTIVE, false)
                .setValue(OPEN, false));
    }

    @Override
    protected @NotNull MapCodec<? extends HorizontalDirectionalBlock> codec() {
        return simpleCodec(ChallengeAltarBlock::new);
    }

    @Override
    public @NotNull InteractionResult useWithoutItem(@NotNull BlockState state, Level level, @NotNull BlockPos pos, @NotNull Player player, @NotNull BlockHitResult hit) {
        if (!level.isClientSide) {
            if (level.getBlockEntity(pos) instanceof ChallengeAltarBlockEntity altar) {
                // 冷却检查
                if (altar.isOnCooldown()) {
                    long remainingSeconds = (altar.cooldownEndTick - level.getGameTime()) / 20;
                    long minutes = remainingSeconds / 60;
                    long seconds = remainingSeconds % 60;
                    player.displayClientMessage(
                            Component.translatable("challenge.cooldown", minutes, seconds),
                            true
                    );
                    return InteractionResult.CONSUME;
                }
                // 创造模式：手持物品设置祭坛类型（调试用）
                if (player.isCreative()) {
                    ItemStack held = player.getMainHandItem();
                    ChallengeType preset = null;
                    if (held.is(ModItems.TOMB_ARROW.get())) preset = ChallengeType.ARCHER;
                    else if (held.is(ModItems.DOOM_STAFF.get())) preset = ChallengeType.WARLOCK;
                    else if (held.is(ModItems.BONE_HATCHET.get())) preset = ChallengeType.WARRIOR;
                    if (preset != null) {
                        altar.setPresetType(preset);
                        level.setBlock(pos, state.setValue(TYPE, preset), 3);
                        player.displayClientMessage(Component.translatable("challenge.preset_set", preset.getSerializedName()), true);
                        return InteractionResult.SUCCESS;
                    }
                }

                ChallengeManager manager = ChallengeManager.get(level);
                if (manager.isChallengeActive(altar.getRoomId())) {
                    player.displayClientMessage(Component.translatable("challenge.other_active"), true);
                    return InteractionResult.CONSUME;
                }

                // 获取玩家手持物品对应的挑战类型
                ChallengeType chosenType = determineType(player);
                if (chosenType == ChallengeType.NONE) {
                    player.displayClientMessage(Component.translatable("challenge.need_item"), true);
                    return InteractionResult.CONSUME;
                }

                // 获取祭坛预设类型（结构生成时固定）
                ChallengeType presetType = altar.getPresetType();
                if (presetType == ChallengeType.NONE) {
                    player.displayClientMessage(Component.translatable("challenge.no_preset"), true);
                    return InteractionResult.CONSUME;
                }

                // 类型匹配检查
                if (chosenType != presetType) {
                    player.displayClientMessage(Component.translatable("challenge.wrong_type", presetType.getSerializedName()), true);
                    return InteractionResult.CONSUME;
                }
// 消耗战利品（仅生存模式）
                if (!player.isCreative()) {
                    ItemStack held = player.getMainHandItem();
                    held.shrink(1);  // 减少一个物品
                }

                // 开启挑战（不修改方块类型）
                manager.startChallenge(altar.getRoomId(), pos, chosenType, (ServerLevel) level);
                level.playSound(null, pos, SoundEvents.WITHER_SPAWN, SoundSource.BLOCKS, 1.0f, 1.0f);
                return InteractionResult.SUCCESS;
            }
        }
        return InteractionResult.sidedSuccess(level.isClientSide);
    }

    private ChallengeType determineType(Player player) {
        ItemStack held = player.getMainHandItem();
        if (held.is(ModItems.SKELETON_WARRIOR_TROPHY_ITEM.get())) return ChallengeType.WARRIOR;
        if (held.is(ModItems.SKELETON_ARCHER_TROPHY_ITEM.get())) return ChallengeType.ARCHER;
        if (held.is(ModItems.SKELETON_WARLOCK_TROPHY_ITEM.get())) return ChallengeType.WARLOCK;
        return ChallengeType.NONE;
    }

    @Nullable
    @Override
    public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState state) {
        return new ChallengeAltarBlockEntity(pos, state);
    }

    @Override
    public @NotNull RenderShape getRenderShape(@NotNull BlockState state) {
        return RenderShape.MODEL;
    }

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

    @Override
    public void spawnAfterBreak(@NotNull BlockState state, @NotNull ServerLevel level, @NotNull BlockPos pos, @NotNull ItemStack stack, boolean dropExperience) {
        super.spawnAfterBreak(state, level, pos, stack, dropExperience);
        // 宝库风格粒子
        for (int i = 0; i < 8; i++) {
            double x = pos.getX() + 0.5 + (level.random.nextDouble() - 0.5) * 1.2;
            double y = pos.getY() + 0.5 + level.random.nextDouble();
            double z = pos.getZ() + 0.5 + (level.random.nextDouble() - 0.5) * 1.2;
            level.sendParticles(ParticleTypes.EFFECT, x, y, z, 1, 0, 0, 0, 0);
        }
        for (int i = 0; i < 12; i++) {
            double x = pos.getX() + 0.5 + (level.random.nextDouble() - 0.5) * 1.5;
            double y = pos.getY() + 0.5 + level.random.nextDouble() * 0.8;
            double z = pos.getZ() + 0.5 + (level.random.nextDouble() - 0.5) * 1.5;
            level.sendParticles(ParticleTypes.ENCHANT, x, y, z, 1, 0, 0.1, 0, 0);
        }
    }

    @Nullable
    @Override
    public <T extends BlockEntity> BlockEntityTicker<T> getTicker(@NotNull Level level, @NotNull BlockState state, @NotNull BlockEntityType<T> type) {
        if (type == ModBlocks.CHALLENGE_ALTAR_BE.get()) {
            return level.isClientSide
                    ? (l, p, s, be) -> ChallengeAltarBlockEntity.clientTick(l, p, s, (ChallengeAltarBlockEntity) be)
                    : (l, p, s, be) -> ChallengeAltarBlockEntity.serverTick(l, p, s, (ChallengeAltarBlockEntity) be);
        }
        return null;
    }
}