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

// Configuration constants
const GUIDEBOOK_ENTITY_ID = 'dss_mc:dss_mc_guidebook';
const LEFT_HITBOX_ENTITY_ID = 'dss_mc:guidebook_left_hitbox';
const RIGHT_HITBOX_ENTITY_ID = 'dss_mc:guidebook_right_hitbox';
const GUIDEBOOK_SPAWN_EGG_ID = 'dss_mc:dss_mc_guidebook_spawn_egg';
const HAS_GUIDEBOOK_TAG = 'has_mcguidebook';
const SKIN_ID_CHANGE_DELAY = 9.5; // ticks

// Page navigation constants
const MAX_PAGE = 31; // 0-based indexing (8 = 9th page)
const MIN_PAGE = 0;

/**
 * Debug logging function that only logs if debug mode is enabled
 */
const DEBUG = false;
function debugLog(message) {
  if (DEBUG) {
    console.log(`[DEBUG] ${message}`);
  }
}

/**
 * Give guidebook spawn egg to new players
 */
world.afterEvents.playerSpawn.subscribe(event => {
  try {
    const { player, initialSpawn } = event;
    
    if (initialSpawn && !player.hasTag(HAS_GUIDEBOOK_TAG)) {
      try {
        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}`);
        }
      } catch (error) {
        console.error(`Error adding guidebook to inventory: ${error}`);
      }
    }
  } catch (error) {
    console.error(`Error in playerSpawn event: ${error}`);
  }
});

/**
 * Initialize newly spawned guidebook entities
 */
world.afterEvents.entitySpawn.subscribe(event => {
  try {
    const entity = event.entity;
    
    if (entity.typeId === GUIDEBOOK_ENTITY_ID) {
      // Initialize skin_id to 0 (first page)
      const skinIdComponent = entity.getComponent('minecraft:skin_id');
      if (skinIdComponent) {
        skinIdComponent.value = MIN_PAGE;
        debugLog(`Guidebook spawned with skin_id ${MIN_PAGE}`);
      }
      
      // Play spawn sound
      world.playSound('item.book.put', entity.location, {
        pitch: 1.0,
        volume: 1.0
      });
    }
  } catch (error) {
    console.error(`Error in entitySpawn event: ${error}`);
  }
});

/**
 * Handle player interaction with guidebook hitboxes
 */
world.afterEvents.playerInteractWithEntity.subscribe(event => {
  try {
    const { player, target } = event;
    
    // Check if player interacted with a guidebook hitbox
    if (target.typeId === LEFT_HITBOX_ENTITY_ID || target.typeId === RIGHT_HITBOX_ENTITY_ID) {
      // Find the parent guidebook entity
      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);
    }
  } catch (error) {
    console.error(`Error in playerInteractWithEntity event: ${error}`);
  }
});

/**
 * Handle turning the page of the guidebook
 * @param {Object} guidebookEntity - The guidebook entity
 * @param {boolean} isNextPage - Whether to go to the next page (true) or previous page (false)
 */
function handlePageTurn(guidebookEntity, isNextPage) {
  try {
    // Get current skin_id (page)
    const skinIdComponent = guidebookEntity.getComponent('minecraft:skin_id');
    if (!skinIdComponent) {
      console.warning(`Guidebook entity has no skin_id component`);
      return;
    }
    
    const currentPage = skinIdComponent.value;
    debugLog(`Current page: ${currentPage}`);
    
    // Calculate new page based on direction
    let newPage;
    if (isNextPage) {
      newPage = currentPage < MAX_PAGE ? currentPage + 1 : currentPage;
      debugLog(`Next page requested: ${newPage}`);
      
      // Only play animation and sound if not at max page
      if (newPage > currentPage) {
        playPageTurnAnimation(guidebookEntity, true);
      } else {
        debugLog(`Already at last page`);
      }
    } else {
      newPage = currentPage > MIN_PAGE ? currentPage - 1 : currentPage;
      debugLog(`Previous page requested: ${newPage}`);
      
      // Only play animation and sound if not at min page
      if (newPage < currentPage) {
        playPageTurnAnimation(guidebookEntity, false);
      } else {
        debugLog(`Already at first page`);
      }
    }
    
    // Update the skin_id if changed
    if (newPage !== currentPage) {
      system.runTimeout(() => {
        skinIdComponent.value = newPage;
        debugLog(`Changed to page ${newPage}`);
      }, SKIN_ID_CHANGE_DELAY);
      
      // Play page turn sound
      world.playSound('item.book.page_turn', guidebookEntity.location, {
        pitch: 1.0,
        volume: 1.0
      });
    }
  } catch (error) {
    console.error(`Error in handlePageTurn: ${error}`);
  }
}

/**
 * Play the page turning animation by setting the variant component
 * @param {Object} guidebookEntity - The guidebook entity to animate
 * @param {boolean} isNextPage - Whether to play the next page animation (true) or previous page animation (false)
 */
function playPageTurnAnimation(guidebookEntity, isNextPage) {
  try {
    // Play the appropriate animation based on direction
    if (isNextPage) {
      guidebookEntity.playAnimation('animation.dss_mc_guidebook.nextpage');
    } else {
      guidebookEntity.playAnimation('animation.dss_mc_guidebook.prevpage');
    }
    debugLog(`Playing ${isNextPage ? 'next' : 'previous'} page animation`);
  } catch (error) {
    console.error(`Error in playPageTurnAnimation: ${error}`);
  }
}