import { world, system, ItemStack, EntityComponentTypes } from '@minecraft/server';

const GUIDEBOOK_ENTITY_ID = 'dss_st:st_guidebook'; 
const LEFT_HITBOX_ENTITY_ID = 'dss_st:st_gb_la';
const RIGHT_HITBOX_ENTITY_ID = 'dss_st:st_gb_ra';
const GUIDEBOOK_SPAWN_EGG_ID = 'dss_st:gb_placer';
const HAS_GUIDEBOOK_TAG = 'has_dss_st_guidebook';
const STREET_BUILDER_TAG = 'street_build_set_builder';
const DROP_GB_EVENT = 'dss_st:drop_gb';

const LEFT_HITBOX_ENTITY_ANIM = 'animation.st_gb_la.interact';
const RIGHT_HITBOX_ENTITY_ANIM = 'animation.st_gb_ra.interact';

const MAX_PAGE = 12; // 0-based indexing
const MIN_PAGE = 0;

const DEBUG = false;
function debugLog(message) {
  if (DEBUG) {
    console.log(`[DEBUG] ${message}`);
  }
}

world.afterEvents.playerSpawn.subscribe(event => {
  const { player, initialSpawn } = event;
  if (initialSpawn && !player.hasTag(HAS_GUIDEBOOK_TAG)) {
    const inventory = player.getComponent("inventory");
    if (inventory && inventory.container) {
      inventory.container.addItem(new ItemStack(GUIDEBOOK_SPAWN_EGG_ID, 1));
      player.addTag(HAS_GUIDEBOOK_TAG);
      debugLog(`Gave guidebook to player ${player.name}`);
    }
  }
});

world.afterEvents.entitySpawn.subscribe(event => {
  const entity = event.entity;
  if (entity.typeId === GUIDEBOOK_ENTITY_ID) {
    const skinIdComponent = entity.getComponent('minecraft:skin_id');
    if (skinIdComponent) {
      skinIdComponent.value = MIN_PAGE;
      debugLog(`Guidebook spawned with skin_id ${MIN_PAGE}`);
    }
    world.playSound('item.book.put', entity.location, {
      pitch: 1.0,
      volume: 1.0
    });
  }
});

world.afterEvents.playerInteractWithEntity.subscribe(event => {
  const { player, target } = event;
  if (target.typeId === LEFT_HITBOX_ENTITY_ID || target.typeId === RIGHT_HITBOX_ENTITY_ID) {

    target.playAnimation(target.typeId === LEFT_HITBOX_ENTITY_ID ? LEFT_HITBOX_ENTITY_ANIM : RIGHT_HITBOX_ENTITY_ANIM);

    const rideComp = target.getComponent(EntityComponentTypes.Riding);
    const rides = rideComp.entityRidingOn;
    if (!rides) {
      debugLog(`Hitbox has no parent entity`);
      return;
    }
    if (rides.typeId !== GUIDEBOOK_ENTITY_ID) {
      console.warning(`Parent entity is not a guidebook, found: ${rides.typeId}`);
      return;
    }
    const isRightHitbox = target.typeId === RIGHT_HITBOX_ENTITY_ID;
    handlePageTurn(rides, isRightHitbox, player);
  }
});

function handlePageTurn(guidebookEntity, isNextPage, player) {
  const skinIdComponent = guidebookEntity.getComponent('minecraft:skin_id');
  const riders = guidebookEntity.getComponent('minecraft:rideable').getRiders();
  if (!skinIdComponent) {
    console.warning(`Guidebook entity has no skin_id component`);
    return;
  }
  
  const currentPage = skinIdComponent.value;
  debugLog(`Current page: ${currentPage}`);
  
  let newPage;
  if (isNextPage) {
    newPage = currentPage < MAX_PAGE ? currentPage + 1 : currentPage;
    debugLog(`Next page requested: ${newPage}`);
    if (newPage > currentPage) {
      if (newPage === MAX_PAGE && player) {
        handleLastPageAchievement(player);
      }
    }
  } else {
    newPage = currentPage > MIN_PAGE ? currentPage - 1 : currentPage;
    debugLog(`Previous page requested: ${newPage}`);
  }

  if (newPage !== currentPage) {
    skinIdComponent.value = newPage;
    world.playSound('item.book.page_turn', guidebookEntity.location, {
      pitch: 1.0,
      volume: 1.0
    });
  }

  riders.forEach(rider => {
    rider.setProperty("dss_st:page", newPage);
  });
}

function handleLastPageAchievement(player) {
  if (!player.hasTag(STREET_BUILDER_TAG)) {
    player.addTag(STREET_BUILDER_TAG);
    
    player.sendMessage("§eAchievement Unlocked: §dStreet Build Set Builder!");
    world.sendMessage(player.name + " has unlocked the §dStreet Build Set Builder §rachievement!");
    
    world.playSound('random.levelup', player.location, {
      pitch: 1.0,
      volume: 1.0
    });
    debugLog(`Player ${player.name} received the Street Build Set Builder achievement`);
  }
}

system.afterEvents.scriptEventReceive.subscribe((event) => {
    const { id, sourceEntity } = event;
    
    if (id === DROP_GB_EVENT) {
      sourceEntity.dimension.spawnItem(new ItemStack(GUIDEBOOK_SPAWN_EGG_ID, 1), sourceEntity.location)
    }
});