import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from '@material-ui/core';
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import { Doc } from "../../fields/Doc";
import { InkField } from '../../fields/InkField';
import { RichTextField } from '../../fields/RichTextField';
import { Cast, NumCast } from "../../fields/Types";
import { ImageField } from '../../fields/URLField';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
import { GooglePhotos } from '../apis/google_docs/GooglePhotosClientUtils';
import { Docs, DocUtils } from '../documents/Documents';
import { DocumentType } from '../documents/DocumentTypes';
import { SelectionManager } from '../util/SelectionManager';
import { undoBatch } from '../util/UndoManager';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
import './PropertiesButtons.scss';
import React = require("react");
import { CollectionViewType } from './collections/CollectionView';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
const cloud: IconProp = "cloud-upload-alt";
const fetch: IconProp = "sync-alt";
enum UtilityButtonState {
    Default,
    OpenRight,
    OpenExternally
}
@observer
export class PropertiesButtons extends React.Component<{}, {}> {
    private _pullAnimating = false;
    private _pushAnimating = false;
    private _pullColorAnimating = false;
    @observable private pushIcon: IconProp = "arrow-alt-circle-up";
    @observable private pullIcon: IconProp = "arrow-alt-circle-down";
    @observable private pullColor: string = "white";
    @observable public isAnimatingFetch = false;
    @observable public isAnimatingPulse = false;
    @observable private openHover: UtilityButtonState = UtilityButtonState.Default;
    @observable public static Instance: PropertiesButtons;
    public static hasPushedHack = false;
    public static hasPulledHack = false;
    @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; }
    @computed get selectedDocumentView() {
        if (SelectionManager.SelectedDocuments().length) {
            return SelectionManager.SelectedDocuments()[0];
        } else return undefined;
    }
    @computed get onClick() { return this.selectedDoc?.onClickBehavior ? this.selectedDoc?.onClickBehavior : "nothing"; }
    public startPullOutcome = action((success: boolean) => {
        if (!this._pullAnimating) {
            this._pullAnimating = true;
            this.pullIcon = success ? "check-circle" : "stop-circle";
            setTimeout(() => runInAction(() => {
                this.pullIcon = "arrow-alt-circle-down";
                this._pullAnimating = false;
            }), 1000);
        }
    });
    public startPushOutcome = action((success: boolean) => {
        this.isAnimatingPulse = false;
        if (!this._pushAnimating) {
            this._pushAnimating = true;
            this.pushIcon = success ? "check-circle" : "stop-circle";
            setTimeout(() => runInAction(() => {
                this.pushIcon = "arrow-alt-circle-up";
                this._pushAnimating = false;
            }), 1000);
        }
    });
    public setPullState = action((unchanged: boolean) => {
        this.isAnimatingFetch = false;
        if (!this._pullColorAnimating) {
            this._pullColorAnimating = true;
            this.pullColor = unchanged ? "lawngreen" : "red";
            setTimeout(this.clearPullColor, 1000);
        }
    });
    private clearPullColor = action(() => {
        this.pullColor = "white";
        this._pullColorAnimating = false;
    });
    @computed
    get considerGoogleDocsPush() {
        const targetDoc = this.selectedDoc;
        const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
        const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
        return !targetDoc ? (null) : {`${published ? "Push" : "Publish"} to Google Docs`}} placement="top">
            
                 {
                        await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
                        !published && runInAction(() => this.isAnimatingPulse = true);
                        PropertiesButtons.hasPushedHack = false;
                        targetDoc[Pushes] = NumCast(targetDoc[Pushes]) + 1;
                    }}>
                    
                
                Google
             
        ;
    }
    @computed
    get considerGoogleDocsPull() {
        const targetDoc = this.selectedDoc;
        const dataDoc = targetDoc && Doc.GetProto(targetDoc);
        const animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
        const title = (() => {
            switch (this.openHover) {
                default:
                case UtilityButtonState.Default: return `${!dataDoc?.unchanged ? "Pull from" : "Fetch"} Google Docs`;
                case UtilityButtonState.OpenRight: return "Open in Right Split";
                case UtilityButtonState.OpenExternally: return "Open in new Browser Tab";
            }
        })();
        return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) : {title}
>} placement="top">
            
                 {
                        e.altKey && (this.openHover = UtilityButtonState.OpenExternally);
                        e.shiftKey && (this.openHover = UtilityButtonState.OpenRight);
                    })}
                    onPointerLeave={action(() => this.openHover = UtilityButtonState.Default)}
                    onClick={async e => {
                        const googleDocUrl = `https://docs.google.com/document/d/${dataDoc[GoogleRef]}/edit`;
                        if (e.shiftKey) {
                            e.preventDefault();
                            let googleDoc = await Cast(dataDoc.googleDoc, Doc);
                            if (!googleDoc) {
                                const options = { _width: 600, _fitWidth: true, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, useCors: false };
                                googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
                                dataDoc.googleDoc = googleDoc;
                            }
                            CollectionDockingView.AddSplit(googleDoc, "right");
                        } else if (e.altKey) {
                            e.preventDefault();
                            window.open(googleDocUrl);
                        } else {
                            this.clearPullColor();
                            PropertiesButtons.hasPulledHack = false;
                            targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1;
                            dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true);
                        }
                    }}>
                     {
                            switch (this.openHover) {
                                default:
                                case UtilityButtonState.Default: return dataDoc.unchanged === false ? (this.pullIcon as any) : fetch;
                                case UtilityButtonState.OpenRight: return "arrow-alt-circle-right";
                                case UtilityButtonState.OpenExternally: return "share";
                            }
                        })()}
                    />
                
                Fetch
             
        ;
    }
    @action @undoBatch
    onLock = () => {
        SelectionManager.SelectedDocuments().forEach(dv => dv.toggleLockPosition());
    }
    @computed
    get lockButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {`${this.selectedDoc?.lockedPosition ? "Unlock" : "Lock"} Position`}} placement="top">
            
        ;
    }
    @computed
    get downloadButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {"Download Document"}} placement="top">
            
                 this.selectedDoc && Doc.Zip(this.selectedDoc)}>
                    
                
                 downld 
             
        ;
    }
    @undoBatch
    @action
    setDictation = () => {
        SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._showAudio = dv.rootDoc._showAudio === !dv.rootDoc._showAudio);
    }
    @computed
    get dictationButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {"Show Dictation Controls"}} placement="top">
            
        ;
    }
    @undoBatch
    @action
    setTitle = () => {
        SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._showTitle = dv.rootDoc._showTitle === undefined ? "title" : undefined);
    }
    @computed
    get titleButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {"Show Title Header"}} placement="top">
            
        ;
    }
    @undoBatch
    @action
    setCaption = () => {
        SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._showCaption = dv.rootDoc._showCaption === undefined ? "caption" : undefined);
    }
    @computed
    get captionButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {"Show Caption Footer"}} placement="top">
            
        ;
    }
    @undoBatch
    @action
    setChrome = () => {
        SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._chromeStatus = dv.rootDoc._chromeStatus === "disabled" ? "enabled" : "disabled");
    }
    @computed
    get chromeButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {"Show Editing UI"}} placement="top">
            
        ;
    }
    @computed
    get onClickButton() {
        if (this.selectedDoc) {
            return Choose onClick behavior
>} placement="top">
                
                    
                        
                             e.stopPropagation()} >
                                {}
                            
                        
                     
                     onclick 
                 
            ;
        } else {
            return null;
        }
    }
    @undoBatch
    @action
    handleOptionChange = (e: any) => {
        const value = e.target.value;
        this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value);
        SelectionManager.SelectedDocuments().forEach(dv => {
            if (value === "nothing") {
                dv.noOnClick();
            } else if (value === "enterPortal") {
                dv.noOnClick();
                dv.makeIntoPortal();
            } else if (value === "toggleDetail") {
                dv.noOnClick();
                dv.toggleDetail();
            } else if (value === "linkInPlace") {
                dv.noOnClick();
                dv.toggleFollowLink("inPlace", true, false);
            } else if (value === "linkOnRight") {
                dv.noOnClick();
                dv.toggleFollowLink("add:right", false, false);
            }
        });
    }
    @undoBatch @action
    editOnClickScript = () => {
        if (this.selectedDoc) {
            if (SelectionManager.SelectedDocuments().length) SelectionManager.SelectedDocuments().forEach(dv => DocUtils.makeCustomViewClicked(dv.rootDoc, undefined, "onClick"));
            else DocUtils.makeCustomViewClicked(this.selectedDoc, undefined, "onClick");
        }
    }
    @computed
    get onClickFlyout() {
        return 
            {Doc.UserDoc().noviceMode ? (null) : 
 Edit onClick Script
}
        
{"Export to Google Photos"}
>} placement="top">
            
                 this.selectedDoc && GooglePhotos.Export.CollectionToAlbum({ collection: this.selectedDoc }).then(console.log)}>
                    {}
                
                 google 
             
        ;
    }
    @computed
    get clustersButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {this.selectedDoc?._useClusters ? "Stop Showing Clusters" : "Show Clusters"}
>} placement="top">
            
        ;
    }
    @action @undoBatch
    changeFitToBox = () => {
        if (this.selectedDoc) {
            if (SelectionManager.SelectedDocuments().length) SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._fitToBox = !dv.rootDoc._fitToBox);
            else this.selectedDoc._fitToBox = !this.selectedDoc._fitToBox;
        }
    }
    @action @undoBatch
    changeClusters = () => {
        if (this.selectedDoc) {
            if (SelectionManager.SelectedDocuments().length) SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._useClusters = !dv.rootDoc._useClusters);
            else this.selectedDoc._useClusters = !this.selectedDoc._useClusters;
        }
    }
    @computed
    get fitContentButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : {this.selectedDoc?._fitToBox ? "Stop Fitting Content" : "Fit Content"}
>} placement="top">
            
                
                    
                
                 {this.selectedDoc?._fitToBox ? "unfit" : "fit"} 
             
        ;
    }
    @undoBatch
    @action
    private makeMask = () => {
        if (this.selectedDoc) {
            this.selectedDoc._backgroundColor = "rgba(0,0,0,0.7)";
            this.selectedDoc.mixBlendMode = "hard-light";
            this.selectedDoc.color = "#9b9b9bff";
            this.selectedDoc._stayInCollection = true;
            this.selectedDoc.isInkMask = true;
        }
    }
    @computed
    get maskButton() {
        const targetDoc = this.selectedDoc;
        return !targetDoc ? (null) : Make Mask
>} placement="top">
            
        ;
    }
    render() {
        if (!this.selectedDoc) return (null);
        const layoutField = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)];
        const isText = layoutField instanceof RichTextField;
        const isImage = layoutField instanceof ImageField;
        const isInk = layoutField instanceof InkField;
        const isCollection = this.selectedDoc.type === DocumentType.COL;
        const isFreeForm = this.selectedDoc._viewType === CollectionViewType.Freeform;
        const considerPull = isText && this.considerGoogleDocsPull;
        const considerPush = isText && this.considerGoogleDocsPush;
        return 
            
                {this.titleButton}
            
            
                {this.captionButton}
            
            
                {this.chromeButton}
            
            
                {this.lockButton}
            
            
                {this.dictationButton}
            
            
                {this.onClickButton}
            
            
                {this.considerGoogleDocsPush}
            
            
                {this.considerGoogleDocsPull}
            
            
                {this.googlePhotosButton}
            
            
                {this.clustersButton}
            
            
                {this.fitContentButton}
            
            
                {this.maskButton}
            
         ;
    }
}