/**
 * OBJECT PHYSICS SYSTEM
 * =====================
 * 
 * Handles physics bodies, collision setup, and object behavior for chairs and other objects.
 * Separated from rooms.js for better modularity and maintainability.
 */

import { TILE_SIZE } from '../utils/constants.js';

let gameRef = null;
let rooms = null;

// Initialize object physics system
export function initializeObjectPhysics(gameInstance, roomsRef) {
    gameRef = gameInstance;
    rooms = roomsRef;
}

// Set up collision detection between chairs and other objects
export function setupChairCollisions(chair) {
    if (!chair || !chair.body) return;
    
    // Ensure we have a valid game reference
    const game = gameRef || window.game;
    if (!game) {
        console.error('No game reference available, cannot set up chair collisions');
        return;
    }
    
    // Use window.rooms to ensure we see the latest state
    const allRooms = window.rooms || {};
    
    // Collision with other chairs
    if (window.chairs) {
        window.chairs.forEach(otherChair => {
            if (otherChair !== chair && otherChair.body) {
                game.physics.add.collider(chair, otherChair);
            }
        });
    }
    
    // Collision with tables and other static objects
    Object.values(allRooms).forEach(room => {
        if (room.objects) {
            Object.values(room.objects).forEach(obj => {
                if (obj !== chair && obj.body && obj.body.immovable) {
                    game.physics.add.collider(chair, obj);
                }
            });
        }
    });
    
    // Collision with wall collision boxes
    Object.values(allRooms).forEach(room => {
        if (room.wallCollisionBoxes) {
            room.wallCollisionBoxes.forEach(wallBox => {
                if (wallBox.body) {
                    // Add collision callback for swivel chairs to modify spin on wall hit
                    if (chair.isSwivelChair) {
                        game.physics.add.collider(chair, wallBox, () => {
                            handleChairWallCollision(chair);
                        });
                    } else {
                        game.physics.add.collider(chair, wallBox);
                    }
                }
            });
        }
    });
    
    // Collision with closed door sprites
    Object.values(allRooms).forEach(room => {
        if (room.doorSprites) {
            room.doorSprites.forEach(doorSprite => {
                // Only collide with closed doors (doors that haven't been opened)
                if (doorSprite.body && doorSprite.body.immovable) {
                    // Add collision callback for swivel chairs to modify spin on wall hit
                    if (chair.isSwivelChair) {
                        game.physics.add.collider(chair, doorSprite, () => {
                            handleChairWallCollision(chair);
                        });
                    } else {
                        game.physics.add.collider(chair, doorSprite);
                    }
                }
            });
        }
    });
}

// Set up collisions between existing chairs and new room objects
export function setupExistingChairsWithNewRoom(roomId) {
    if (!window.chairs) return;
    
    // Use window.rooms to ensure we see the latest state
    const room = window.rooms ? window.rooms[roomId] : null;
    if (!room) return;
    
    // Ensure we have a valid game reference
    const game = gameRef || window.game;
    if (!game) {
        console.error('No game reference available, cannot set up chair collisions');
        return;
    }
    
    // Collision with new room's tables and static objects
    if (room.objects) {
        Object.values(room.objects).forEach(obj => {
            if (obj.body && obj.body.immovable) {
                window.chairs.forEach(chair => {
                    if (chair.body) {
                        game.physics.add.collider(chair, obj);
                    }
                });
            }
        });
    }
    
    // Collision with new room's wall collision boxes
    if (room.wallCollisionBoxes) {
        room.wallCollisionBoxes.forEach(wallBox => {
            if (wallBox.body) {
                window.chairs.forEach(chair => {
                    if (chair.body) {
                        game.physics.add.collider(chair, wallBox);
                    }
                });
            }
        });
    }
    
    // Collision with new room's door sprites
    if (room.doorSprites) {
        room.doorSprites.forEach(doorSprite => {
            // Only collide with closed doors (doors that haven't been opened)
            if (doorSprite.body && doorSprite.body.immovable) {
                window.chairs.forEach(chair => {
                    if (chair.body) {
                        game.physics.add.collider(chair, doorSprite);
                    }
                });
            }
        });
    }
    
    console.log(`Set up chair collisions for room ${roomId} with ${window.chairs.length} existing chairs`);
}

// Handle collision between swivel chair and wall - modify spin on impact
function handleChairWallCollision(chair) {
    if (!chair.isSwivelChair) return;
    
    // Check if chair is actually moving - if velocity is near zero, don't process collision
    // This prevents continuous collision spam when chair is at rest against a wall
    const velocity = Math.sqrt(
        chair.body.velocity.x * chair.body.velocity.x + 
        chair.body.velocity.y * chair.body.velocity.y
    );
    
    // Only process collision if chair has meaningful velocity
    if (velocity < 5) {
        return; // Chair is at rest or moving too slowly - ignore collision
    }
    
    // When chair hits a wall, reverse the spin direction and give it a speed boost
    // This creates a dynamic "bounce" effect
    if (chair.spinDirection !== 0) {
        chair.spinDirection *= -1; // Reverse spin
        
        // Give spin animation a nudge - speed it up temporarily
        // Add a boost to the rotation speed (up to 30% faster, but cap at max)
        const speedBoost = 1.3;
        chair.rotationSpeed = Math.min(chair.rotationSpeed * speedBoost, chair.maxRotationSpeed);
        
        console.log('Chair hit wall - spin reversed with boost', {
            newDirection: chair.spinDirection,
            newRotationSpeed: chair.rotationSpeed,
            maxRotationSpeed: chair.maxRotationSpeed
        });
    }
}

// Calculate chair spin direction based on contact point
export function calculateChairSpinDirection(player, chair) {
    if (!chair.isSwivelChair) return;
    
    // Get relative position of player to chair SPRITE center (not collision box)
    const chairSpriteCenterX = chair.x + chair.width / 2;
    const chairSpriteCenterY = chair.y + chair.height / 2;
    const playerX = player.x + player.width / 2;
    const playerY = player.y + player.height / 2;
    
    // Calculate offset from chair sprite center
    const offsetX = playerX - chairSpriteCenterX;
    const offsetY = playerY - chairSpriteCenterY;
    
    // Calculate distance from center using sprite dimensions (not collision box)
    const distanceFromCenter = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
    // Use the larger sprite dimension for maxDistance to make center area larger
    const maxDistance = Math.max(chair.width, chair.height) / 2;
    const centerRatio = distanceFromCenter / maxDistance;
    
    
    // Determine spin based on distance from center (EXTREMELY large center area)
    if (centerRatio > 1.2) { // 120% from center - edge hit (strong spin) - ONLY VERY EDGES
        // Determine spin direction based on which side of chair player is on
        if (Math.abs(offsetX) > Math.abs(offsetY)) {
            // Horizontal contact - spin based on X offset
            chair.spinDirection = offsetX > 0 ? 1 : -1; // Right side = clockwise, left side = counter-clockwise
        } else {
            // Vertical contact - spin based on Y offset and player movement
            const playerVelocityX = player.body.velocity.x;
            if (Math.abs(playerVelocityX) > 10) {
                // Player is moving horizontally - use that for spin direction
                chair.spinDirection = playerVelocityX > 0 ? 1 : -1;
            } else {
                // Use Y offset for spin direction
                chair.spinDirection = offsetY > 0 ? 1 : -1;
            }
        }
        
        // Strong spin for edge hits
        const spinIntensity = Math.min(centerRatio, 1.0);
        chair.maxRotationSpeed = 0.15 * spinIntensity;
        chair.rotationSpeed = Math.max(chair.rotationSpeed, 0.05); // Strong rotation start
        
        
    } else if (centerRatio > 0.8) { // 80-120% from center - moderate hit
        // Moderate spin
        if (Math.abs(offsetX) > Math.abs(offsetY)) {
            chair.spinDirection = offsetX > 0 ? 1 : -1;
        } else {
            const playerVelocityX = player.body.velocity.x;
            chair.spinDirection = Math.abs(playerVelocityX) > 10 ? (playerVelocityX > 0 ? 1 : -1) : (offsetY > 0 ? 1 : -1);
        }
        
        const spinIntensity = centerRatio * 0.3; // Reduced intensity
        chair.maxRotationSpeed = 0.06 * spinIntensity;
        chair.rotationSpeed = Math.max(chair.rotationSpeed, 0.015); // Moderate rotation start
        
        
    } else { // 0-80% from center - center hit (minimal spin) - MASSIVE CENTER AREA
        // Very minimal or no spin for center hits
        chair.spinDirection = 0;
        chair.maxRotationSpeed = 0.01; // Very slow spin
        chair.rotationSpeed = Math.max(chair.rotationSpeed, 0.002); // Minimal rotation start
        
    }
}

// Update swivel chair rotation based on movement
export function updateSwivelChairRotation() {
    if (!window.chairs) return;
    
    // Ensure we have a valid game reference
    const game = gameRef || window.game;
    if (!game) return; // Silently return if no game reference
    
    window.chairs.forEach(chair => {
        if (!chair.hasWheels || !chair.body) return;
        
        // Update chair depth based on current position (for all chairs with wheels)
        updateSpriteDepth(chair, chair.elevation || 0);
        
        // Only process rotation for swivel chairs
        if (!chair.isSwivelChair) return;
        
        // Calculate movement speed
        const velocity = Math.sqrt(
            chair.body.velocity.x * chair.body.velocity.x + 
            chair.body.velocity.y * chair.body.velocity.y
        );
        
        // Update rotation speed based on movement
        if (velocity > 10) {
            // Chair is moving - increase rotation speed (slower acceleration)
            chair.rotationSpeed = Math.min(chair.rotationSpeed + 0.01, chair.maxRotationSpeed);
            
            // If no spin direction set, set a default one for testing
            if (chair.spinDirection === 0) {
                chair.spinDirection = 1; // Default to clockwise
            }
        } else {
            // Chair is slowing down - decrease rotation speed (slower deceleration)
            chair.rotationSpeed = Math.max(chair.rotationSpeed - 0.005, 0);
            
            // Reset spin direction when chair stops moving
            if (chair.rotationSpeed < 0.01) {
                chair.spinDirection = 0;
            }
        }
        
        // Update frame based on rotation speed and direction
        if (chair.rotationSpeed > 0.01) {
            // Apply spin direction to rotation
            const rotationDelta = chair.rotationSpeed * chair.spinDirection;
            chair.currentFrame += rotationDelta;
            
            // Handle frame wrapping (8 frames total: 0-7)
            if (chair.currentFrame >= 8) {
                chair.currentFrame = 0; // Loop back to first frame
            } else if (chair.currentFrame < 0) {
                chair.currentFrame = 7; // Loop back to last frame (for counter-clockwise)
            }
            
            // Set the texture based on current frame and chair type
            const frameIndex = Math.floor(chair.currentFrame) + 1; // Convert to 1-based index
            let newTexture;
            
            // Determine texture prefix based on original texture
            if (chair.originalTexture && chair.originalTexture.startsWith('chair-exec-rotate')) {
                newTexture = `chair-exec-rotate${frameIndex}`;
            } else if (chair.originalTexture && chair.originalTexture.startsWith('chair-white-1-rotate')) {
                newTexture = `chair-white-1-rotate${frameIndex}`;
            } else if (chair.originalTexture && chair.originalTexture.startsWith('chair-white-2-rotate')) {
                newTexture = `chair-white-2-rotate${frameIndex}`;
            } else {
                // Fallback to exec chair if original texture is unknown
                newTexture = `chair-exec-rotate${frameIndex}`;
            }
            
            // Check if texture exists before setting
            if (game.textures.exists(newTexture)) {
                chair.setTexture(newTexture);
            } else {
                console.warn(`Texture not found: ${newTexture}`);
            }
        }
    });
}

// Reusable function to update sprite depth based on Y position and elevation
export function updateSpriteDepth(sprite, elevation = 0) {
    if (!sprite || !sprite.active) return;
    
    // Get the bottom of the sprite (feet position)
    const spriteBottomY = sprite.y + (sprite.height * sprite.scaleY);
    
    // Calculate depth: world Y position + layer offset + elevation
    const spriteDepth = spriteBottomY + 0.5 + elevation;
    
    // Set the sprite depth
    sprite.setDepth(spriteDepth);
}

// Export for global access
window.setupChairCollisions = setupChairCollisions;
window.setupExistingChairsWithNewRoom = setupExistingChairsWithNewRoom;
window.calculateChairSpinDirection = calculateChairSpinDirection;
window.updateSwivelChairRotation = updateSwivelChairRotation;
window.updateSpriteDepth = updateSpriteDepth;
