import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { returnFalse, returnNone, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
import { emptyFunction } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { RichTextField } from '../../../fields/RichTextField';
import { DocCast, NumCast, RTFCast, StrCast, toList } from '../../../fields/Types';
import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
import '../pdf/GPTPopup/GPTPopup.scss';
import { DocUtils } from '../../documents/DocUtils';
import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { undoable } from '../../util/UndoManager';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { PinDocView, PinProps } from '../PinFuncs';
import { StyleProp } from '../StyleProp';
import './ComparisonBox.scss';
import { DocumentView } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
import ReactLoading from 'react-loading';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { tickStep } from 'd3';

@observer
export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
    public static LayoutString(fieldKey: string) {
        return FieldView.LayoutString(ComparisonBox, fieldKey);
    }
    private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined];
    constructor(props: FieldViewProps) {
        super(props);
        makeObservable(this);
    }

    @observable private _inputValue = '';
    @observable private _outputValue = '';
    @observable private _loading = false;
    @observable private _errorMessage = '';
    @observable private _outputMessage = '';
    @observable private _isEmpty = false;

    public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined;

    @action handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
        this._inputValue = e.target.value;
        console.log(this._inputValue);
    };

    @observable _animating = '';

    @computed get clipWidth() {
        return NumCast(this.layoutDoc[this.clipWidthKey], 50);
    }
    get clipWidthKey() {
        return '_' + this._props.fieldKey + '_clipWidth';
    }

    @computed get clipHeight() {
        return NumCast(this.layoutDoc[this.clipHeightKey], 200);
    }
    get revealOp() {
        return this.layoutDoc[`_${this._props.fieldKey}_revealOp`];
    }
    get clipHeightKey() {
        return '_' + this._props.fieldKey + '_clipHeight';
    }

    componentDidMount() {
        this._props.setContentViewBox?.(this);
        reaction(
            () => this._props.isSelected(),
            selected => !selected && (this.childActive = false)
        );
    }
    protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => {
        this._disposers[disposerId]?.();
        if (ele) {
            this._disposers[disposerId] = DragManager.MakeDropTarget(ele, (e, dropEvent) => this.internalDrop(e, dropEvent, fieldKey), this.layoutDoc);
        }
    };

    private internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => {
        if (dropEvent.complete.docDragData) {
            const { droppedDocuments } = dropEvent.complete.docDragData;
            const added = dropEvent.complete.docDragData.moveDocument?.(droppedDocuments, this.Document, (doc: Doc | Doc[]) => this.addDoc(toList(doc).lastElement(), fieldKey));
            Doc.SetContainer(droppedDocuments.lastElement(), this.dataDoc);
            !added && e.preventDefault();
            e.stopPropagation(); // prevent parent Doc from registering new position so that it snaps back into place
            return added;
        }
        return undefined;
    }, 'internal drop');

    private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
        if (e.button !== 2) {
            setupMoveUpEvents(
                this,
                e,
                this.onPointerMove,
                emptyFunction,
                action((moveEv, doubleTap) => {
                    if (doubleTap) {
                        this.childActive = true;
                        if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
                        if (!this.dataDoc[this.fieldKey + '_2'] && !this.dataDoc[this.fieldKey + '_alternate']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
                    }
                }),
                false,
                undefined,
                action(() => {
                    if (this.childActive) return;
                    this._animating = 'all 200ms';
                    // on click, animate slider movement to the targetWidth
                    this.layoutDoc[this.clipWidthKey] = (targetWidth * 100) / this._props.PanelWidth();
                    // this.layoutDoc[this.clipHeightKey] = (targetWidth * 100) / this._props.PanelHeight();

                    setTimeout(
                        action(() => {
                            this._animating = '';
                        }),
                        200
                    );
                })
            );
        }
    };

    // private onClick(e: React.PointerEvent<HTMLDivElement>) {
    //     setupMoveUpEvents(
    //         this, e, this.onPointerMOve, emptyFunction(), () => {this._isAnyChildContentActive = true;}, emptyFunction(), emptyFunction()
    //     )
    // }

    @action
    private onPointerMove = ({ movementX }: PointerEvent) => {
        const width = movementX * this.ScreenToLocalBoxXf().Scale + (this.clipWidth / 100) * this._props.PanelWidth();
        if (width && width > 5 && width < this._props.PanelWidth()) {
            this.layoutDoc[this.clipWidthKey] = (width * 100) / this._props.PanelWidth();
        }
        return false;
    };

    getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
        const anchor = Docs.Create.ConfigDocument({
            title: 'CompareAnchor:' + this.Document.title,
            // set presentation timing properties for restoring view
            presentation_transition: 1000,
            annotationOn: this.Document,
        });
        if (anchor) {
            if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
            /* addAsAnnotation && */ this.addDocument(anchor);
            PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), clippable: true } }, this.Document);
            return anchor;
        }
        return this.Document;
    };

    clearDoc = undoable((fieldKey: string) => {
        // delete this.dataDoc[fieldKey];
        this.dataDoc[fieldKey] = undefined;
        this._isEmpty = true;
        // this.dataDoc[fieldKey] = 'empty';
        console.log('HERE' + fieldKey + ';');
    }, 'clear doc');
    // clearDoc = (fieldKey: string) => delete this.dataDoc[fieldKey];

    moveDoc = (doc: Doc, addDocument: (document: Doc | Doc[]) => boolean, which: string) => this.remDoc(doc, which) && addDocument(doc);
    addDoc = (doc: Doc, which: string) => {
        if (this.dataDoc[which] && !this._isEmpty) return false;
        this.dataDoc[which] = doc;
        return true;
    };
    remDoc = (doc: Doc, which: string) => {
        if (this.dataDoc[which] === doc) {
            this._isEmpty = true;
            // this.dataDoc[which] = 'empty';
            console.log('HEREEEE');
            this.dataDoc[which] = undefined;
            return true;
        }
        console.log('FALSE');
        return false;
    };

    closeDown = (e: React.PointerEvent, which: string) => {
        setupMoveUpEvents(
            this,
            e,
            moveEv => {
                const de = new DragManager.DocumentDragData([DocCast(this.dataDoc[which])], dropActionType.move);
                de.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => addDocument(doc);
                de.canEmbed = true;
                DragManager.StartDocumentDrag([this._closeRef.current!], de, moveEv.clientX, moveEv.clientY);
                return true;
            },
            emptyFunction,
            () => this.clearDoc(which)
        );
    };
    docStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
        if (property === StyleProp.PointerEvents) return 'none';
        return this._props.styleProvider?.(doc, props, property);
    };
    moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
    moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
    remDoc1 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true);
    remDoc2 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true);

    /**
     * Tests for whether a comparison box slot (ie, before or after) has renderable text content.
     * If it does, render a FormattedTextBox for that slot that references the comparisonBox's slot field
     * @param whichSlot field key for start or end slot
     * @returns a JSX layout string if a text field is found, othwerise undefined
     */
    testForTextFields = (whichSlot: string) => {
        const slotData = Doc.Get(this.dataDoc, whichSlot, true);
        const slotHasText = slotData instanceof RichTextField || typeof slotData === 'string';
        const subjectText = RTFCast(this.Document[this.fieldKey])?.Text.trim();
        const altText = RTFCast(this.Document[this.fieldKey + '_alternate'])?.Text.trim();
        const layoutTemplateString =
            slotHasText ? FormattedTextBox.LayoutString(whichSlot):
            whichSlot.endsWith('1') ? (subjectText !== undefined ? FormattedTextBox.LayoutString(this.fieldKey) : undefined) :
                                       altText !== undefined     ? FormattedTextBox.LayoutString(this.fieldKey + '_alternate'): undefined; // prettier-ignore

        // A bit hacky to try out the concept of using GPT to fill in flashcards
        //   If the second slot doesn't have anything in it, but the fieldKey slot has text (e.g., this.text is a string)
        // and the fieldKey + "_alternate" has text that includes a GPT query (indicated by (( && )) ) that is parameterized (optionally) by the fieldKey text (this) or other metadata (this.<field>).
        // eg., this.text_alternate is
        //     "((Provide a one sentence definition for (this) that doesn't use any word in (this.excludeWords) ))"
        //     where (this) is replaced by the text in the fieldKey slot abd this.excludeWords is repalced by the conetnts of the excludeWords field
        // The GPT call will put the "answer"  in the second slot of the comparison (eg., text_2)
        if (whichSlot.endsWith('2') && !layoutTemplateString?.includes(whichSlot)) {
            const queryText = altText?.replace('(this)', subjectText); // TODO: this should be done in Doc.setField but it doesn't know about the fieldKey ...
            if (queryText?.match(/\(\(.*\)\)/)) {
                Doc.SetField(this.Document, whichSlot, ':=' + queryText, false); // make the second slot be a computed field on the data doc that calls ChatGpt
            }
        }
        return layoutTemplateString;
    };

    _closeRef = React.createRef<HTMLDivElement>();

    /**
     * Flips a flashcard to the alternate side for the user to view.
     */
    flipFlashcard = () => {
        const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`];
        this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : undefined;
    };

    /**
     * Changes the view option to hover for a flashcard.
     */
    hoverFlip = (side: string | undefined) => {
        if (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'hover') this.layoutDoc[`_${this._props.fieldKey}_usePath`] = side;
    };
    /**
     * Creates the button used to flip the flashcards.
     */
    @computed get overlayAlternateIcon() {
        const usepath = this.layoutDoc[`_${this._props.fieldKey}_usePath`];
        return (
            <Tooltip title={<div className="dash-tooltip">flip</div>}>
                <div
                    className="formattedTextBox-alternateButton"
                    onPointerDown={e =>
                        setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => {
                            if (!this.layoutDoc[`_${this._props.fieldKey}_revealOp`] || this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'flip') {
                                this.flipFlashcard();

                                // console.log('Print Front of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text ?? ''));
                                // console.log('Print Back of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text ?? ''));
                            }
                        })
                    }
                    style={{
                        background: usepath === 'alternate' ? 'white' : 'black',
                        color: usepath === 'alternate' ? 'black' : 'white',
                        display: 'inline-block',
                    }}>
                    <div key="alternate" className="formattedTextBox-flip">
                        <FontAwesomeIcon icon="turn-up" size="1x" />
                    </div>
                </div>
            </Tooltip>
        );
    }

    @computed get flashcardMenu() {
        return (
            <div>
                <Tooltip
                    title={
                        this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? (
                            <div className="dash-tooltip">Flip to front side to use GPT</div>
                        ) : (
                            <div className="dash-tooltip">Ask GPT to create an answer on the back side of the flashcard</div>
                        )
                    }>
                    <div style={{ position: 'absolute', bottom: '3px', right: '56px', cursor: 'pointer' }} onPointerDown={e => (!this.layoutDoc[`_${this._props.fieldKey}_usePath`] ? this.askGPT(GPTCallType.CHATCARD) : null)}>
                        <FontAwesomeIcon icon="lightbulb" size="xl" />
                    </div>
                </Tooltip>
                <Tooltip title={<div>Create a flashcard pile</div>}>
                    <div
                        style={{ position: 'absolute', bottom: '3px', right: '80px', cursor: 'pointer' }}
                        onPointerDown={e => {
                            const collectionArr: Doc[] = [];
                            collectionArr.push(this.Document);
                            const newCol = Docs.Create.CarouselDocument(collectionArr, {
                                _width: NumCast(this.layoutDoc['_' + this._props.fieldKey + '_width'], 250),
                                _height: NumCast(this.layoutDoc['_' + this._props.fieldKey + '_width'], 200),
                                _layout_fitWidth: false,
                                _layout_autoHeight: true,
                            });
                            newCol['x'] = e.clientX - 820;
                            newCol['y'] = e.clientY - 640;
                            this._props.addDocument?.(newCol);
                            this._props.removeDocument?.(this.Document);
                            this.Document.embedContainer = newCol;
                        }}>
                        <FontAwesomeIcon icon="folder-plus" size="xl" />
                    </div>
                </Tooltip>
                <Tooltip title={<div className="dash-tooltip">Hover to reveal</div>}>
                    <div
                        style={{ position: 'absolute', bottom: '3px', right: '25px', cursor: 'pointer' }}
                        onClick={e => (this.revealOp === 'hover' ? (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'flip') : (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'hover'))}>
                        <FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="layer-group" size="xl" />
                    </div>
                </Tooltip>
                {/* <Tooltip title={<div className="dash-tooltip">Remove this side of the flashcard</div>}>
                    <div
                        style={{ position: 'absolute', bottom: '3px', right: '80px', cursor: 'pointer' }}
                        onPointerDown={e => this.closeDown(e, this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this._props.fieldKey + '_1' : this._props.fieldKey + '_0')}>
                        <FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="trash-can" size="xl" />
                    </div>
                </Tooltip> */}
                {/* {this.overlayAlternateIcon} */}
            </div>
        );
    }
    // this.closeDown(e, this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this.fieldKey + '_0' : this.fieldKey + '_1')}
    @action activateContent = () => {
        this.childActive = true;
    };

    @action handleRenderGPTClick = () => {
        // Call the GPT model and get the output
        this.layoutDoc[`_${this._props.fieldKey}_usePath`] = 'alternate';
        this._outputValue = '';
        if (this._inputValue) this.askGPT(GPTCallType.QUIZ);
    };

    @action handleRenderClick = () => {
        // Call the GPT model and get the output
        this.layoutDoc[`_${this._props.fieldKey}_usePath`] = undefined;
    };

    animateRes = (resIndex: number, newText: string, callType: GPTCallType) => {
        if (resIndex < newText.length) {
            // const marks = this._editorView?.state.storedMarks ?? [];
            switch (callType) {
                case GPTCallType.CHATCARD:
                    DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text += newText[resIndex];
                    break;
                case GPTCallType.QUIZ:
                    this._outputValue += newText[resIndex];
                    break;
                default:
                    return;
            }

            // this._editorView?.dispatch(this._editorView?.state.tr.insertText(newText[resIndex]).setStoredMarks(this._outputValue));
            setTimeout(() => this.animateRes(resIndex + 1, newText, callType), 20);
        }
    };

    /**
     * Calls the GPT model to create QuizCards. Evaluates how similar the user's response is to the alternate
     * side of the flashcard.
     */
    askGPT = async (callType: GPTCallType): Promise<string | undefined> => {
        const questionText = 'Question: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text);
        const rubricText = ' Rubric: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text);
        const queryText = questionText + ' UserAnswer: ' + this._inputValue + '. ' + rubricText;
        this._loading = true;
        const doc = DocCast(this.dataDoc[this.props.fieldKey + '_0']);
        if (callType == GPTCallType.CHATCARD) {
            if (StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text) === '') {
                this._loading = false;
                return;
            }
            this.flipFlashcard();
        }
        try {
            const res = await gptAPICall(callType == GPTCallType.QUIZ ? queryText : questionText, callType);
            if (!res) {
                console.error('GPT call failed');
                return;
            }
            // this.animateRes(0, res, callType);
            if (callType == GPTCallType.CHATCARD) {
                DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = res;
                // this.flipFlashcard();
            }
            if (callType == GPTCallType.QUIZ) this._outputValue = res;
            // DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = res;
            // this._outputValue = res;
            console.log(res);
        } catch (err) {
            console.error('GPT call failed');
        }
        this._loading = false;
    };
    layoutWidth = () => NumCast(this.layoutDoc.width, 200);
    layoutHeight = () => NumCast(this.layoutDoc.height, 200);

    // specificMenu = (): void => {
    //     const cm = ContextMenu.Instance;
    //     cm.addItem({ description: 'Create an Answer on the Back', event: () => this.askGPT(GPTCallType.CHATCARD), icon: 'pencil' });
    // };
    @observable childActive = false;

    render() {
        const clearButton = (which: string) => (
            <Tooltip title={<div className="dash-tooltip">remove</div>}>
                <div
                    // style={{ position: 'relative', top: '0px', left: '10px' }}
                    ref={this._closeRef}
                    className={`clear-button ${which}`}
                    onPointerDown={e => this.closeDown(e, which)} // prevent triggering slider movement in registerSliding
                >
                    <FontAwesomeIcon className={`clear-button ${which}`} icon="times" size="xs" />
                </div>
            </Tooltip>
        );
        const displayDoc = (whichSlot: string) => {
            const whichDoc = DocCast(this.dataDoc[whichSlot]);
            const targetDoc = DocCast(whichDoc?.annotationOn, whichDoc);
            const layoutString = targetDoc ? '' : this.testForTextFields(whichSlot);

            return targetDoc || layoutString ? (
                <>
                    <DocumentView
                        // eslint-disable-next-line react/jsx-props-no-spreading
                        {...this._props}
                        ignoreUsePath={layoutString ? true : undefined}
                        renderDepth={this.props.renderDepth + 1}
                        LayoutTemplateString={layoutString}
                        Document={layoutString ? this.Document : targetDoc}
                        containerViewPath={this.DocumentView?.().docViewPath}
                        moveDocument={whichSlot.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
                        removeDocument={whichSlot.endsWith('1') ? this.remDoc1 : this.remDoc2}
                        NativeWidth={this.layoutWidth}
                        NativeHeight={this.layoutHeight}
                        isContentActive={() => this.childActive}
                        isDocumentActive={returnFalse}
                        dontSelect={returnTrue}
                        whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
                        styleProvider={this.childActive ? this._props.styleProvider : this.docStyleProvider}
                        hideLinkButton
                        pointerEvents={this.childActive ? undefined : returnNone}
                    />
                    {/* <div style={{ position: 'absolute', top: '-5px', left: '2px' }}>{layoutString ? null : clearButton(whichSlot)}</div> */}
                </> // placeholder image if doc is missingleft: `${NumCast(this.layoutDoc.width, 200) - 33}px`
            ) : (
                <div className="placeholder">
                    <FontAwesomeIcon className="upload-icon" icon="cloud-upload-alt" size="lg" />
                </div>
            );
        };
        const displayBox = (which: string, index: number, cover: number) => (
            <div
                className={`${index === 0 ? 'before' : 'after'}Box-cont`}
                key={which}
                style={{ width: this._props.PanelWidth() }}
                onPointerDown={e => {
                    this.registerSliding(e, cover);
                    this.activateContent();
                }}
                ref={ele => this.createDropTarget(ele, which, index)}>
                {!this._isEmpty ? displayDoc(which) : null}
                {/* {this.dataDoc[this.fieldKey + '_0'] !== 'empty' ? displayDoc(which) : null} */}
            </div>
        );

        if (this.Document._layout_isFlashcard) {
            const side = this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 1 : 0;

            // add text box to each side when comparison box is first created
            // (!this.dataDoc[this.fieldKey + '_0'] && this.dataDoc[this._props.fieldKey + '_0'] !== 'empty')
            if (!this.dataDoc[this.fieldKey + '_0'] && !this._isEmpty) {
                const dataSplit = StrCast(this.dataDoc.data).split('Answer');
                const newDoc = Docs.Create.TextDocument(dataSplit[1]);
                // if there is text from the pdf ai cards, put the question on the front side.
                // eslint-disable-next-line prefer-destructuring
                newDoc[DocData].text = dataSplit[1];
                this.addDoc(newDoc, this.fieldKey + '_0');
            }
            if (!this.dataDoc[this.fieldKey + '_1'] && !this._isEmpty) {
                const dataSplit = StrCast(this.dataDoc.data).split('Answer');
                const newDoc = Docs.Create.TextDocument(dataSplit[0]);
                // if there is text from the pdf ai cards, put the answer on the alternate side.
                // eslint-disable-next-line prefer-destructuring
                newDoc[DocData].text = dataSplit[0];
                this.addDoc(newDoc, this.fieldKey + '_1');
            }

            // render the QuizCards
            // console.log('GERE' + DocCast(this.Document.embedContainer).filterOp);
            if (DocCast(this.Document.embedContainer) && DocCast(this.Document.embedContainer).practiceMode === 'quiz') {
                const text = StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text);
                return (
                    <div className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} style={{ display: 'flex', flexDirection: 'column' }}>
                        <p style={{ color: 'white', padding: 10 }}>{text}</p>
                        <p style={{ display: text === '' ? 'flex' : 'none', color: 'white', padding: 10 }}>Return to all flashcards and add text to both sides. </p>
                        <div className="input-box">
                            <textarea
                                value={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this._outputValue : this._inputValue}
                                onChange={this.handleInputChange}
                                onScroll={e => e.stopPropagation()}
                                placeholder={!this.layoutDoc[`_${this._props.fieldKey}_usePath`] ? 'Enter a response for GPT to evaluate.' : ''}
                                readOnly={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate'}></textarea>

                            {this._loading ? (
                                <div className="loading-spinner" style={{ position: 'absolute' }}>
                                    <ReactLoading type="spin" height={30} width={30} color={'blue'} />
                                </div>
                            ) : null}
                        </div>
                        <div className="submit-button" style={{ overflow: 'hidden', display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'none' : 'flex' }}>
                            <button type="button" onClick={this.handleRenderGPTClick} style={{ borderRadius: '2px', marginBottom: '3px' }}>
                                Submit
                            </button>
                        </div>
                        <div className="submit-button" style={{ overflow: 'hidden', marginBottom: '2px', display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'flex' : 'none' }}>
                            <button type="button" onClick={this.handleRenderClick} style={{ borderRadius: '2px' }}>
                                Redo the Question
                            </button>
                        </div>
                    </div>
                );
            }

            // render a normal flashcard when not a QuizCard
            return (
                <div
                    className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} /* change className to easily disable/enable pointer events in CSS */
                    // onContextMenu={this.specificMenu}
                    style={{ display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
                    onMouseEnter={() => {
                        this.hoverFlip('alternate');
                    }}
                    onMouseLeave={() => {
                        this.hoverFlip(undefined);
                    }}
                    // onPointerUp={() => (this._isAnyChildContentActive = true)}
                >
                    {displayBox(`${this.fieldKey}_${side === 0 ? 1 : 0}`, side, this._props.PanelWidth() - 3)}
                    {this._loading ? (
                        <div className="loading-spinner" style={{ position: 'absolute' }}>
                            <ReactLoading type="spin" height={30} width={30} color={'blue'} />
                        </div>
                    ) : null}
                    {this._props.isContentActive() ? this.flashcardMenu : null}
                    {this.overlayAlternateIcon}
                </div>
            );
        }
        // render a comparison box that compares items side by side
        return (
            <div className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}` /* change className to easily disable/enable pointer events in CSS */}>
                {displayBox(`${this.fieldKey}_2`, 1, this._props.PanelWidth() - 3)}
                <div className="clip-div" style={{ width: this.clipWidth + '%', transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, 'gray') }}>
                    {displayBox(`${this.fieldKey}_1`, 0, 0)}
                </div>

                <div
                    className="slide-bar"
                    style={{
                        left: `calc(${this.clipWidth + '%'} - 0.5px)`,
                        cursor: this.clipWidth < 5 ? 'e-resize' : this.clipWidth / 100 > (this._props.PanelWidth() - 5) / this._props.PanelWidth() ? 'w-resize' : undefined,
                    }}
                    onPointerDown={e => !this.childActive && this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
                >
                    <div className="slide-handle" />
                </div>
            </div>
        );
    }
}

Docs.Prototypes.TemplateMap.set(DocumentType.COMPARISON, {
    data: '',
    layout: { view: ComparisonBox, dataField: 'data' },
    options: {
        acl: '',
        backgroundColor: 'gray',
        dropAction: dropActionType.move,
        waitForDoubleClickToClick: 'always',
        _layout_reflowHorizontal: true,
        _layout_reflowVertical: true,
        _layout_nativeDimEditable: true,
        systemIcon: 'BsLayoutSplit',
    },
});
