import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Button, IconButton, isDark, Size, Type } from 'browndash-components';
import { action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaBug } from 'react-icons/fa';
import { Doc, DocListCast } from '../../../fields/Doc';
import { AclAdmin, DashVersion } from '../../../fields/DocSymbols';
import { StrCast } from '../../../fields/Types';
import { GetEffectiveAcl } from '../../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
import { CurrentUserUtils } from '../../util/CurrentUserUtils';
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 { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { CollectionDockingView } from '../collections/CollectionDockingView';
import { CollectionLinearView } from '../collections/collectionLinear';
import { DashboardView } from '../DashboardView';
import { Colors } from '../global/globalEnums';
import { DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
import { DefaultStyleProvider } from '../StyleProvider';
import './TopBar.scss';
import { dropActionType } from '../../util/DragManager';
import { Flip } from 'react-awesome-reveal';
import { ObservableReactComponent } from '../ObservableReactComponent';

/**
 * 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 ObservableReactComponent<{}> {
    static Instance: TopBar;
    @observable private _flipDocumentation = 0;
    constructor(props: any) {
        super(props);
        makeObservable(this);
        TopBar.Instance = this;
    }

    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
        });
    };

    @computed get color() {
        return SettingsManager.userColor;
    }
    @computed get variantColor() {
        return SettingsManager.userVariantColor;
    }
    @computed get backgroundColor() {
        return PingManager.Instance.IsBeating ? SettingsManager.userBackgroundColor : 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={DocListCast(Doc.MySharedDocs.data_dashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'portrait' : 'home'} />}
                        color={this.color}
                    />
                ) : (
                    <div className="logo-container">
                        <img className="logo" src="/assets/medium-blue-light-blue-circle.png" alt="dash logo"></img>
                        <span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, fontWeight: 200 }}>brown</span>
                        <span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_BLUE : Colors.MEDIUM_BLUE, fontWeight: 500 }}>dash</span>
                    </div>
                )}
                {Doc.ActiveDashboard && (
                    <Button
                        text="Explore"
                        type={Type.TERT}
                        tooltip="Browsing mode for directly navigating to documents"
                        size={Size.SMALL}
                        color={SnappingManager.ExploreMode ? this.variantColor : this.color}
                        background={SnappingManager.ExploreMode ? this.color : 'transparent'}
                        onClick={() => SnappingManager.SetExploreMode(!SnappingManager.ExploreMode)}
                    />
                )}
            </div>
        );
    }

    @computed get dashMenuButtons() {
        const selDoc = Doc.MyTopBarBtns;
        return !(selDoc instanceof Doc) ? null : (
            <div className="collectionMenu-contMenuButtons" style={{ height: '100%' }}>
                <CollectionLinearView
                    Document={selDoc}
                    docViewPath={returnEmptyDocViewList}
                    fieldKey="data"
                    dropAction={dropActionType.embed}
                    styleProvider={DefaultStyleProvider}
                    select={emptyFunction}
                    isContentActive={returnTrue}
                    isAnyChildContentActive={returnFalse}
                    isSelected={returnFalse}
                    moveDocument={returnFalse}
                    addDocument={returnFalse}
                    addDocTab={DocumentViewInternal.addDocTabFunc}
                    pinToPres={emptyFunction}
                    removeDocument={returnFalse}
                    ScreenToLocalTransform={Transform.Identity}
                    PanelWidth={() => 200}
                    PanelHeight={() => 30}
                    renderDepth={0}
                    focus={emptyFunction}
                    whenChildContentsActiveChanged={emptyFunction}
                    childFilters={returnEmptyFilter}
                    childFiltersByRanges={returnEmptyFilter}
                    searchFilterDocs={returnEmptyDoclist}
                />
            </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="Open Dashboards"
                    size={Size.SMALL}
                    color={this.color}
                    style={{ fontWeight: 700, fontSize: '1rem' }}
                    onClick={(e: React.MouseEvent) => {
                        const dashView = Doc.ActiveDashboard && DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard);
                        dashView?.showContextMenu(e.clientX + 20, e.clientY + 30);
                    }}
                />
                {!Doc.noviceMode && this.dashMenuButtons}
            </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() {
        const upToDate = DashVersion === CurrentUserUtils.ServerVersion;
        return (
            <div className="topbar-right">
                {Doc.ActiveDashboard ? (
                    <Button
                        text={GetEffectiveAcl(Doc.ActiveDashboard) === AclAdmin ? 'Share' : 'View Original'}
                        type={Type.TERT}
                        color={SettingsManager.userColor}
                        background={this.variantColor}
                        onClick={() => {
                            SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
                        }}
                    />
                ) : null}
                <IconButton tooltip={'Issue Reporter ⌘I'} size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
                <Flip key={this._flipDocumentation}>
                    <IconButton tooltip={'Documentation ⌘D'} size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
                </Flip>
                <IconButton tooltip={'Settings ⌘⇧S'} size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
                <IconButton
                    size={Size.SMALL}
                    onClick={ServerStats.Instance.open}
                    type={Type.TERT}
                    tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running ' + (upToDate ? DashVersion : 'out of date version:' + DashVersion)}
                    color={this.happyHeart ? (upToDate ? Colors.LIGHT_BLUE : Colors.YELLOW) : Colors.ERROR_RED}
                    icon={<FontAwesomeIcon icon={this.happyHeart ? 'heart' : 'heart-broken'} />}
                />
                {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.color} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
            </div>
        );
    }

    /**
     * Make the documentation icon flip around to draw attention to it.
     */
    FlipDocumentationIcon = action(() => (this._flipDocumentation = this._flipDocumentation + 1));

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