import { eventTarget, PLAY_ROLLING_SOUND } from "../Events";
import { Global } from "../Global";

const { ccclass, property } = cc._decorator;

@ccclass
export default class DevicemotionController extends cc.Component {
    @property(cc.Node)
    private jarNode: cc.Node;

    private _x: number = 0;
    private _y: number = 0;
    private _z: number = 0;
    private _count = 0;
    private _isShake = false;

    protected onLoad(): void {
        if (cc.sys.os === cc.sys.OS_IOS && !Global.deviceMotionPermission) {
            this.node.on('click', this.setDeviceMotionIOS, this);
        }
        else {
            this.scheduleOnce(this.setDeviceMotion, 1);
        }
    }

    private setDeviceMotionIOS() {
        if (window.DeviceMotionEvent) {
            if (typeof (DeviceMotionEvent as any).requestPermission === 'function') {
                (DeviceMotionEvent as any).requestPermission()
                    .then(permissionState => {
                        if (permissionState === 'granted') {
                            Global.deviceMotionPermission = true;
                            this.setDeviceMotion();
                        } else {
                            console.log('Không được cấp quyền sử dụng DeviceMotion');
                        }
                    })
                    .catch(e => {
                        console.error(e);
                    });
            } else {
                this.setDeviceMotion();
            }
        } else {
            console.log('Trình duyệt không hỗ trợ DeviceMotion API');
        }
    }

    private setDeviceMotion() {
        window.addEventListener("devicemotion", (event) => {
            if (!event.accelerationIncludingGravity) {
                return;
            }

            const x = event.accelerationIncludingGravity.x;
            const y = event.accelerationIncludingGravity.y;
            const z = event.accelerationIncludingGravity.z;

            if (x - this._x > 5 || y - this._y > 5 || z - this._z > 5) {
                if (this._isShake) {
                    this._count++;
                }
            }

            if (x - this._x < -5 || y - this._y < -5 || z - this._z < -5) {
                if (!this._isShake) {
                    this._count++;
                }
            }

            if (this._count > 0) {
                this.scheduleOnce(() => {
                    this._count = 0;
                }, 2)
            }

            if (this._count > 5) {
                this._count = 0;
                this.shakeBottle();
            }

            this._x = x;
            this._y = y;
            this._z = z;
        });
    }

    private shakeBottle() {
        eventTarget.emit(PLAY_ROLLING_SOUND);
        cc.tween(this.jarNode)
            .repeat(5, cc.tween(this.jarNode)
                .call(() => this.vibratePhone())
                .to(0.2, { position: cc.v3(40, this.randomY(), 0) })
                .to(0.2, { position: cc.v3(-40, this.randomY(), 0) })
            )
            .to(0.2, { position: cc.v3(0, 0, 0) })
            .start();
    }

    private vibratePhone() {
        if ("vibrate" in navigator) {
            navigator.vibrate(200);
        } else {
            console.log("Trình duyệt không hỗ trợ vibrate");
        }
    }

    private randomY(): number {
        return Math.random() * 100 - 50;
    }
}
