import { PluginSettings } from './types/plugin-settings';
import { PluginData } from './types/plugin-data';
import ModalAddress from './modal-address';
import $j from './lib/jquery';
import OrderResync from './order-resync';
import ToppingDisplay from './topping-display';
import SettingsValidator from './settings-validator';

export default class FreyaSyncService {
    private static instance: FreyaSyncService;
    private readonly pluginSettings: PluginSettings;
    private readonly phpData: PluginData;

    private constructor(phpData: PluginData, settings: PluginSettings) {
        this.phpData = phpData;
        this.pluginSettings = settings;
    }

    /**
     * Bootstrap function, only used once at the beginning of plugin runtime
     * @param data
     */
    public static async bootstrap(data: PluginData) {
        if (FreyaSyncService.instance) {
            return;
        }

        const settings = await fetchSettings(data.ajax_url, data.nonce);
        FreyaSyncService.instance = new FreyaSyncService(data, settings);
        FreyaSyncService.instance.bootstrapComponents();
    }

    private bootstrapComponents() {
        ModalAddress.bootstrap();
        OrderResync.bootstrap();
        ToppingDisplay.bootstrap();
        SettingsValidator.bootstrap();
    }

    public static get sharedInstance(): FreyaSyncService {
        if (!FreyaSyncService.instance) {
            throw new Error('No instance');
        }

        return FreyaSyncService.instance;
    }

    public get settings(): PluginSettings {
        return this.pluginSettings;
    }

    public get data(): PluginData {
        return this.phpData;
    }
}

async function fetchSettings(ajax_url: string, nonce: string): Promise<PluginSettings> {
    return new Promise((resolve, reject) => {
        $j.ajax({
            type: 'POST',
            url: ajax_url,
            dataType: 'json',
            data: { action: 'freya_sync_service_get_settings', nonce: nonce },
            success: (data: { success: boolean; data: any }) => {
                const settings: PluginSettings = {
                    fsCompanyUid: data.data.fsCompanyUid,
                    fsDefaultLocationUid: data.data.fsDefaultLocationUid,
                    fsCountyRestriction: data.data.fsCountyRestriction,
                    fsServiceUrl: data.data.fsServiceUrl,
                    fsNoAddressFoundMessage: data.data.fsNoAddressFoundMessage,
                    fsAddressRequestOnPages: data.data.fsAddressRequestOnPages,
                    fsIsRunningOnLandingPageInstance: data.data.fsIsRunningOnLandingPageInstance === '1',
                    fsEnableMultiSubdomain: data.data.fsEnableMultiSubdomain === '1',
                    fsNoPolygons: data.data.fsNoPolygons === '1',
                };
                resolve(settings);
            },
            error: (xhr, ajaxOptions, thrownError) => {
                reject();
            },
        });
    });
}
