import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, observable, reaction, runInAction } from "mobx";
import React from "react";
import { returnFalse, returnEmptyFilter, returnTrue } from "../../../../../../ClientUtils";
import { emptyFunction } from "../../../../../../Utils";
import { Doc, returnEmptyDoclist } from "../../../../../../fields/Doc";
import { DefaultStyleProvider } from "../../../../StyleProvider";
import { DocumentView, DocumentViewInternal } from "../../../DocumentView";
import { DocCreatorMenu } from "../DocCreatorMenu";
import { TemplatePreviewGrid } from "./TemplatePreviewGrid";
import { observer } from "mobx-react";
import { Transform } from "../../../../../util/Transform";
import { Template } from "../Template";
import { TemplateMenuAIUtils } from "../Backend/TemplateMenuAIUtils";
import { ObservableReactComponent } from "../../../../ObservableReactComponent";
import { IDisposer } from "mobx-utils";
import { ImageField } from "../../../../../../fields/URLField";
import { DocCreatorMenuButton } from "./DocCreatorMenuButton";

interface TemplateEditingWindowProps {
    menu: DocCreatorMenu;
    template: Template;
}

@observer
export class TemplateEditingWindow extends ObservableReactComponent<TemplateEditingWindowProps> {

    private fireflyPrompt: string = 'Use this template to generate an empty baseball card template.';
    private previewWindow: HTMLDivElement | null = null;
    private disposers: { [name: string]: IDisposer } = {};
    private promptInput: HTMLTextAreaElement | null = null;

    @observable _loading: boolean = false;
    @observable _variationsTabOpen: boolean = false;
    @observable _variationURLs: string[] = [];
    @observable _variations: Template[] = [];

    componentDidMount(): void {
        this.disposers.windowDimensions = reaction(() => 
            this._props.menu._resizing, 
            () => { this.forceUpdate() }, 
            { fireImmediately: true }
            );
    }

    componentWillUnmount() {
        Object.values(this.disposers).forEach(disposer => disposer?.());
    }

    setPromptInputRef: React.LegacyRef<HTMLTextAreaElement> = (node) => {
        this.promptInput = node;
        this.forceUpdate();
    }

    setContainerRef: React.LegacyRef<HTMLDivElement> = (node) => {
        this.previewWindow = node;
        this.forceUpdate();
    }

    @action setVariationTab = (open: boolean) => {
        this._variationsTabOpen = open;
        if (this.previewWindow && open) {
            this.previewWindow.style.height = String(Number(this.previewWindow.clientHeight) * .6);
        } else if (this.previewWindow && !open) {
            this.previewWindow.style.height = String(Number(this.previewWindow.clientHeight) * 5/3);
        }
        this.forceUpdate();
    }

    generateVariations = async () => {
        this._props.menu._variations = [];
        this._loading = true;
        this._variationURLs = await this._props.menu.generateVariations(this._props.template.clone(false).getRenderedDoc()!, this.fireflyPrompt);
        this._variationURLs.forEach(url => {
            const newTemplate: Template = this._props.template.clone(true);
            this._props.menu._variations.push(newTemplate);
        });
        this._loading = false;
        setTimeout(() => {
            this._variationURLs.forEach((url, i) => {
                this._props.menu._variations[i].setImageAsBackground(url, true);
            });
            this.forceUpdate();
        });
    }

    get fireflyVariationsTab() {

        return (
            <>
                <div className="docCreatorMenu-option-divider full no-margin-bottom"/>
                <TemplatePreviewGrid
                    menu={this._props.menu}
                    title={'Generate Variations'}
                    loading={this._loading}
                    templates={this._props.menu._variations}
                    optionsButtonOpts={['gear', () => {}]}
                    previewBoxRightButtonOpts={['gear', (template: Template) => {this.forceUpdate();}]}
                />
                <div className="docCreatorMenu-section">
                    <div className="docCreatorMenu-variation-prompt-input">
                        <textarea
                            className="docCreatorMenu-variation-prompt-input-textbox"
                            ref={this.setPromptInputRef}
                            onChange={e => this.fireflyPrompt = e.target.value}
                            onInput={() => {
                                if (this.promptInput !== null) {
                                    this.promptInput.style.height = 'auto';
                                    this.promptInput.style.height = this.promptInput.scrollHeight + 'px';
                                }
                            }}
                            defaultValue={''}
                            placeholder={'Enter a custom prompt here (optional)'}
                        />
                        <DocCreatorMenuButton icon={'arrows-rotate'} styles={'border'} function={this.generateVariations}/>
                    </div>
                    <div className='docCreatorMenu-variation-options-container'>

                    </div>
                </div>
            </>
        )
    }
   
    get renderedDocPreview(){
        const doc: Doc = this._props.template.getRenderedDoc() as unknown as Doc;

        return (
            <div className="docCreatorMenu-expanded-template-preview" ref={this.setContainerRef}>
                {this.previewWindow ? <DocumentView
                    Document={doc}
                    isContentActive={emptyFunction}
                    addDocument={returnFalse}
                    moveDocument={returnFalse}
                    removeDocument={returnFalse}
                    PanelWidth={() => this.previewWindow?.clientWidth ?? 500}
                    PanelHeight={() => this.previewWindow?.clientHeight ?? 500}
                    ScreenToLocalTransform={() => new Transform(-this._props.menu._pageX - 5, -this._props.menu._pageY - 35, 1)}
                    renderDepth={5}
                    whenChildContentsActiveChanged={emptyFunction}
                    focus={emptyFunction}
                    styleProvider={DefaultStyleProvider}
                    addDocTab={DocumentViewInternal.addDocTabFunc}
                    pinToPres={() => undefined}
                    childFilters={returnEmptyFilter}
                    childFiltersByRanges={returnEmptyFilter}
                    searchFilterDocs={returnEmptyDoclist}
                    fitContentsToBox={returnFalse}
                    fitWidth={returnFalse}
                /> : null}
            </div>
        )
    }

    render() {
        return (
            <div className='docCreatorMenu-templates-view'>
                <div className="docCreatorMenu-expanded-template-preview">
                    <div className="top-panel"/>
                    {this.renderedDocPreview}
                    {this._variationsTabOpen ? this.fireflyVariationsTab : null}
                    <div className="right-buttons-panel">
                        <DocCreatorMenuButton icon={'minimize'} function={() => {
                                if (this._props.template === this._props.menu._selectedTemplate) {
                                    this._props.menu.updateRenderedPreviewCollection(this._props.template);
                                }
                                this._props.menu.setExpandedView(undefined);
                            }}/>
                        <DocCreatorMenuButton icon={'lightbulb'} function={() => this.setVariationTab(!this._variationsTabOpen)}/>
                    </div>
                </div>
            </div>
        );
    }
}