import { Player } from '../player.js';
import { CycleManager } from '../cycle.js';
import { ObjectManager } from '../objects.js';
import { InventoryManager } from '../inventory.js';

export class Game extends Phaser.Scene {
    constructor() {
        super({ key: 'Game' });
        this.cycleManager = null;
        this.objectManager = null;
        this.mainLayer = null;
    }

    preload() {
        this.load.tilemapTiledJSON('game-map', 'assets/game-map.json');
        this.load.spritesheet('player', 'assets/images/player.png', {
            frameWidth: 100, 
            frameHeight: 100 
        });
        this.load.spritesheet('objects', 'assets/images/objects.png', {
            frameWidth: 100, 
            frameHeight: 100 
        });

        // Images
        this.load.image('terrain-tileset', 'assets/images/terrain.png');
        this.load.image('backpack', 'assets/images/backpack.png');
        this.load.image('inventory', 'assets/images/inventory.png');
        this.load.image('craftDrop', 'assets/images/craftDrop.png');
        // FX
        this.load.audio('chop', 'assets/fx/chop.mp3');
        this.load.audio('zip', 'assets/fx/zip.mp3');
        this.load.audio('inventory', 'assets/fx/inventory.mp3');

        // Music
        this.load.audio('bgMusic', 'assets/music/bgMusic.mp3');
    }

    create() {
        // Create tilemap
        const map = this.make.tilemap({ key: 'game-map' });
        
        // Add tileset to map
        const terrainTileset = map.addTilesetImage('terrain', 'terrain-tileset');
        
        // Create layer named "main"
        this.mainLayer = map.createLayer('main', terrainTileset, 0, 0)
            .setCollisionByProperty({ collides: true });

        // Set world bounds based on tilemap dimensions
        const worldWidth = map.widthInPixels;
        const worldHeight = map.heightInPixels;
        this.physics.world.setBounds(0, 0, worldWidth, worldHeight);

        // Initialize object manager
        this.objects = this.physics.add.group();
        this.items = this.physics.add.group();
        this.objectManager = new ObjectManager(this);
        this.objectManager.init();

        // Create player at center of screen
        this.player = new Player(this, 1600, 3100);

        // Initialize inventory manager
        this.inventoryManager = new InventoryManager(this);
        this.inventoryManager.init();

        // Physics Collisions
        this.physics.add.collider(this.player, this.mainLayer);
        this.physics.add.collider(this.player, this.objects, (player, object) => {
            player.stop();
            this.objectManager.takeDamage(object, player);
        });
        this.physics.add.collider(this.player, this.items, (player, item) => {
            if (item.props.collected === true) {
                return;
            }
            item.props.collected = true;
            player.stop();
            this.inventoryManager.addItem(item);
            const cam = this.cameras.main.worldView;
            this.sound.play('zip');
            this.tweens.add({
                targets: item,
                x: cam.x+cam.width-150,
                y: cam.y+cam.height-150,
                duration: 500,
                onComplete: () => {
                    this.sound.play('inventory');
                    item.destroy();
                }
            });
        });

        // Make camera follow the player
        this.cameras.main.startFollow(this.player);
        this.cameras.main.setBounds(0, 0, worldWidth, worldHeight);

        // Initialize cycle manager
        this.cycleManager = new CycleManager(this);
        this.cycleManager.init();

        // Background Music
        this.bgMusic = this.sound.add('bgMusic', { volume: 0.5 });
        this.bgMusic.loop = true;
        this.bgMusic.play();
    }

    update(time, delta) {
        // Update player
        if (this.player) {
            this.player.update();
        }

        // Update cycle manager
        if (this.cycleManager) {
            this.cycleManager.update(delta);
            
            // Apply tint to main layer when needed
            if (this.mainLayer && this.cycleManager.getCurrentCycle() !== 'day') {
                this.cycleManager.applyTint(this.mainLayer);
            }
        }

        // Update object manager
        if (this.objectManager) {
            this.objectManager.update(delta);
        }

        if (this.inventoryManager) {
            this.inventoryManager.update(delta);
        }
    }
}