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

export interface CollectionFreeFormInfoUIProps {
    Document: Doc;
    Freeform: CollectionFreeFormView;
}

@observer
export class CollectionFreeFormInfoUI extends ObservableReactComponent<CollectionFreeFormInfoUIProps> {
    private _disposers: { [name: string]: IReactionDisposer } = {};

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

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

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

    setupStates = () => {
        //  state entry functions
        const setBackground = (col: string) => () => (this._props.Freeform.layoutDoc.backgroundColor = col);
        //  arc transition trigger conditions
        const firstDoc = () => this._props.Freeform.childDocs.lastElement();
        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;

        let pinned : FieldResult<Field>;
        const pin = () => Doc.ActivePresentation?.data;
        const trail = () => 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("green")); // 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("green")); // 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("green")); // 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("orange")); // 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("yellow")); // 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, () => {
                pinned = pin();
                return demos;
            }],
            // docPinned: [() => pin(), () => pinnedDoc],
        }, setBackground("white")); // prettier-ignore

        const demos = InfoState('Wanna explore more?', {
            // activePen: [() => activeTool() === InkTool.Pen, () => penMode],
            docPinned: [() => pinned && pinned != pin(), () => pinnedDoc],
        });

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

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

        const pinnedDoc = InfoState('You just pinned your doc.', {
            editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            // autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => demos],
        });
        
        // 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('Manual presentation mode.', {
            editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => demos],
            docCreated: [() => numDocs() == 4, () => completed],
        });

        const autoPresentationMode = InfoState('Auto presentation mode.', {
            editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            docRemoved: [() => numDocs() < 3, () => demos],
            docCreated: [() => numDocs() == 4, () => completed],
        });

        const completed = InfoState('Eager to learn more? Click the ? icon to read our full documentation', {
            //
        }, setBackground("white")); // prettier-ignore

        return start;
    };

    /*
    componentDidMount(): void {
        this._disposers.reaction1 = reaction(
            () => this._props.Freeform.childDocs.slice(),
            docs => {
                if (docs.length === 1) {
                    this.firstDoc = docs[0];
                    this.firstDocPos = { x: NumCast(this.firstDoc.x), y: NumCast(this.firstDoc.y) };
                    this.message = 'Hello world! You can drag and drop to move your document around.';
                } else if (docs.length === 2) {
                    this.message = 'Great job. To create a new link between them, click the link icon on both documents.';
                } else {
                    // this.message = 'Click anywhere and begin typing to create your first text document!';
                }
            },
            { fireImmediately: true }
        );
        this._disposers.reaction2 = reaction(
            () => ({ x: NumCast(this.firstDoc?.x), y: NumCast(this.firstDoc?.y), links: this.firstDoc && LinkManager.Instance.getAllDirectLinks(this.firstDoc) }),
            ({ x, y, links }) => {
                if ((x && x != this.firstDocPos.x) || (y && y != this.firstDocPos.y)) {
                    this.message = 'Great moves. Try creating a second document.';
                }
                if (links && links.length > 0) {
                    this.message = 'You made your first link! You can view your links by selecting the blue dot.';
                }
            },
            { fireImmediately: true }
        );
        this._disposers.reaction3 = reaction(
            () => ({ activeTool: Doc.ActiveTool, viewingLinks: DocumentLinksButton.LinkEditorDocView }),
            ({ activeTool, viewingLinks }) => {
                if (activeTool == InkTool.Pen) {
                    this.message = "You're in pen mode! Click and drag to draw your first masterpiece.";
                }
                if (viewingLinks) {
                    this.message = 'To edit your links, click the pencil icon.';
                }
                if (Doc.ActiveTool === InkTool.Pen) {
                    this.message = 'Editing links';
                }
            },
            { fireImmediately: true }
        );
        this._disposers.reaction4 = reaction(
            () => ({ startLink: DocumentLinksButton.StartLink, endLink: Doc.UserDoc().links }),
            ({ startLink, endLink }) => {
                if (startLink) {
                    this.message = "You've started a link.";
                } else if (endLink) {
                    this.message = "You've completed a link.";
                }
            }
        );
        this._disposers.reaction5 = reaction(
            () => ({ pin: Doc.ActivePresentation?.data, trails: DocumentManager.Instance.DocumentViews.find(view => view.Document === Doc.MyTrails) }),
            ({ pin, trails }) => {
                // if (pin) {
                //     this.message = 'You pinned your doc to a trail.';
                // }
                if (trails) {
                    this.message = 'This is your trails tab.';
                }
            }
        );
        this._disposers.reaction6 = reaction(
            () => ({ presentationMode: Doc.ActivePresentation?.presentation_status }),
            ({ presentationMode }) => {
                if (presentationMode === 'edit') {
                    this.message = 'You are editing your presentation.';
                } else if (presentationMode === 'manual') {
                    this.message = 'Manual presentation mode';
                } else if (presentationMode === 'auto') {
                    this.message = 'Auto presentation mode';
                }
            }
        );
    }

    componentWillUnmount(): void {
        Object.values(this._disposers).forEach(disposer => disposer?.());
    }

    // stop reaction from what it's currently doing
    // this._disposers.reaction1();

    @observable message = 'Click anywhere and begin typing to create your first document!';
    @observable firstDoc: Doc | undefined = undefined;
    @observable secondDoc: Doc | undefined = undefined;
    */
    firstDocPos = { x: 0, y: 0 };

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