import ViewEmitter from "../notification/ViewEmitter.js";
import AnimationTrack from "../../animation/keyed2/AnimationTrack.js";
import TransitionFunctions from "../../animation/TransitionFunctions.js";
import { assert } from "../../../core/assert.js";
import NotificationView from "../../../view/elements/notify/NotificationView.js";
import { NotificationAreaKind } from "../notification/NotificationAreaKind.js";

function makePrimary() {
    /**
     *
     * @type {ViewEmitter<Notification>}
     */
    const viewEmitter = new ViewEmitter();
    viewEmitter.setRushThreshold(1);
    viewEmitter.setSpawnDelay(2);

    const animationTrack = new AnimationTrack(["alpha", "scale"]);
    animationTrack.addKey(0, [0, 1.3]);
    animationTrack.addKey(0.6, [1, 1]);
    animationTrack.addKey(2.9, [1, 1]);
    animationTrack.addKey(3.4, [0, 1]);

    animationTrack.addTransition(0, TransitionFunctions.EaseIn);
    animationTrack.addTransition(2, TransitionFunctions.EaseOut);

    viewEmitter.setAnimation(animationTrack, function (alpha, scale) {
        /**
         * @type View
         */
        const view = this;

        view.el.style.opacity = alpha;
        view.scale.set(scale, scale);
    });

    viewEmitter.viewFactory = function (options) {
        assert.notEqual(options, undefined, 'options is undefined');

        const notificationView = new NotificationView(options);

        return notificationView;
    };


    return viewEmitter;
}

function makeSecondary() {
    /**
     *
     * @type {ViewEmitter<Notification>}
     */
    const viewEmitter = new ViewEmitter();
    viewEmitter.setRushThreshold(1);
    viewEmitter.setSpawnDelay(0.7);

    const animationTrack = new AnimationTrack(["alpha", "position.y", "scale"]);
    animationTrack.addKey(0, [0.2, 0, 1.1]);
    animationTrack.addKey(0.17, [1, 0, 1]);
    animationTrack.addKey(3.2, [1, -60, 1]);
    animationTrack.addKey(3.7, [0, -70, 1]);

    animationTrack.addTransition(0, TransitionFunctions.EaseIn);
    animationTrack.addTransition(1, TransitionFunctions.Linear);
    animationTrack.addTransition(2, TransitionFunctions.EaseOut);

    viewEmitter.setAnimation(animationTrack, function (alpha, positionY, scale) {
        /**
         * @type View
         */
        const view = this;

        view.el.style.opacity = alpha;
        view.position.setY(positionY);
        view.scale.set(scale, scale);
    });


    viewEmitter.viewFactory = function (options) {
        const notificationView = new NotificationView(options);

        return notificationView;
    };

    return viewEmitter;
}

function makeToast() {
    const displayDuration = 7.5;

    /**
     *
     * @type {ViewEmitter<Notification>}
     */
    const viewEmitter = new ViewEmitter();
    viewEmitter.setRushThreshold(5);
    viewEmitter.setSpawnDelay(0.1);

    const animationTrack = new AnimationTrack(["alpha", "position.x"]);
    animationTrack.addKey(0, [0.2, 100]);
    animationTrack.addKey(0.17, [1, 0]);
    animationTrack.addKey(displayDuration, [1, 0]);
    animationTrack.addKey(displayDuration + 0.5, [0, 0]);

    animationTrack.addTransition(0, TransitionFunctions.EaseIn);
    animationTrack.addTransition(1, TransitionFunctions.Linear);
    animationTrack.addTransition(2, TransitionFunctions.EaseOut);

    viewEmitter.setAnimation(animationTrack, function (alpha, position_x) {
        /**
         * @type View
         */
        const view = this;

        view.el.style.opacity = alpha;
        view.position.setX(position_x);
    });


    viewEmitter.viewFactory = function (options) {
        const notificationView = new NotificationView(options);

        return notificationView;
    };

    return viewEmitter;
}

/**
 *
 * @param {NotificationManager} manager
 */
export function initializeNotifications(manager) {

    manager.createChannel(NotificationAreaKind.Primary);
    manager.createChannel(NotificationAreaKind.Secondary);
    manager.createChannel(NotificationAreaKind.Toast);

    manager.addEmitterDisplay(NotificationAreaKind.Primary, makePrimary());
    manager.addEmitterDisplay(NotificationAreaKind.Secondary, makeSecondary());
    manager.addEmitterDisplay(NotificationAreaKind.Toast, makeToast(), 'managed-toast-notifications');

    // testNotifications(manager);
}
