import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { Button, FontSize, IconButton, Size } from 'browndash-components';
import { action, computed, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaBug, FaCamera, FaStamp } from 'react-icons/fa';
import { Doc } from '../../../fields/Doc';
import { AclAdmin } from '../../../fields/DocSymbols';
import { StrCast } from '../../../fields/Types';
import { GetEffectiveAcl } from '../../../fields/util';
import { DocumentManager } from '../../util/DocumentManager';
import { PingManager } from '../../util/PingManager';
import { ReportManager } from '../../util/reportManager/ReportManager';
import { ServerStats } from '../../util/ServerStats';
import { SettingsManager } from '../../util/SettingsManager';
import { SharingManager } from '../../util/SharingManager';
import { UndoManager } from '../../util/UndoManager';
import { CollectionDockingView } from '../collections/CollectionDockingView';
import { ContextMenu } from '../ContextMenu';
import { DashboardView } from '../DashboardView';
import { Colors } from '../global/globalEnums';
import { MainView } from '../MainView';
import './TopBar.scss';

/**
 * ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user
 * and settings and help buttons. Future scope for this bar is to include the collaborators that are on the same Dashboard.
 */
@observer
export class TopBar extends React.Component {
    navigateToHome = () => {
        (CollectionDockingView.Instance?.CaptureThumbnail() ?? new Promise<void>(res => res())).then(() => {
            Doc.ActivePage = 'home';
            DashboardView.closeActiveDashboard(); // bcz: if we do this, we need some other way to keep track, for user convenience, of the last dashboard in use
        });
    };

    @observable textColor: string = Colors.LIGHT_GRAY;
    @computed get backgroundColor() {
        return PingManager.Instance.IsBeating ? Colors.DARK_GRAY : Colors.MEDIUM_GRAY;
    }

    @observable happyHeart: boolean = PingManager.Instance.IsBeating;
    setHappyHeart = action((status: boolean) => (this.happyHeart = status));
    dispose = reaction(
        () => PingManager.Instance.IsBeating,
        isBeating => this.setHappyHeart(isBeating)
    );

    /**
     * Returns the left hand side of the topbar.
     * This side of the topbar contains the different modes.
     * The modes include:
     * - Explore mode
     * - Tracking mode
     */
    @computed get topbarLeft() {
        return (
            <div className="topbar-left">
                {Doc.ActiveDashboard ? (
                    <IconButton onClick={this.navigateToHome} icon={<FontAwesomeIcon icon="home" />} color={this.textColor} />
                ) : (
                    <div className="logo-container">
                        <img className="logo" src="/assets/medium-blue-light-blue-circle.png" alt="dash logo"></img>
                        <span style={{ color: Colors.LIGHT_GRAY, fontWeight: 200 }}>brown</span>
                        <span style={{ color: Colors.LIGHT_BLUE, fontWeight: 500 }}>dash</span>
                    </div>
                )}
                {Doc.ActiveDashboard && (
                    <Button text="Explore" tooltip="Browsing mode for directly navigating to documents" size={Size.SMALL} color={this.textColor} onClick={action(() => (MainView.Instance._exploreMode = !MainView.Instance._exploreMode))} />
                )}
            </div>
        );
    }

    /**
     * Returns the center of the topbar
     * This part of the topbar contains everything related to the current dashboard including:
     * - Selection of dashboards
     * - Creating a new dashboard
     * - Taking a snapshot of a dashboard
     */
    @computed get topbarCenter() {
        // const dashboardItems = myDashboards.map(board => {
        //     const boardTitle = StrCast(board.title);
        //     console.log(boardTitle);
        //     return {
        //         text: boardTitle,
        //         onClick: () => DashboardView.openDashboard(board),
        //         val: board,
        //     };
        // });
        return Doc.ActiveDashboard ? (
            <div className="topbar-center">
                <Button
                    text={StrCast(Doc.ActiveDashboard.title)}
                    tooltip="Browsing mode for directly navigating to documents"
                    size={Size.SMALL}
                    color={'white'}
                    onClick={(e: React.MouseEvent) => {
                        const dashView = Doc.ActiveDashboard && DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard);
                        ContextMenu.Instance.addItem({ description: 'Open Dashboard View', event: this.navigateToHome, icon: 'edit' });
                        ContextMenu.Instance.addItem({
                            description: 'Snapshot Dashboard',
                            event: async () => {
                                const batch = UndoManager.StartBatch('snapshot');
                                await DashboardView.snapshotDashboard();
                                batch.end();
                            },
                            icon: 'edit',
                        });
                        dashView?.showContextMenu(e.clientX + 20, e.clientY + 30);
                    }}
                />
                <Button
                    text={GetEffectiveAcl(Doc.GetProto(Doc.ActiveDashboard)) === AclAdmin ? 'Share' : 'View Original'}
                    onClick={() => {
                        SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
                    }}
                    size={Size.SMALL}
                />
                {!Doc.noviceMode && (
                    <IconButton
                        tooltip="Work on a copy of the dashboard layout"
                        size={Size.SMALL}
                        color={this.textColor}
                        onClick={async () => {
                            const batch = UndoManager.StartBatch('snapshot');
                            await DashboardView.snapshotDashboard();
                            batch.end();
                        }}
                        icon={<FaCamera />}
                    />
                )}
            </div>
        ) : null;
    }

    /**
     * Returns the right hand side of the topbar.
     * This part of the topbar includes information about the current user,
     * and allows the user to access their account settings etc.
     */
    @computed get topbarRight() {
        return (
            <div className="topbar-right">
                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ReportManager.Instance.open} icon={<FaBug />} />
                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
                <Tooltip title={<div className="dash-tooltip">{'Server connection ' + (PingManager.Instance.IsBeating ? 'active' : 'broken')}</div>}>
                    <div className={'topbarHeart' + (this.happyHeart ? '' : '-red')}>
                        <IconButton
                            size={Size.SMALL}
                            onClick={PingManager.Instance.showAlert}
                            tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running'}
                            color={this.happyHeart ? Colors.LIGHT_BLUE : Colors.ERROR_RED}
                            icon={<FontAwesomeIcon icon={this.happyHeart ? 'heart' : 'heart-broken'} />}
                        />
                    </div>
                </Tooltip>
                {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.textColor} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
            </div>
        );
    }

    render() {
        return (
            //TODO:glr Add support for light / dark mode
            <div style={{ pointerEvents: 'all' }} className="topbar-container">
                <div
                    className="topbar-inner-container"
                    style={{
                        color: this.textColor,
                        background: this.backgroundColor,
                    }}>
                    {this.topbarLeft}
                    {this.topbarCenter}
                    {this.topbarRight}
                </div>
            </div>
        );
    }
}
