import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { returnTrue } from '../../../ClientUtils';
import { Doc, Opt, StrListCast } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { NumCast, StrCast } from '../../../fields/Types';
import { Docs } from '../../documents/Documents';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { FieldsDropdown } from '../FieldsDropdown';
import { PinDocView } from '../PinFuncs';
import { DocumentView } from '../nodes/DocumentView';
import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
import './CollectionTimeView.scss';
import { ViewDefBounds, computePivotLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';

@observer
export class CollectionPivotView extends CollectionSubView() {
    _changing = false;
    @observable _collapsed: boolean = false;
    @observable _childClickedScript: Opt<ScriptField> = undefined;
    @observable _viewDefDivClick: Opt<ScriptField> = undefined;
    @observable _focusPivotField: Opt<string> = undefined;

    constructor(props: SubCollectionViewProps) {
        super(props);
        makeObservable(this);
    }

    componentDidMount() {
        this._props.setContentViewBox?.(this);
        runInAction(() => {
            this._childClickedScript = ScriptField.MakeScript('openInLightbox(this)', { this: Doc.name });
            this._viewDefDivClick = ScriptField.MakeScript('pivotColumnClick(this,payload)', { payload: 'any' });
        });
    }

    get pivotField() {
        return this._focusPivotField || StrCast(this.layoutDoc._pivotField);
    }

    getAnchor = (addAsAnnotation: boolean) => {
        const anchor = Docs.Create.ConfigDocument({
            title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as unknown as string, // title can take a functiono or a string
            annotationOn: this.Document,
        });
        PinDocView(anchor, { pinData: { collectionType: true, pivot: true, filters: true } }, this.Document);
        addAsAnnotation && Doc.AddDocToList(this.dataDoc, this.fieldKey + '_annotations', anchor); // when added as an annotation, links to anchors can be found as links to the document even if the anchors are not rendered
        return anchor;
    };

    @action
    scrollPreview = (docView: DocumentView, anchor: Doc /* , focusSpeed: number, options: FocusViewOptions */) => {
        // if in preview, then override document's fields with view spec
        this._focusFilters = StrListCast(anchor.config_docFilters);
        this._focusRangeFilters = StrListCast(anchor.config_docRangeFilters);
        this._focusPivotField = StrCast(anchor.config_pivotField);
        return undefined;
    };

    toggleVisibility = action(() => {
        this._collapsed = !this._collapsed;
    });

    goTo = (prevFilterIndex: number) => {
        this.layoutDoc._pivotField = this.layoutDoc['_prevPivotFields' + prevFilterIndex];
        this.layoutDoc._childFilters = ObjectField.MakeCopy(this.layoutDoc['_prevDocFilter' + prevFilterIndex] as ObjectField);
        this.layoutDoc._childFiltersByRanges = ObjectField.MakeCopy(this.layoutDoc['_prevDocRangeFilters' + prevFilterIndex] as ObjectField);
        this.layoutDoc._prevFilterIndex = prevFilterIndex;
    };

    @action
    contentsDown = () => {
        const prevFilterIndex = NumCast(this.layoutDoc._prevFilterIndex);
        if (prevFilterIndex > 0) {
            this.goTo(prevFilterIndex - 1);
        } else {
            this.layoutDoc._childFilters = new List([]);
        }
    };
    layoutEngine = () => computePivotLayout.name;
    @computed get contents() {
        return (
            <div className="collectionTimeView-innards" key="timeline" style={{ pointerEvents: this._props.isContentActive() ? undefined : 'none' }} onClick={this.contentsDown}>
                <CollectionFreeFormView
                    {...this._props}
                    engineProps={{ pivotField: this.pivotField, childFilters: this.childDocFilters, childFiltersByRanges: this.childDocRangeFilters }}
                    fitContentsToBox={returnTrue}
                    childClickScript={this._childClickedScript}
                    viewDefDivClick={this._viewDefDivClick}
                    layoutEngine={this.layoutEngine}
                />
            </div>
        );
    }

    render() {
        return (
            <div className="collectionTimeView-pivot" style={{ width: this._props.PanelWidth(), height: '100%' }}>
                {this.contents}
                <div style={{ right: 0, top: 0, position: 'absolute' }}>
                    <FieldsDropdown Doc={this.Document} isInactive={!this._props.isContentActive()} selectFunc={fieldKey => (this.layoutDoc._pivotField = fieldKey)} placeholder={StrCast(this.layoutDoc._pivotField)} />
                </div>
            </div>
        );
    }
}

// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function pivotColumnClick(pivotDoc: Doc, bounds: ViewDefBounds) {
    const pivotField = StrCast(pivotDoc._pivotField, 'author');
    let prevFilterIndex = NumCast(pivotDoc._prevFilterIndex);
    const originalFilter = StrListCast(ObjectField.MakeCopy(pivotDoc._childFilters as ObjectField));
    pivotDoc['_prevDocFilter' + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._childFilters as ObjectField);
    pivotDoc['_prevDocRangeFilters' + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._childFiltersByRanges as ObjectField);
    pivotDoc['_prevPivotFields' + prevFilterIndex] = pivotField;
    pivotDoc._prevFilterIndex = ++prevFilterIndex;
    pivotDoc._childFilters = new List();
    setTimeout(
        action(() => {
            const filterVals = bounds.payload as string[];
            filterVals.map(filterVal => Doc.setDocFilter(pivotDoc, pivotField, filterVal, 'check'));
            const pivotView = DocumentView.getDocumentView(pivotDoc);
            if (pivotDoc && pivotView?.ComponentView instanceof CollectionPivotView && filterVals.length === 1) {
                if (pivotView?.ComponentView.childDocs.length && pivotView.ComponentView.childDocs[0][filterVals[0]]) {
                    pivotDoc._pivotField = filterVals[0];
                }
            }
            const newFilters = StrListCast(pivotDoc._childFilters);
            if (newFilters.length && originalFilter.length && newFilters.lastElement() === originalFilter.lastElement()) {
                pivotDoc._prevFilterIndex = --prevFilterIndex;
                pivotDoc['_prevDocFilter' + prevFilterIndex] = undefined;
                pivotDoc['_prevDocRangeFilters' + prevFilterIndex] = undefined;
                pivotDoc['_prevPivotFields' + prevFilterIndex] = undefined;
            }
        })
    );
});
