import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { ColorState, SketchPicker } from 'react-color';
import { Doc } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { BoolCast, Cast, StrCast } from '../../fields/Types';
import { addStyleSheet, addStyleSheetRule, Utils } from '../../Utils';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { DocServer } from '../DocServer';
import { Networking } from '../Network';
import { MainViewModal } from '../views/MainViewModal';
import { FontIconBox } from '../views/nodes/button/FontIconBox';
import { DragManager } from './DragManager';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
import { undoBatch } from './UndoManager';
const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
export enum ColorScheme {
    Dark = '-Dark',
    Light = '-Light',
    System = '-MatchSystem',
}
@observer
export class SettingsManager extends React.Component<{}> {
    public static Instance: SettingsManager;
    static _settingsStyle = addStyleSheet();
    @observable private isOpen = false;
    @observable private passwordResultText = '';
    @observable private playgroundMode = false;
    @observable private curr_password = '';
    @observable private new_password = '';
    @observable private new_confirm = '';
    @observable activeTab = 'Accounts';
    @observable public static propertiesWidth: number = 0;
    @observable public static headerBarHeight: number = 0;
    @computed get backgroundColor() {
        return Doc.UserDoc().activeCollectionBackground;
    }
    @computed get colorScheme() {
        return Doc.ActiveDashboard?.colorScheme;
    }
    constructor(props: {}) {
        super(props);
        SettingsManager.Instance = this;
    }
    public close = action(() => (this.isOpen = false));
    public open = action(() => (this.isOpen = true));
    private googleAuthorize = action(() => GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true));
    private changePassword = async () => {
        if (!(this.curr_password && this.new_password && this.new_confirm)) {
            runInAction(() => (this.passwordResultText = "Error: Hey, we're missing some fields!"));
        } else {
            const passwordBundle = { curr_pass: this.curr_password, new_pass: this.new_password, new_confirm: this.new_confirm };
            const { error } = await Networking.PostToServer('/internalResetPassword', passwordBundle);
            runInAction(() => (this.passwordResultText = error ? 'Error: ' + error[0].msg + '...' : 'Password successfully updated!'));
        }
    };
    @undoBatch selectUserMode = action((e: React.ChangeEvent) => (Doc.noviceMode = (e.currentTarget as any)?.value === 'Novice'));
    @undoBatch changeShowTitle = action((e: React.ChangeEvent) => (Doc.UserDoc().showTitle = (e.currentTarget as any).value ? 'title' : undefined));
    @undoBatch changeFontFamily = action((e: React.ChangeEvent) => (Doc.UserDoc().fontFamily = (e.currentTarget as any).value));
    @undoBatch changeFontSize = action((e: React.ChangeEvent) => (Doc.UserDoc().fontSize = (e.currentTarget as any).value));
    @undoBatch switchActiveBackgroundColor = action((color: ColorState) => (Doc.UserDoc().activeCollectionBackground = String(color.hex)));
    @undoBatch switchUserColor = action((color: ColorState) => {
        Doc.SharingDoc().userColor = undefined;
        Doc.GetProto(Doc.SharingDoc()).userColor = String(color.hex);
    });
    @undoBatch playgroundModeToggle = action(() => {
        this.playgroundMode = !this.playgroundMode;
        if (this.playgroundMode) {
            DocServer.Control.makeReadOnly();
            addStyleSheetRule(SettingsManager._settingsStyle, 'topbar-inner-container', { background: 'red !important' });
        } else Doc.CurrentUserEmail !== 'guest' && DocServer.Control.makeEditable();
    });
    @undoBatch
    @action
    changeColorScheme = action((e: React.ChangeEvent) => {
        const activeDashboard = Doc.ActiveDashboard;
        if (!activeDashboard) return;
        const scheme: ColorScheme = (e.currentTarget as any).value;
        switch (scheme) {
            case ColorScheme.Light:
                activeDashboard.colorScheme = undefined; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
                addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: '#d3d3d3 !important' });
                break;
            case ColorScheme.Dark:
                activeDashboard.colorScheme = ColorScheme.Dark;
                addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: 'black !important' });
                break;
            case ColorScheme.System:
            default:
                window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
                    activeDashboard.colorScheme = e.matches ? ColorScheme.Dark : undefined; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
                });
                break;
        }
    });
    @computed get colorsContent() {
        const colorBox = (func: (color: ColorState) => void) => (