import {
  createAppSettingsCapsule,
  getErrorMonitorCompat,
  getExperimentsCompat,
  getHostContainerCompat,
  getWixPatternsWindowExperiments,
  showToastCompat,
  WixPatternsEssentials,
} from '@wix/bex-core';
import { CairoProviderBaseProps, usePageLocation } from '@wix/bex-core/react';
import { Trans, useTranslation } from '@wix/bex-utils/@wix/wix-i18n-config';
import { Essentials } from '@wix/fe-essentials/core';
import React, { useState } from 'react';
import { CairoProvider as CairoProviderBase } from '../providers';
import { dashboard as dashboardType, EnvironmentState } from '@wix/dashboard';
import { getInstanceJwtData } from './getInstanceJwtData';
import { bi, errorHandler, experiments } from '@wix/essentials';

export interface WixPatternsProviderProps
  extends Omit<CairoProviderBaseProps, 'localCache' | 'contextType'> {}

interface WixPatternsProviderPrivateProps extends WixPatternsProviderProps {
  dashboard: Pick<
    typeof dashboardType,
    | 'showToast'
    | 'navigate'
    | 'onBeforeUnload'
    | 'onLayerStateChange'
    | 'getDashboardMenuPlugins'
    | 'getDashboardPlugins'
    | 'openMediaManager'
  >;
  environment: EnvironmentState;
  essentials: Essentials;
}

export function WixPatternsDashboardBaseProvider({
  children,
  dashboard,
  environment: { locale, pageLocation },
  essentials,
  ...rest
}: WixPatternsProviderPrivateProps) {
  const [value] = useState((): WixPatternsEssentials => {
    const jwtData = getInstanceJwtData(window.location.search);

    const user = {
      id: jwtData?.uid,
      permissions: ['DATA_EXTENSION_SCHEMA.WRITE'],
    };

    const environment = {
      language: locale || 'en',
      artifactId: essentials.environment.artifactId,
      componentId: pageLocation.pageId,
      providerType: 'bm' as const,
      msid: jwtData?.metaSiteId,
    };

    // ready doesn't exist in the dashboard-sdk because it's always true. adding it for backwards compatibility
    const experimentsWithReady = {
      ...experiments,
      ready: async () => true,
    };

    let biLogger;
    try {
      biLogger = bi.getLogger();
    } catch (error) {
      console.error(error);
    }

    return {
      useExperiments: () => ({
        ready: true,
        experiments: getExperimentsCompat({
          experiments: experimentsWithReady,
        }),
      }),
      experiments: getExperimentsCompat({ experiments: experimentsWithReady }),
      Trans,
      useTranslation,
      showToast: showToastCompat(dashboard.showToast),
      usePageLocation,
      navigateTo: ({
        pageId = pageLocation.pageId,
        relativeUrl,
        displayMode,
        history,
      }) =>
        dashboard.navigate({ pageId, relativeUrl }, { displayMode, history }),
      onSidePanelOpen: undefined, // missing in dashboard-sdk
      onBeforeUnload: dashboard.onBeforeUnload,
      onLayerStateChange: dashboard.onLayerStateChange,
      openMediaManager: dashboard.openMediaManager,
      closeSidePanel: undefined, // missing in dashboard-sdk
      getHostContainer: getHostContainerCompat(
        dashboard.getDashboardMenuPlugins,
        dashboard.getDashboardPlugins,
      ),
      environment,
      user,
      environmentBI: {
        componentId: environment.componentId,
      },
      httpClient: essentials.httpClient,
      errorMonitor: getErrorMonitorCompat(essentials.asPartial),
      errorHandler,
      biLogger,
      createEssentials: (options) => {
        return essentials.createChildEssentials({
          ...options,
          experiments:
            options.experiments &&
            'scopes' in options.experiments &&
            options.experiments?.scopes[0] === 'cairo'
              ? {
                  bag: getWixPatternsWindowExperiments() ?? {},
                }
              : options.experiments,
        });
      },
      createComponentSettings: createAppSettingsCapsule,
    };
  });

  return (
    <CairoProviderBase {...rest} value={value}>
      {children}
    </CairoProviderBase>
  );
}
