import {Dispatch, SetStateAction, FunctionComponent} from 'react';
import {timer as rxTimer, Subject, race} from 'rxjs';
import {SnackbarType} from './snackbar-type.enum';
import {SnackbarRef} from './snackbar-ref';
import {SnackbarItem} from './snackbar-item';

const defaultDuration = 5000;

export class SnackbarManager {
    constructor(
        private _list: SnackbarRef[],
        private setList: Dispatch<SetStateAction<SnackbarRef[]>>
    ) {}

    get list(): SnackbarRef[] {
        return this._list;
    }

    set list(val: SnackbarRef[]) {
        this._list = val;
        this.setList(val);
    }

    private open(text: string, type: SnackbarType, duration: number) {
        const closeEmitter = new Subject<unknown>();
        const SnackbarComponet: FunctionComponent = () => (
            <SnackbarItem
                message={text}
                type={type}
                onClose={() => closeEmitter.next(null)}
            />
        );

        const ref = new SnackbarRef(closeEmitter, SnackbarComponet);
        const sub = race(rxTimer(duration), closeEmitter.asObservable()).subscribe(() => {
            this.list = this.list.filter(elm => elm !== ref);
            sub.unsubscribe();
        });

        this.list = [...this.list, ref];
    }

    success(text: string, duration: number = defaultDuration) {
        this.open(text, SnackbarType.Success, duration);
    }

    error(text: string, duration: number = defaultDuration) {
        this.open(text, SnackbarType.Error, duration);
    }

    warning(text: string, duration: number = defaultDuration) {
        this.open(text, SnackbarType.Warning, duration);
    }

    comparisonInfo(text: string, duration: number = defaultDuration) {
        this.open(text, SnackbarType.ComparisonInfo, duration);
    }
}
