import { IReactionDisposer, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Field, FieldResult } from '../../../../fields/Doc';
import { InkTool } from '../../../../fields/InkField';
import { DocumentManager } from '../../../util/DocumentManager';
import { LinkManager } from '../../../util/LinkManager';
import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { CollectionFreeFormInfoState, InfoState, infoState, StateEntryFunc } from './CollectionFreeFormInfoState';
import { CollectionFreeFormView } from './CollectionFreeFormView';
import './CollectionFreeFormView.scss';
import { StrCast } from '../../../../fields/Types';

export interface CollectionFreeFormInfoUIProps {
    Document: Doc;
    Freeform: CollectionFreeFormView;
    close: () => boolean;
}

@observer
export class CollectionFreeFormInfoUI extends ObservableReactComponent<CollectionFreeFormInfoUIProps> {
    _firstDocPos = { x: 0, y: 0 };

    constructor(props: any) {
        super(props);
        makeObservable(this);
        this.currState = this.setupStates();
    }
    _originalbackground: string | undefined;

    @observable _currState: infoState | undefined = undefined;
    get currState() { return this._currState!; } // prettier-ignore
    set currState(val) { runInAction(() => (this._currState = val)); } // prettier-ignore

    componentWillUnmount(): void {
        this._props.Freeform.layoutDoc.backgroundColor = this._originalbackground;
    }

    setCurrState = (state: infoState) => {
        if (state) {
            this.currState = state;
            this.currState[StateEntryFunc]?.();
        }
    };

    setupStates = () => {
        this._originalbackground = StrCast(this._props.Freeform.layoutDoc.backgroundColor);
        //  state entry functions
        const setBackground = (colour: string) => () => (this._props.Freeform.layoutDoc.backgroundColor = colour);
        const setOpacity = (opacity: number) => () => (this._props.Freeform.layoutDoc.opacity = opacity);
        //  arc transition trigger conditions
        const firstDoc = () => (this._props.Freeform.childDocs.length ? this._props.Freeform.childDocs[0] : undefined);
        const numDocs = () => this._props.Freeform.childDocs.length;

        let docX: FieldResult<Field>;
        let docY: FieldResult<Field>;

        const docNewX = () => firstDoc()?.x;
        const docNewY = () => firstDoc()?.y;

        const linkStart = () => DocumentLinksButton.StartLink;

        const numDocLinks = () => LinkManager.Instance.getAllDirectLinks(firstDoc())?.length;
        const linkMenuOpen = () => DocButtonState.Instance.LinkEditorDocView;

        const activeTool = () => Doc.ActiveTool;

        const pin = () => DocListCast(Doc.ActivePresentation?.data);

        let trail: number;

        const trailView = () => DocumentManager.Instance.DocumentViews.find(view => view.Document === Doc.MyTrails);
        const presentationMode = () => Doc.ActivePresentation?.presentation_status;

        // set of states
        const start = InfoState('Click anywhere and begin typing to create your first text document.', {
            docCreated: [() => numDocs(), () => {
                docX = firstDoc()?.x;
                docY = firstDoc()?.y;
                return oneDoc;
            }],
        }, setBackground("blue")); // prettier-ignore

        const oneDoc = InfoState('Hello world! You can drag and drop to move your document around.', {
            // docCreated: [() => numDocs() > 1, () => multipleDocs],
            docDeleted: [() => numDocs() < 1, () => start],
            docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
                docX = firstDoc()?.x;
                docY = firstDoc()?.y;
                return movedDoc1;
              }],
        }, setBackground("red")); // prettier-ignore

        const movedDoc1 = InfoState('Great moves. Try creating a second document.', {
            docCreated: [() => numDocs() == 2, () => multipleDocs],
            docDeleted: [() => numDocs() < 1, () => start],
            docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
                docX = firstDoc()?.x;
                docY = firstDoc()?.y;
                return movedDoc2;
              }],
        }, setBackground("yellow")); // prettier-ignore

        const movedDoc2 = InfoState('Slick moves. Try creating a second document.', {
            docCreated: [() => numDocs() == 2, () => multipleDocs],
            docDeleted: [() => numDocs() < 1, () => start],
            docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
                docX = firstDoc()?.x;
                docY = firstDoc()?.y;
                return movedDoc3;
              }],
        }, setBackground("pink")); // prettier-ignore

        const movedDoc3 = InfoState('Groovy moves. Try creating a second document.', {
            docCreated: [() => numDocs() == 2, () => multipleDocs],
            docDeleted: [() => numDocs() < 1, () => start],
            docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
                docX = firstDoc()?.x;
                docY = firstDoc()?.y;
                return movedDoc1;
              }],
        }, setBackground("green")); // prettier-ignore

        const multipleDocs = InfoState('Let\'s create a new link. Click the link icon on one of your documents.', {
            linkStarted: [() => linkStart(), () => startedLink],
            docRemoved: [() => numDocs() < 2, () => oneDoc],
        }, setBackground("purple")); // prettier-ignore

        const startedLink = InfoState('Now click the highlighted link icon on your other document.', {
            linkCreated: [() => numDocLinks(), () => madeLink],
            docRemoved: [() => numDocs() < 2, () => oneDoc],
        }, setBackground("orange")); // prettier-ignore

        const madeLink = InfoState('You made your first link! You can view your links by selecting the blue dot.', {
            linkCreated: [() => !numDocLinks(), () => multipleDocs],
            linkViewed: [() => linkMenuOpen(), () => {
                alert(numDocLinks() + " cheer for " + numDocLinks() + " link!");
                return viewedLink;
            }],
        }, setBackground("blue")); // prettier-ignore

        const viewedLink = InfoState('Great work. You are now ready to create your own hypermedia world.', {
            linkDeleted: [() => !numDocLinks(), () => multipleDocs],
            docRemoved: [() => numDocs() < 2, () => oneDoc],
            docCreated: [() => numDocs() == 3, () => {
                trail = pin().length;
                return presentDocs;
            }],
            activePen: [() => activeTool() === InkTool.Pen, () => penMode],
        }, setBackground("black")); // prettier-ignore

        const presentDocs = InfoState(
            'Another document! You could make a presentation. Click the pin icon in the top left corner.',
            {
                docPinned: [
                    () => pin().length > trail,
                    () => {
                        trail = pin().length;
                        return pinnedDoc1;
                    },
                ],
                docRemoved: [() => numDocs() < 3, () => viewedLink],
            },
            setBackground('black'),
            '/assets/dash-pin-with-view.gif'
        );

        const penMode = InfoState('You\'re in pen mode. Click and drag to draw your first masterpiece.', {
            // activePen: [() => activeTool() === InkTool.Eraser, () => eraserMode],
            activePen: [() => activeTool() !== InkTool.Pen, () => viewedLink],
        }); // prettier-ignore

        // const eraserMode = InfoState('You\'re in eraser mode. Say goodbye to your first masterpiece.', {
        //     docsRemoved: [() => numDocs() == 3, () => demos],
        // }); // prettier-ignore

        const pinnedDoc1 = InfoState('You just pinned your doc.', {
            docPinned: [
                () => pin().length > trail,
                () => {
                    trail = pin().length;
                    return pinnedDoc2;
                },
            ],
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
        });

        const pinnedDoc2 = InfoState(`You pinned another doc.`, {
            docPinned: [
                () => pin().length > trail,
                () => {
                    trail = pin().length;
                    return pinnedDoc3;
                },
            ],
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
        });

        const pinnedDoc3 = InfoState(`You pinned yet another doc.`, {
            docPinned: [
                () => pin().length > trail,
                () => {
                    trail = pin().length;
                    return pinnedDoc2;
                },
            ],
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
        });

        // const openedTrail = InfoState('This is your trails tab.', {
        //     trailView: [() => presentationMode() === 'edit', () => editPresentationMode],
        // });

        // const editPresentationMode = InfoState('You are editing your presentation.', {
        //     manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
        //     autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
        //     docRemoved: [() => numDocs() < 3, () => demos],
        //     docCreated: [() => numDocs() == 4, () => completed],
        // });

        const manualPresentationMode = InfoState("You're in manual presentation mode.", {
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
            docCreated: [() => numDocs() == 4, () => completed],
        });

        const autoPresentationMode = InfoState("You're in auto presentation mode.", {
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
            docCreated: [() => numDocs() == 4, () => completed],
        });

        const completed = InfoState('Eager to learn more? Click the ? icon in the top right corner to read our full documentation.', {
            docRemoved: [() => numDocs() == 1, () => oneDoc],
        }, setBackground("white")); // prettier-ignore

        return start;
    };

    render() {
        return <CollectionFreeFormInfoState next={this.setCurrState} close={this._props.close} infoState={this.currState} />;
    }
}
