import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
import { ScriptField } from '../../../../fields/ScriptField';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import './CollectionFreeFormView.scss';

export interface CollectionFreeFormPannableContentsProps {
    Document: Doc;
    viewDefDivClick?: ScriptField;
    children?: React.ReactNode | undefined;
    transition: () => string;
    isAnnotationOverlay: boolean | undefined;
    showPresPaths: () => boolean;
    transform: () => string;
    brushedView: () => { panX: number; panY: number; width: number; height: number } | undefined;
}

@observer
export class CollectionFreeFormPannableContents extends ObservableReactComponent<CollectionFreeFormPannableContentsProps> {
    static _overlayPlugin: ((fform: Doc) => React.JSX.Element) | null = null;
    /**
     * Setup a plugin function that returns components to display on a layer above the collection
     *     See PresBox which renders presenstation paths over the collection
     * @param plugin a function that receives the collection Doc and returns JSX Elements
     */
    public static SetOverlayPlugin(plugin: ((fform: Doc) => React.JSX.Element) | null) {
        CollectionFreeFormPannableContents._overlayPlugin = plugin;
    }
    constructor(props: CollectionFreeFormPannableContentsProps) {
        super(props);
        makeObservable(this);
    }
    @computed get presPaths() {
        return this._props.showPresPaths() ? CollectionFreeFormPannableContents._overlayPlugin?.(this._props.Document) : null;
    }
    // rectangle highlight used when following trail/link to a region of a collection that isn't a document
    showViewport = (viewport: { panX: number; panY: number; width: number; height: number } | undefined) =>
        !viewport ? null : (
            <div
                className="collectionFreeFormView-brushView"
                style={{
                    transform: `translate(${viewport.panX}px, ${viewport.panY}px)`,
                    width: viewport.width,
                    height: viewport.height,
                    border: `orange solid ${viewport.width * 0.005}px`,
                }}
            />
        );

    render() {
        return (
            <div
                className={'collectionfreeformview' + (this._props.viewDefDivClick ? '-viewDef' : '-none')}
                onScroll={e => {
                    const { target } = e;
                    if (target instanceof Element && getComputedStyle(target)?.overflow === 'visible') {
                        target.scrollTop = target.scrollLeft = 0; // if collection is visible, scrolling messes things up since there are no scroll bars
                    }
                }}
                style={{
                    transform: this._props.transform(),
                    transition: this._props.transition(),
                    width: this._props.isAnnotationOverlay ? undefined : 0, // if not an overlay, then this will be the size of the collection, but panning and zooming will move it outside the visible border of the collection and make it selectable.  This problem shows up after zooming/panning on a background collection -- you can drag the collection by clicking on apparently empty space outside the collection
                }}>
                {this.props.children}
                {this.presPaths}
                {this.showViewport(this._props.brushedView())}
            </div>
        );
    }
}
