import React, { ReactNode, useState } from 'react';
import {
  WixPatternsEssentials,
  WixPatternsEssentialsOverrides,
} from '@wix/bex-core';
import { CairoProviderBaseProps } from '@wix/bex-core/react';
import {
  Trans,
  useEssentials,
  useExperiments,
  useTranslation,
} from '@wix/fe-essentials/react';
import {
  AppSettingsStorageStrategy,
  DataCapsule,
} from '@wix/fe-essentials/data-capsule';
import { CairoProvider } from '../providers';
import ExtensionWidget from './ExtensionWidget';
import { Edit } from '@wix/wix-ui-icons-common';
import { ErrorHandler } from '@wix/fe-essentials/error-handler';

export interface WixPatternsEssentialsTestProviderProps
  extends CairoProviderBaseProps {
  children?: ReactNode;
  overrides?: Partial<WixPatternsEssentialsOverrides>;
  defaultExperiments?: Record<string, string>;
}

export function WixPatternsEssentialsTestProvider(
  props: WixPatternsEssentialsTestProviderProps,
) {
  const { children, overrides, defaultExperiments, ...rest } = props;
  const {
    errorMonitor,
    httpClient,
    environment,
    createChildEssentials,
    experiments,
    biLoggerFactory,
  } = useEssentials();

  const [value] = useState(
    (): WixPatternsEssentials => ({
      createEssentials: (options) =>
        createChildEssentials({
          ...options,
          experiments:
            options.experiments &&
            'scopes' in options.experiments &&
            options.experiments?.scopes[0] === 'cairo'
              ? {
                  bag: {
                    ...(new URLSearchParams(window.location.search)
                      .get('id')
                      ?.includes('responsivetoolbar') && {
                      'specs.cairo.EnableResponsiveToolbar11420': 'true',
                    }),
                    ...(new URLSearchParams(window.location.search)
                      .get('id')
                      ?.includes('responsive-header') && {
                      'specs.cairo.CollectionPageMinWidth': 'true',
                    }),
                    ...defaultExperiments,
                    ...Object.fromEntries(
                      new URLSearchParams(window.location.search)
                        .get('experiments')
                        ?.split(',')
                        ?.map((e) => {
                          const [spec = '', enabled = 'true'] = e.split(':');
                          return [spec, enabled];
                        }) ?? [],
                    ),
                  },
                }
              : options.experiments,
        }),
      createComponentSettings: () => () =>
        new DataCapsule({
          namespace: '',
          scope: 'cairo-test',
          strategy: new AppSettingsStorageStrategy({
            host: 'other',
            httpClient,
          }),
        }),
      errorMonitor,
      errorHandler: new ErrorHandler({
        biLoggerOrFactory: biLoggerFactory,
        createErrorMonitor: (options) =>
          createChildEssentials({ errorMonitor: options }).errorMonitor,
        environment,
        createI18n: (options) => createChildEssentials({ i18n: options }).i18n,
      }).v2,
      useTranslation,
      Trans,
      useExperiments: () => useExperiments({ readOnly: true }),
      httpClient,
      experiments,
      ...overrides,
      user: {
        permissions: [],
        ...overrides?.user,
      },
      environment: {
        ...environment,
        componentId: [environment.artifactId, 'cairo-test-component'].join('.'),
        language: 'en-US',
        ...overrides?.environment,
      },
      environmentBI: {
        artifactId: environment.artifactId,
      },
      getHostContainer: (_: string) => ({
        getExtensions: () =>
          Promise.resolve([
            {
              title: 'Extension',
              componentId: '',
              Extension: (props: any) => <ExtensionWidget {...props} />,
              menuItem: {
                IconComponent: Edit,
                structuredAction: () => alert('action'),
              },
            },
          ]),
      }),
    }),
  );

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