import * as React from 'react';
import { Subject } from 'rxjs';
import { filter, map, takeUntil } from 'rxjs/operators';
import { constants, css, R, util } from '../common';
const CSS = constants.CSS;
export class DataGridOverlay extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.state = {};
        this.state$ = new Subject();
        this.unmounted$ = new Subject();
    }
    componentDidMount() {
        const { grid } = this.props;
        this.state$.pipe(takeUntil(this.unmounted$)).subscribe((e) => this.setState(e));
        const events$ = grid.events$.pipe(takeUntil(this.unmounted$));
        const command$ = events$.pipe(filter((e) => e.type === 'GRID/command'), map((e) => e.payload));
        command$
            .pipe(filter((e) => e.command === 'OVERLAY/show'), map((e) => e), filter((e) => !R.equals(e.props.screen, this.state.screen)))
            .subscribe((e) => {
            const key = e.props.cell;
            const screen = e.props.screen;
            if (key && screen) {
                this.show({ key, screen });
            }
        });
        command$
            .pipe(filter((e) => e.command === 'OVERLAY/hide'), filter(() => this.isShowing))
            .subscribe((e) => this.hide());
    }
    componentWillUnmount() {
        this.unmounted$.next();
        this.unmounted$.complete();
    }
    get isShowing() {
        return Boolean(this.state.screen);
    }
    get key() {
        return this.state.key;
    }
    get data() {
        return this.getData(this.key);
    }
    get request() {
        const { screen } = this.state;
        const key = this.key;
        const data = this.data;
        if (!screen || !data || !key) {
            return undefined;
        }
        else {
            const props = util.toGridCellProps(data.props);
            const view = props.view;
            const req = {
                type: 'SCREEN',
                grid: this.props.grid,
                cell: { key, data, props },
                view,
            };
            return req;
        }
    }
    getData(key) {
        return this.props.grid.data.cells[key] || {};
    }
    show(args) {
        const { key, screen, Provider } = args;
        this.state$.next({ key, screen, Provider });
    }
    hide() {
        this.state$.next({
            key: undefined,
            screen: undefined,
            Provider: undefined,
        });
    }
    render() {
        const req = this.request;
        const { screen, Provider } = this.state;
        const { factory } = this.props;
        if (!req || !screen || !Provider) {
            return null;
        }
        const styles = {
            base: css({
                Absolute: 0,
                display: 'flex',
                backgroundColor: 'rgba(0, 0, 0, 0)',
                zIndex: 9999,
            }),
        };
        const className = `${CSS.CLASS.SCREEN.BASE} ${screen.className || ''}`;
        return (React.createElement("div", Object.assign({}, css(styles.base, this.props.style), { className: className }),
            React.createElement(Provider, null, factory(req))));
    }
}
