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

// Configuration constants
const GUIDEBOOK_ENTITY_ID = 'dss_gep:dss_gep_gb'; 
const LEFT_HITBOX_ENTITY_ID = 'dss_gep:dss_gep_gb_lhb';
const RIGHT_HITBOX_ENTITY_ID = 'dss_gep:dss_gep_gb_rhb';
const GUIDEBOOK_SPAWN_EGG_ID = 'dss_gep:golf_expansion_pack_guidebook';
const HAS_GUIDEBOOK_TAG = 'has_dss_gep_guidebook';
const SKIN_ID_CHANGE_DELAY = 9.5; // ticks
const GUIDEBOOK_PROPERTY = 'dss_gep:page';

const ACHIEVEMENT_TAG = 'gep_enthusiast'; // Tag for achievement
const ACHIEVEMENT_MESSAGE = '§eAchievement Unlocked: §dGolf Enthusiast!';
const ACHIEVEMENT_NOTIFICATION = ' has unlocked the §dGolf Enthusiast §rachievement!';

const NEXT_PAGE_ANIMATION = 'animation.dss_gep_gb.nextpage';
const PREV_PAGE_ANIMATION = 'animation.dss_gep_gb.prevpage';

const DROP_GB_EVENT = 'dss_gep:drop_gb';

const SPAWN_SOUND = 'item.book.put';
const PAGE_TURN_SOUND = 'item.book.page_turn';
const ACHIEVE_SOUND = 'random.levelup';

// Page navigation constants
const MAX_PAGE = 14; // 0-based indexing
const MIN_PAGE = 0;

/**
 * Debug logging function that only logs if debug mode is enabled
 */
const DEBUG = false;
function debugLog(message, type = 'info') {
  if (DEBUG) {
    switch (type) {
      case 'info':
        console.info(`[INFO] ${message}`);
        break;
      case 'warn':
        console.warn(`[WARN] ${message}`);
        break;
      case 'error':
        console.error(`[ERROR] ${message}`);
        break;
      default:
        console.log(`[DEBUG] ${message}`);
    }
  }
}

/**
 * Give guidebook spawn egg to new players
 */
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}`);
        }
    }
});

/**
 * Initialize newly spawned guidebook entities
 */
world.afterEvents.entitySpawn.subscribe(event => {
  const entity = event.entity;
  
  if (entity.typeId === GUIDEBOOK_ENTITY_ID) {
    // Play spawn sound
    entity.dimension.playSound(SPAWN_SOUND, entity.location, {
      pitch: 1.0,
      volume: 1.0
    });
  }
});

/**
 * Handle player interaction with guidebook hitboxes
 */
world.afterEvents.playerInteractWithEntity.subscribe(event => {
  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`, 'warn');
      return;
    }
    
    if (rides.typeId !== GUIDEBOOK_ENTITY_ID) {
      debugLog(`Parent entity is not a guidebook, found: ${rides.typeId}`, 'warn');
      return;
    }
    
    const isRightHitbox = target.typeId === RIGHT_HITBOX_ENTITY_ID;
    handlePageTurn(rides, isRightHitbox, player);
  }
});

/**
 * 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)
 * @param {Object} player - The player who interacted with the guidebook
 */
function handlePageTurn(guidebookEntity, isNextPage, player) {
    // Get current skin_id (page)
    const pageProperty = guidebookEntity.getProperty(GUIDEBOOK_PROPERTY);
    if (pageProperty === undefined) {
      debugLog(`Guidebook entity has no page property: ${pageProperty}`, 'warn');
      return;
    }
    
    const currentPage = pageProperty;
    debugLog(`Current page: ${currentPage}`, 'info');
    
    // Calculate new page based on direction
    let newPage;
    if (isNextPage) {
      newPage = currentPage < MAX_PAGE ? currentPage + 1 : currentPage;
      debugLog(`Next page requested: ${newPage}`, 'info');
      
      // Only play animation and sound if not at max page
      if (newPage > currentPage) {
        playPageTurnAnimation(guidebookEntity, true);
        
        // Check if player reached the last page and handle achievement
        if (newPage === MAX_PAGE && player) {
          handleLastPageAchievement(player);
        }
      } else {
        // If already at last page and player tries to go next, show ready UI for admin
        if (currentPage === MAX_PAGE && player && player.hasTag('admin')) {
          showReadyUI(player, guidebookEntity);
        } else {
          debugLog(`Already at last page`, 'info');
        }
      }
    } else {
      newPage = currentPage > MIN_PAGE ? currentPage - 1 : currentPage;
      debugLog(`Previous page requested: ${newPage}`, 'info');
      
      // Only play animation and sound if not at min page
      if (newPage < currentPage) {
        playPageTurnAnimation(guidebookEntity, false);
      } else {
        debugLog(`Already at first page`, 'info');
      }
    }
    
    // Update the skin_id if changed
    if (newPage !== currentPage) {
      if(!guidebookEntity) return;
      system.runTimeout(() => {
        guidebookEntity.setProperty(GUIDEBOOK_PROPERTY, newPage);
        debugLog(`Changed from ${guidebookEntity.getProperty(GUIDEBOOK_PROPERTY)} to ${newPage}`);
      }, SKIN_ID_CHANGE_DELAY);
      
      // Play page turn sound
      guidebookEntity.dimension.playSound(PAGE_TURN_SOUND, guidebookEntity.location, {
        pitch: 1.0,
        volume: 1.0
      });
    }
}

/**
 * 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) {
    // Play the appropriate animation based on direction
    if (isNextPage) {
      guidebookEntity.playAnimation(NEXT_PAGE_ANIMATION);
    } else {
      guidebookEntity.playAnimation(PREV_PAGE_ANIMATION);
    }
    debugLog(`Playing ${isNextPage ? 'next' : 'previous'} page animation`);
}

/**
 * Handle giving the kawaii builder achievement when a player reaches the last page
 * @param {Object} player - The player who viewed the last page
 */
function handleLastPageAchievement(player) {
    if (!player.hasTag(ACHIEVEMENT_TAG)) {
      // Give the achievement tag
      player.addTag(ACHIEVEMENT_TAG);
      
      // Send achievement message
      player.sendMessage(ACHIEVEMENT_MESSAGE);
      world.sendMessage(player.name + ACHIEVEMENT_NOTIFICATION);
      
      // Play achievement sound
      player.dimension.playSound(ACHIEVE_SOUND, player.location, {
        pitch: 1.0,
        volume: 1.0
      });
    }
}

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)
    }
});