import { state } from '../state.js';
import { SceneFeature } from './SceneFeature.js';
import sceneFeatureManager from './SceneFeatureManager.js';

export class MusicPlayer extends SceneFeature {
    constructor() {
        super();
        this.audioContext = null;
        this.analyser = null;
        this.source = null;
        this.dataArray = null;
        this.loudnessHistory = [];
        sceneFeatureManager.register(this);
    }

    init() {
        state.music.player = document.getElementById('audioPlayer');
        state.music.loudness = 0;
        state.music.isLoudEnough = false;

        const loadButton = document.getElementById('loadMusicButton');
        const fileInput = document.getElementById('musicFileInput');
        const uiContainer = document.getElementById('ui-container');
        const metadataContainer = document.getElementById('metadata-container');
        const songTitleElement = document.getElementById('song-title');

        loadButton.addEventListener('click', () => {
            fileInput.click();
        });

        fileInput.addEventListener('change', (event) => {
            const file = event.target.files[0];
            if (file) {
                // Setup Web Audio API if not already done
                if (!this.audioContext) {
                    this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
                    this.analyser = this.audioContext.createAnalyser();
                    this.analyser.fftSize = 128; // Lower resolution is fine for loudness
                    this.source = this.audioContext.createMediaElementSource(state.music.player);
                    this.source.connect(this.analyser);
                    this.analyser.connect(this.audioContext.destination);
                    this.dataArray = new Uint8Array(this.analyser.frequencyBinCount);
                }

                // Hide the main button
                loadButton.style.display = 'none';

                // Show metadata
                songTitleElement.textContent = file.name.replace(/\.[^/.]+$/, ""); // Show filename without extension
                metadataContainer.classList.remove('hidden');

                const url = URL.createObjectURL(file);
                state.music.player.src = url;

                // Wait 5 seconds, then start the party
                setTimeout(() => {
                    metadataContainer.classList.add('hidden');
                    this.startParty();
                }, 5000);
            }
        });

        state.music.player.addEventListener('ended', () => {
            this.stopParty();
            uiContainer.style.display = 'flex'; // Show the button again
        });
    }

    startParty() {
        state.clock.start();
        state.music.player.play();
        document.getElementById('ui-container').style.display = 'none';
        state.partyStarted = true;

        // You could add BPM detection here in the future
        // For now, we use the fixed BPM

        // Trigger 'start' event for other features
        this.notifyFeatures('onPartyStart');
    }

    stopParty() {
        state.clock.stop();
        state.partyStarted = false;
        setTimeout(() => {
            const startButton = document.getElementById('loadMusicButton');
            startButton.style.display = 'block';
            startButton.textContent = "Party some more?"
        }, 5000);
        // Trigger 'end' event for other features
        this.notifyFeatures('onPartyEnd');
    }

    notifyFeatures(methodName) {
        sceneFeatureManager.features.forEach(feature => {
            if (typeof feature[methodName] === 'function') {
                feature[methodName]();
            }
        });
    }

    update(deltaTime) {
        if (!state.partyStarted || !this.analyser) return;

        this.analyser.getByteFrequencyData(this.dataArray);

        // --- Calculate current loudness ---
        let sum = 0;
        for (let i = 0; i < this.dataArray.length; i++) {
            sum += this.dataArray[i];
        }
        const average = sum / this.dataArray.length;
        state.music.loudness = average / 255; // Normalize to 0-1 range

        // --- Track loudness over the last 2 seconds ---
        this.loudnessHistory.push(state.music.loudness);
        if (this.loudnessHistory.length > 120) { // Assuming ~60fps, 2 seconds of history
            this.loudnessHistory.shift();
        }

        // --- Determine if it's loud enough to jump ---
        const avgLoudness = this.loudnessHistory.reduce((a, b) => a + b, 0) / this.loudnessHistory.length;
        const quietThreshold = 0.1; // Adjust this value based on testing

        state.music.isLoudEnough = avgLoudness > quietThreshold;
    }
}

new MusicPlayer();