import { makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { CollectionFreeFormInfoState, infoState } from './CollectionFreeFormInfoState';
import { Button } from '../../../util/CurrentUserUtils';
import { InfoState } from './CollectionFreeFormInfoState';
import { DocButtonState } from '../../nodes/DocumentLinksButton';
import { InkTool } from '../../../../fields/InkField';
import { DocumentLinksButton } from '../../nodes/DocumentLinksButton';
import { CollectionFreeFormView } from '.';
import { DocListCast } from '../../../../fields/Doc';
import { ButtonType } from '../../nodes/FontIconBox/FontIconBox';

export interface CollectionFreeFormInfoUIProps {
    Document: Doc;
    LayoutDoc: Doc;
    childDocs: () => Doc[];
    close: () => void;
}

@observer
export class CollectionFreeFormInfoUI extends ObservableReactComponent<CollectionFreeFormInfoUIProps> {
    _originalBackground: string | undefined;
    private tutorialStates: { [key: string]: infoState } = {};

    public static Init() {
        CollectionFreeFormView.SetInfoUICreator(
            (doc: Doc, layout: Doc, childDocs: () => Doc[], close: () => void) =>
                <CollectionFreeFormInfoUI 
                    Document={doc} 
                    LayoutDoc={layout} 
                    childDocs={childDocs} 
                    close={close} 
                />
        );
    }

    constructor(props: CollectionFreeFormInfoUIProps) {
        super(props);
        makeObservable(this);
        this.tutorialStates = {}; // Initialize an empty object
        this.currState = this.setupStates(); // Call setupStates() here
    }
    

    @observable _currState: infoState | undefined = undefined;
    @observable _nextState: infoState | undefined = undefined; // Track next state

    get currState() {
        return this._currState;
    }
    
    set currState(val) {
        runInAction(() => {
            this._currState = val;
        });
    }

    componentWillUnmount(): void {
        this._props.Document.backgroundColor = this._originalBackground;
    }

    skipToState = (newState: infoState) => {
        runInAction(() => {
            if (!this._currState) {
                this._currState = newState; // Assign directly if undefined
            } else {
                this._currState = newState;
        }
        });
    };

    createNextButton = (newState: ReturnType<typeof InfoState>) => {
        return {
            title: "Next",
            toolTip: "Next",
            btnType: ButtonType.ClickButton,
            scripts: {
                onClick: `this.skipToState(${newState})`
            },
            targetState: newState
        };
    };

    setupStates = () => {
        let docCounter = this._props.childDocs().length;
        let lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
        let linkCounter = Doc.Links(lastDocCreated)?.length;
        let presentationCounter = DocListCast(Doc.ActivePresentation?.data).length
        this._originalBackground = this._props.Document.backgroundColor as string;
        
        this.tutorialStates.multipleDocs = InfoState("Let's create a new link! Click the link icon on one document and connect it to another.", {
                // eslint-disable-next-line no-use-before-define
            linkStarted: [() => DocumentLinksButton.StartLink, () => {
                linkCounter = Doc.Links(lastDocCreated).length
                // eslint-disable-next-line no-use-before-define
                return startedLink}],
                // docCreated: [() => this._props.childDocs().length > docCounter, () => {
                //     docCounter += 1
                //     lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
                //     // eslint-disable-next-line no-use-before-define
                // return this.tutorialStates.makePresentation}]
            },
            'dash-create-link-board.gif'
        );

        this.tutorialStates.presentDocs = InfoState("Select a document then click the 'pin' button in the top left to create your presentation.", {
                // eslint-disable-next-line no-use-before-define
            docPinned: [() => DocListCast(Doc.ActivePresentation?.data).length > presentationCounter, () => {
                presentationCounter++
                // eslint-disable-next-line no-use-before-define
                return pinnedDoc}],
            },
    'pin-explanation.gif');

    this.tutorialStates.nestedCollections = InfoState("Want to learn how to create a nested collection? Click the : button and add a 'collection' doc", {
        // eslint-disable-next-line no-use-before-define
        docCreated: [() => this._props.childDocs().length > docCounter, () => {
            docCounter += 1
            lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
            // eslint-disable-next-line no-use-before-define
            return marqueeSelection}]
    },
    'dash-nested-collection.gif')

    
    this.tutorialStates.makePresentation = InfoState("Add a new document to create a presentation!", {
        docCreated: [() => this._props.childDocs().length > docCounter, () => {
            docCounter += 1
            lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
            // eslint-disable-next-line no-use-before-define
            return this.tutorialStates.presentDocs}],
    });
    
        const skipToLinksButton: Button = {
            title: "Links Tutorial",
            toolTip: "Skip",
            btnType: ButtonType.ClickButton,
            scripts: {
                onClick: "this.skipToState(this.tutorialStates.multipleDocs)"
            },
            targetState: this.tutorialStates.multipleDocs
        };

        const skipToPinsButton: Button = {
            title: "Pins Tutorial",
            toolTip: "Skip",
            btnType: ButtonType.ClickButton,
            scripts: {
                onClick: "this.skipToState(this.tutorialStates.makePresentation)"
            },
            targetState: this.tutorialStates.makePresentation
        };

        const skipToPresentationButton: Button = {
            title: "Collections Tutorial",
            toolTip: "Skip",
            btnType: ButtonType.ClickButton,
            scripts: {
                onClick: "this.skipToState(this.tutorialStates.nestedCollections)"
            },
            targetState: this.tutorialStates.nestedCollections
        };

        const ending = InfoState("If you have any more questions, feel free to ask Dash's AI Bot!")

        // Traditional tutorial

        const completed = InfoState(
            "Eager to learn more? Click the ? icon in the top right corner to read our full documentation.",
            { docRemoved: [() => this._props.childDocs().length === 1, () => this.tutorialStates.start] },
            'documentation.png',
        );

        const penMode = InfoState("You're in pen mode! Click and drag to draw your first masterpiece, then click the Ink button once you're done.", {
            activePen: [() => Doc.ActiveTool !== InkTool.Ink, () => completed],
        });
    
        const briefArtisticFeature = InfoState("Finally, want to explore the art feature of Dash? Click the 'Ink' button on the hotbar then click the pen button.", {
            penModeActivated: [() => Doc.ActiveTool === InkTool.Ink, () => penMode],
        });
    
        const activatePresentation = InfoState("Lastly, click the linked node and start the presentation!", {
            presentation: [() => Doc.ActivePresentation?.presentation_status === "auto", () => briefArtisticFeature],
        });
    
        const deletePresentation = InfoState("Cool! Click 'setOnClick to follow primary link' for your non-presentation doc and try deleting the presentation.", {
            docRemoved: [() => this._props.childDocs().length < docCounter, () => {
                docCounter -= 1
                return activatePresentation}],
        },
    'onclick-node.gif');

        const trailedPresentation = InfoState("Try linking your presentation to the last doc you created (now highlighted).", {
            linkAdd: [() => Doc.Links(lastDocCreated)?.length > linkCounter, () => {
                linkCounter += 1
                return deletePresentation
            }],
            docAdded: [() => this._props.childDocs().length > docCounter, () => {
                docCounter += 1
                // Last doc that is not the presentation
                lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 2]
                linkCounter = Doc.Links(lastDocCreated)?.length
                return deletePresentation}]
        },
    'link-presentation.gif');
    
        const pinnedPresentation = InfoState("Want to see something cool? Zoom out, click the trail button on the presentation, and drag it inside the canvas.", {
            docAdded: [() => this._props.childDocs().length > docCounter, () => {
                docCounter += 1
                // Last doc that is not the presentation
                lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 2]
                Doc.HighlightDoc(lastDocCreated)
                linkCounter = Doc.Links(lastDocCreated)?.length
                return trailedPresentation}],
        },
    'dash-trail-explanation.gif');

        const pinnedDoc2 = InfoState("You pinned another doc. Press autoplay to the right to show your presentation!", {
            autoPresentation: [() => Doc.ActivePresentation?.presentation_status === "auto", () => pinnedPresentation],
        });

        const pinnedDoc = InfoState("You just pinned your doc. Pin another doc to add to the presentation!", {
            // eslint-disable-next-line no-use-before-define
            addedDoc: [() => this._props.childDocs().length > docCounter, () => {
                docCounter += 1
                lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
            return pinnedDoc}],
            docPinned: [() => DocListCast(Doc.ActivePresentation?.data).length > presentationCounter, () => {
                presentationCounter++
                // eslint-disable-next-line no-use-before-define
                return pinnedDoc2}],
        });
    
        const editLink = InfoState("Want to make your link visible? Click 'show link'.", {
            docCreated: [() => this._props.childDocs().length > docCounter, () => {
                docCounter += 1
                lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
                return this.tutorialStates.makePresentation}],
        },
        'show-link.gif');

        const madeLink = InfoState("You made your first link! You can view your links by selecting the blue dot.", {
            linkViewed: [() => DocButtonState.Instance.LinkEditorDocView, () => {
                docCounter = this._props.childDocs().length 
                return editLink}],
        },
        'dash-following-link.gif');
    
        const startedLink = InfoState("Now click the highlighted link icon on your other document.", {
            linkAdd: [() => Doc.Links(lastDocCreated)?.length > linkCounter, () => {
                linkCounter += 1
                return madeLink
            }]
        },
        'dash-create-link-board.gif');

        this.tutorialStates.movedDoc = InfoState("Great moves! Try creating a second document.", {
            docCreated: [() => this._props.childDocs().length > docCounter, () => {
                docCounter += 1
                lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
                return this.tutorialStates.multipleDocs}],
        },
        'dash-colon-menu.gif'); // prettier-ignore
    
        this.tutorialStates.start = InfoState("Welcome to Dash! Click anywhere and begin typing ':' to create your first document.", {
            docCreated: [() => this._props.childDocs().length > docCounter, () => {
                docCounter += 1
                lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
                return this.tutorialStates.movedDoc}]
        },
        undefined,
        [skipToLinksButton, skipToPinsButton])
    
        // Information on created nested collections
        const createdMarquee = InfoState("Next, right click and drag a square to create the collection", {
            // eslint-disable-next-line no-use-before-define
            marqueeMade: [() => this._props.childDocs().length < docCounter, () => {
                docCounter -= 1
                return ending}],
        },
        'dash-create-collection-marquee.gif')
        
        const marqueeSelection = InfoState("Want an easier way to make a collection of docs? First add two docs you want to make a collection of", {
            marqueeMade: [() => this._props.childDocs().length > docCounter, () => {
                docCounter += 1
                lastDocCreated = this._props.childDocs()[this.props.childDocs().length - 1]
                return createdMarquee}]
        })

        // Explanation of importing

        const easierImport = InfoState("Or, for easier access, you can drag any of the accepted file types from your computer or a webpage and drop it into your dashboard. This includes images, videos, audio, pdfs, and more!", {
        },
        'dash-',
        [this.createNextButton(ending)])
        
        this.tutorialStates.importFile = InfoState("Want to learn how to import a file? Import using the import menu on the left hand side", {
        },
        'dash-import.gif',
        [this.createNextButton(easierImport)])

        // Editing documents

        // Accessed by right-clicking anywhere on the target document or selecting the three bars menu at the bottom of the document chrome

        const extraContentsOfDoc = InfoState("Lastly, all documents also have a context-sensitive toolbar. The toolbar contents vary depending on the document type.", {
        },
        'context-toolbar.png',
        [this.createNextButton(ending)])

        const contentsofDoc = InfoState("You can access the context of a doc through right-clicking anywhere on the target document or selecting the three bars menu at the bottom of the document chrome", {
        },
        'dash-context-menu.gif',
        [this.createNextButton(extraContentsOfDoc)])

        const propertiesofDoc = InfoState("You can also access the properties of a doc through the double arrows in the top right or the single arrow on the right edge of the screen", {
        },
        'dash-properties-pane.gif',
        [this.createNextButton(contentsofDoc)])

        this.tutorialStates.editingDocuments = InfoState("Want to learn how to edit a document? Either left or right click the document", {
        },
        'document-chrome.png',
        [this.createNextButton(propertiesofDoc)])
        return this.tutorialStates.start
    };


    render() {
        if (!this.currState) return null;
        
        return (
            <CollectionFreeFormInfoState 
                next={this.skipToState}  // This ensures skipToState is passed correctly
                close={this._props.close} 
                infoState={this.currState} 
            />
        );
    }
}