import { FormPageState } from '@wix/bex-core';
import { action, computed, makeObservable, observable } from 'mobx';
import { SettingsPageStateBIReporter } from './SettingsPageStateBIReporter';
import { EventEmitter } from '@wix/bex-core/events';
export class SettingsPageState {
    constructor(params) {
        this._settings = null;
        this.events = new EventEmitter();
        this.fetch = params.fetch;
        this._onSave = params.onSave;
        this._onCancel = params.onCancel;
        this.saveSuccessToast = params.saveSuccessToast;
        this.saveErrorToast = params.saveErrorToast;
        this.formPage = new FormPageState({ form: params.form });
        this.container = params.container;
        this.reportBI = this.container.createBILogger({
            componentType: 'Settings page',
            pageType: 'Settings',
            route: window.location.pathname,
        });
        this.bi = new SettingsPageStateBIReporter({
            reportBI: this.reportBI,
            settingsPageState: this,
        });
        this.bi.init();
        makeObservable(this, {
            handleSubmit: action,
            _settings: observable.ref,
            setSettings: action,
            isDirty: computed,
        });
    }
    init() {
        const { formPage: { initTask }, container, } = this;
        const { onBeforeUnload } = container;
        const onBeforeUnloadSubscription = onBeforeUnload?.(action((event) => {
            if (!this.isDirty) {
                return;
            }
            event.preventDefault();
            this.bi.reportOnBeforeUnload();
        }));
        initTask.runOnce(async () => {
            const [data] = await Promise.all([
                this.fetch(),
                container.initTask.status.promise,
            ]);
            this.setSettings(data.settings ?? null);
            this.bi.appLoaded?.();
        });
        return () => {
            onBeforeUnloadSubscription?.remove();
        };
    }
    retryFetch() {
        this.formPage.retryFetch();
    }
    setSettings(newSettings) {
        this._settings = newSettings;
    }
    get settings() {
        return this._settings;
    }
    get isFetching() {
        return this.formPage.isFetching;
    }
    get form() {
        return this.formPage.form;
    }
    get isDirty() {
        return this.formPage.isDirty;
    }
    onCancel() {
        this.bi.reportButtonClick({ ctaName: 'Cancel' });
        this._onCancel();
    }
    _showErrorToast(err, e) {
        const errorToast = this.saveErrorToast?.(err, {
            retry: () => this.handleSubmit(e),
        });
        const message = typeof errorToast === 'string' ? errorToast : errorToast?.message;
        const showTryAgain = typeof errorToast === 'string' ? true : errorToast?.tryAgain !== false;
        const action = typeof errorToast === 'string' ? undefined : errorToast?.action;
        this.container.showToast?.({
            type: 'ERROR',
            biName: 'cairo-settings-page-save-error-toast',
            message: message ??
                this.container.translate(err?.code === 'ERR_NETWORK'
                    ? 'cairo.entityPage.saveError-offline.toast.description'
                    : 'cairo.entityPage.saveError-technical.toast.description'),
            action: action || showTryAgain
                ? {
                    uiType: 'LINK',
                    text: action?.text ?? this.container.translate('cairo.toast.retry'),
                    onClick: () => {
                        if (action?.onClick) {
                            action.onClick();
                        }
                        else {
                            this.bi.reportSaveTryAgain();
                            this.handleSubmit(e);
                        }
                    },
                    removeToastOnClick: true,
                }
                : undefined,
        });
    }
    _showSuccessToast() {
        const message = typeof this.saveSuccessToast === 'string'
            ? this.saveSuccessToast
            : this.saveSuccessToast?.message;
        this.container.showToast?.({
            type: 'SUCCESS',
            biName: 'cairo-settings-page-save-success-toast',
            message: message ?? this.container.translate('cairo.entityPage.success.toast'),
        });
    }
    async handleSubmit(e) {
        if (this.formPage.submitTask.status.isLoading) {
            return;
        }
        this.events.emit('save');
        const { form, formPage: { submitTask }, bi, } = this;
        submitTask.run(async () => {
            await form.handleSubmit(async () => {
                bi.reportButtonClick({ ctaName: 'Save', isValid: true });
                try {
                    if (!this.isFetching) {
                        await this._onSave();
                        form.reset(form.getValues());
                    }
                    this._showSuccessToast();
                }
                catch (err) {
                    this._showErrorToast(err, e);
                    this.container.errorMonitor.captureException(err);
                    this.events.emit('saveError', err);
                    form.setError('root.serverError', {}); // https://react-hook-form.com/docs/useform/seterror
                }
            }, () => {
                bi.reportButtonClick({ ctaName: 'Save', isValid: false });
            })(e);
        });
        await this.formPage.submitTask.status.promise;
    }
    get initTask() {
        return this.formPage.initTask;
    }
    get submitTask() {
        return this.formPage.submitTask;
    }
}
//# sourceMappingURL=SettingsPageState.js.map