import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { DataSym, Doc, DocListCast, DocListCastAsync } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { Cast, ImageCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { Docs, DocumentOptions } from '../documents/Documents';
import { CollectionViewType } from '../documents/DocumentTypes';
import { HistoryUtil } from '../util/History';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
import { SharingManager } from '../util/SharingManager';
import { undoBatch } from '../util/UndoManager';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionView } from './collections/CollectionView';
import { ContextMenu } from './ContextMenu';
import './DashboardView.scss';
import { MainViewModal } from './MainViewModal';
enum DashboardGroup {
    MyDashboards,
    SharedDashboards,
}
// DashboardView is the view with the dashboard previews, rendered when the app first loads
@observer
export class DashboardView extends React.Component {
    //TODO: delete dashboard, share dashboard, etc.
    public static _urlState: HistoryUtil.DocUrl;
    @observable private selectedDashboardGroup = DashboardGroup.MyDashboards;
    @observable private newDashboardName: string | undefined = undefined;
    @action abortCreateNewDashboard = () => {
        this.newDashboardName = undefined;
    };
    @action setNewDashboardName(name: string) {
        this.newDashboardName = name;
    }
    @action
    selectDashboardGroup = (group: DashboardGroup) => {
        this.selectedDashboardGroup = group;
    };
    clickDashboard = async (e: React.MouseEvent, dashboard: Doc) => {
        if (e.detail === 2) {
            Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
            Doc.ActiveDashboard = dashboard;
            Doc.ActivePage = 'dashboard';
        }
    };
    getDashboards = () => {
        const allDashboards = DocListCast(Doc.MyDashboards.data);
        if (this.selectedDashboardGroup === DashboardGroup.MyDashboards) {
            return allDashboards.filter(dashboard => Doc.GetProto(dashboard).author === Doc.CurrentUserEmail);
        } else {
            const sharedDashboards = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._viewType === CollectionViewType.Docking);
            return sharedDashboards;
        }
    };
    isUnviewedSharedDashboard = (dashboard: Doc): boolean => {
        // const sharedDashboards = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._viewType === CollectionViewType.Docking);
        return !DocListCast(Doc.MySharedDocs.viewed).includes(dashboard);
    };
    getSharedDashboards = () => {
        const sharedDashs = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._viewType === CollectionViewType.Docking);
        return sharedDashs.filter(dashboard => !DocListCast(Doc.MySharedDocs.viewed).includes(dashboard));
    };
    @undoBatch
    createNewDashboard = async (name: string) => {
        DashboardView.createNewDashboard(undefined, name);
        this.abortCreateNewDashboard();
    };
    @computed
    get namingInterface() {
        return (
            
                 this.setNewDashboardName((e.target as any).value)} />
                
                
            
        );
    }
    _downX: number = 0;
    _downY: number = 0;
    @action
    onContextMenu = (dashboard: Doc, e?: React.MouseEvent, pageX?: number, pageY?: number) => {
        // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
        if (e) {
            e.preventDefault();
            e.stopPropagation();
            e.persist();
            if (!navigator.userAgent.includes('Mozilla') && (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3)) {
                return;
            }
            const cm = ContextMenu.Instance;
            cm.addItem({
                description: 'Share Dashboard',
                event: async () => {
                    SharingManager.Instance.open(undefined, dashboard);
                },
                icon: 'edit',
            });
            cm.addItem({
                description: 'Delete Dashboard',
                event: async () => {
                    DashboardView.removeDashboard(dashboard);
                },
                icon: 'trash',
            });
            cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15);
        }
    };
    render() {
        return (
            <>
                
                    
                         {
                                this.setNewDashboardName('');
                            }}>
                            New
                        
                         this.selectDashboardGroup(DashboardGroup.MyDashboards)}>
                            My Dashboards
                        
                         this.selectDashboardGroup(DashboardGroup.SharedDashboards)}>
                            Shared Dashboards
                        
                     
                    
                        {this.getDashboards().map(dashboard => {
                            const href = ImageCast((dashboard.thumb as Doc)?.data)?.url.href;
                            return (
                                
 {
                                        this.onContextMenu(dashboard, e);
                                    }}
                                    onClick={e => this.clickDashboard(e, dashboard)}>
                                    
                                    
                                         {StrCast(dashboard.title)} 
                                        {this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ? 
unviewed
 : 
}
                                        
 {
                                                this._downX = e.clientX;
                                                this._downY = e.clientY;
                                            }}
                                            onClick={e => {
                                                this.onContextMenu(dashboard, e);
                                            }}>
                                            
                                        
                                     
                                
                            );
                        })}
                    
 
                 
                
                ;
            >
        );
    }
    public static closeActiveDashboard() {
        Doc.ActiveDashboard = undefined;
    }
    public static snapshotDashboard() {
        return CollectionDockingView.TakeSnapshot(Doc.ActiveDashboard);
    }
    /// opens a dashboard as the ActiveDashboard (and adds the dashboard to the users list of dashboards if it's not already there).
    /// this also sets the readonly state of the dashboard based on the current mode of dash (from its url)
    public static openDashboard = (doc: Doc | undefined, fromHistory = false) => {
        if (!doc) return false;
        Doc.MainDocId = doc[Id];
        Doc.AddDocToList(Doc.MyDashboards, 'data', doc);
        // this has the side-effect of setting the main container since we're assigning the active/guest dashboard
        Doc.UserDoc() ? (Doc.ActiveDashboard = doc) : (Doc.GuestDashboard = doc);
        const state = DashboardView._urlState;
        if (state.sharing === true && !Doc.UserDoc()) {
            DocServer.Control.makeReadOnly();
        } else {
            fromHistory ||
                HistoryUtil.pushState({
                    type: 'doc',
                    docId: doc[Id],
                    readonly: state.readonly,
                    nro: state.nro,
                    sharing: false,
                });
            if (state.readonly === true || state.readonly === null) {
                DocServer.Control.makeReadOnly();
            } else if (state.safe) {
                if (!state.nro) {
                    DocServer.Control.makeReadOnly();
                }
                CollectionView.SetSafeMode(true);
            } else if (state.nro || state.nro === null || state.readonly === false) {
            } else if (doc.readOnly) {
                DocServer.Control.makeReadOnly();
            } else {
                Doc.CurrentUserEmail !== 'guest' && DocServer.Control.makeEditable();
            }
        }
        return true;
    };
    public static removeDashboard = async (dashboard: Doc) => {
        const dashboards = await DocListCastAsync(Doc.MyDashboards.data);
        if (dashboards?.length) {
            if (dashboard === Doc.ActiveDashboard) DashboardView.openDashboard(dashboards.find(doc => doc !== dashboard));
            Doc.RemoveDocFromList(Doc.MyDashboards, 'data', dashboard);
            if (!dashboards.length) Doc.ActivePage = 'home';
        }
    };
    public static createNewDashboard = (id?: string, name?: string) => {
        const presentation = Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true);
        const dashboards = Doc.MyDashboards;
        const dashboardCount = DocListCast(dashboards.data).length + 1;
        const freeformOptions: DocumentOptions = {
            x: 0,
            y: 400,
            _width: 1500,
            _height: 1000,
            _fitWidth: true,
            _backgroundGridShow: true,
            title: `Untitled Tab 1`,
        };
        const title = name ? name : `Dashboard ${dashboardCount}`;
        const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
        const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
        freeformDoc.context = dashboardDoc;
        // switching the tabs from the datadoc to the regular doc
        const dashboardTabs = DocListCast(dashboardDoc[DataSym].data);
        dashboardDoc.data = new List(dashboardTabs);
        dashboardDoc['pane-count'] = 1;
        Doc.ActivePresentation = presentation;
        Doc.AddDocToList(dashboards, 'data', dashboardDoc);
        // open this new dashboard
        Doc.ActiveDashboard = dashboardDoc;
        Doc.ActivePage = 'dashboard';
    };
}
export function AddToList(MySharedDocs: Doc, arg1: string, dash: any) {
    throw new Error('Function not implemented.');
}
ScriptingGlobals.add(function createNewDashboard() {
    return DashboardView.createNewDashboard();
}, 'creates a new dashboard when called');
ScriptingGlobals.add(function shareDashboard(dashboard: Doc) {
    SharingManager.Instance.open(undefined, dashboard);
}, 'opens sharing dialog for Dashboard');
ScriptingGlobals.add(function removeDashboard(dashboard: Doc) {
    DashboardView.removeDashboard(dashboard);
}, 'Remove Dashboard from Dashboards');
ScriptingGlobals.add(function addToDashboards(dashboard: Doc) {
    DashboardView.openDashboard(Doc.MakeAlias(dashboard));
}, 'adds Dashboard to set of Dashboards');
ScriptingGlobals.add(function snapshotDashboard() {
    DashboardView.snapshotDashboard();
}, 'creates a snapshot copy of a dashboard');