/**
 * This file is part of Anis Client.
 *
 * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

import { Injectable } from '@angular/core';

import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { map, tap, mergeMap, catchError } from 'rxjs/operators';
import { ToastrService } from 'ngx-toastr';

import { SampService } from '../services/samp.service';
import * as sampActions from '../actions/samp.actions';

/**
 * @class
 * @classdesc Samp effects.
 */
@Injectable()
export class SampEffects {

    /**
     * Calls actions to register.
     */
    register$ = createEffect((): any =>
        this.actions$.pipe(
            ofType(sampActions.register),
            mergeMap(() => this.sampService.register()
                .pipe(
                    map(() => sampActions.registerSuccess()),
                    catchError(() => of(sampActions.registerFail()))
                )
            )
        )
    );

    /**
     * Displays register success notification.
     */
    registerSuccess$ = createEffect(() =>
        this.actions$.pipe(
            ofType(sampActions.registerSuccess),
            tap(() => this.toastr.success('You are now connected to a SAMP-hub', 'SAMP-hub register success'))
        ),
        { dispatch: false }
    );

    /**
     * Displays register error notification.
     */
    registerFail$ = createEffect(() =>
        this.actions$.pipe(
            ofType(sampActions.registerFail),
            tap(() => this.toastr.error('Connection to a SAMP-hub has failed', 'SAMP-hub register fail'))
        ),
        { dispatch: false }
    );

    /**
     * Calls actions to disconnect.
     */
    unregister$ = createEffect(() =>
        this.actions$.pipe(
            ofType(sampActions.unregister),
            tap(() => {
                this.sampService.unregister();
            })
        ),
        { dispatch: false }
    );

    /**
     * Calls actions to broadcast.
     */
    broadcastVotable$ = createEffect(() =>
        this.actions$.pipe(
            ofType(sampActions.broadcastVotable),
            tap(action => {
                this.sampService.broadcast('table.load.votable', action.url)
            })
        ),
        { dispatch: false }
    );

    constructor(
        private actions$: Actions,
        private sampService: SampService,
        private toastr: ToastrService
    ) {}
}