import { GYRO_DEADZONE, GYRO_MAX_TILT, GYRO_SENSITIVITY } from '../utils/constants';

/**
 * Gestion du gyroscope pour iOS et Android
 * Retourne une valeur normalisée entre -1 et 1
 */
export class GyroControl {
    private tiltValue: number = 0;
    private isActive: boolean = false;

    constructor() {
        this.setupGyroscope();
    }

    /**
     * Configure les listeners du gyroscope
     * Note: La permission doit avoir été demandée AVANT (via MenuScene sur iOS)
     */
    private setupGyroscope(): void {
        if (!window.DeviceOrientationEvent) {
            console.warn('Gyroscope non disponible sur cet appareil');
            return;
        }

        // Activer directement le gyroscope
        // La permission a déjà été demandée dans MenuScene pour iOS
        this.enableGyroscope();
    }

    /**
     * Active le listener du gyroscope
     */
    private enableGyroscope(): void {
        window.addEventListener('deviceorientation', (event) => {
            this.handleOrientation(event);
        });
        this.isActive = true;
        console.log('✅ Gyroscope activé');
    }

    /**
     * Gère les événements d'orientation
     */
    private handleOrientation(event: DeviceOrientationEvent): void {
        if (!this.isActive) return;

        // Déterminer l'axe horizontal en fonction de l'orientation écran
        const angle = (window.screen.orientation?.angle ?? (window as any).orientation ?? 0) as number;
        const beta = event.beta ?? 0;  // inclinaison avant/arrière
        const gamma = event.gamma ?? 0; // inclinaison gauche/droite

        // En paysage, la gauche/droite correspond à beta; en portrait, à gamma
        let horizontalTiltDeg = gamma;
        if (angle === 90) {
            horizontalTiltDeg = -beta;
        } else if (angle === -90 || angle === 270) {
            horizontalTiltDeg = beta;
        }

        const relativeTilt = horizontalTiltDeg;

        // Appliquer la deadzone
        if (Math.abs(relativeTilt) < GYRO_DEADZONE) {
            this.tiltValue = 0;
            return;
        }

        // Normaliser entre -1 et 1
        let normalizedTilt = relativeTilt / GYRO_MAX_TILT;

        // Clamper entre -1 et 1
        normalizedTilt = Math.max(-1, Math.min(1, normalizedTilt));

        // Inversion gauche/droite (plus naturel selon retour)
        this.tiltValue = -normalizedTilt;
    }

    /**
     * Retourne la valeur actuelle du tilt normalisée (-1 à 1)
     */
    public getTiltValue(): number {
        return this.tiltValue;
    }

    /**
     * Retourne la vitesse calculée depuis le tilt
     */
    public getVelocity(): number {
        return this.tiltValue * GYRO_SENSITIVITY;
    }

    /**
     * Calibre le gyroscope (définit l'orientation actuelle comme neutre)
     */
    public calibrate(): void {
        // Calibration simplifiée : pas de base dynamique, on recentre juste à 0
        this.tiltValue = 0;
    }

    /**
     * Active/désactive le gyroscope
     */
    public setActive(active: boolean): void {
        this.isActive = active;
        if (!active) {
            this.tiltValue = 0;
        }
    }

    /**
     * Vérifie si le gyroscope est actif
     */
    public getIsActive(): boolean {
        return this.isActive;
    }

    /**
     * Détruit le contrôleur (cleanup)
     */
    public destroy(): void {
        this.isActive = false;
        this.tiltValue = 0;
    }
}
