import React, {Dispatch, SetStateAction, ComponentType} from 'react';
import {Subject} from 'rxjs';
import {ModalContentComponent} from './modal-content-component';
import {Modal, ModalProps} from './modal';
import {ModalRef} from './modal-ref';

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

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

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

    open<In extends Record<string, unknown>, Out>(
        ContentComponent: ModalContentComponent<In, Out>,
        contentProps: In,
        modalOptions: Omit<ModalProps<any>, 'onClose'>
    ): ModalRef<Out | unknown> {
        const closeEmitter = new Subject<Out | unknown>();
        const ModalComponent: ComponentType<unknown> = () => (
            <Modal<Out>
                {...modalOptions}
                onClose={res => closeEmitter.next(res)}
            >
                <ContentComponent
                    {...contentProps}
                    closeModal={(res) => closeEmitter.next(res)}
                />
            </Modal>
        );

        const ref = new ModalRef(closeEmitter, ModalComponent);
        const sub = closeEmitter.subscribe(() => {
            this.list = this.list.filter(elm => elm !== ref);
            sub.unsubscribe();
        });
        this.list = [...this.list, ref];

        return ref;
    }

    close<Out>(result: Out, ref: ModalRef<Out>) {
        (ref || [...this.list].pop())?.close(result);
    }
}
