import React, { Suspense } from 'react';
import { Box, Text, TextButton } from '@wix/design-system';
import { Confirm, Minus } from '@wix/wix-ui-icons-common';
import type { PatternsFieldType } from '@wix/bex-core';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import { observer } from 'mobx-react-lite';
import type { CellAddressViewProps } from '@wix/patterns-fields';
import type { WixCodeGalleryItem } from '@wix/patterns-fields/auto-field-types';
import { getDateWithoutTimezone } from '../../utils/datesUtil';

// Cell renderers live in @wix/patterns-fields, which statically pulls the
// rich-text editor (Ricos/draft-js) and media SDKs. Importing them eagerly put
// that weight into every bundle that renders a source column (DataExtension,
// CMS, the tables). Loading them lazily moves it into an async chunk fetched
// only when a cell of one of these types first renders. The light types in the
// switch below stay inline (WDS only) and ship nothing extra.
function lazyCell<P extends object>(
  pick: (m: typeof import('@wix/patterns-fields')) => React.ComponentType<P>,
) {
  const C = React.lazy(async () => ({
    default: pick(await import('@wix/patterns-fields')),
  }));
  return (props: P) => (
    <Suspense fallback={null}>
      <C {...props} />
    </Suspense>
  );
}

const CellAddressView = lazyCell((m) => m.CellAddressView);
const CellAudioView = lazyCell((m) => m.CellAudioView);
const CellColorView = lazyCell((m) => m.CellColorView);
const CellDocumentView = lazyCell((m) => m.CellDocumentView);
const CellMediaGalleryView = lazyCell((m) => m.CellMediaGalleryView);
const CellMultiDocumentView = lazyCell((m) => m.CellMultiDocumentView);
const CellRichContentView = lazyCell((m) => m.CellRichContentView);
const CellRichTextView = lazyCell((m) => m.CellRichTextView);
const ImageView = lazyCell((m) => m.ImageView);
const JsonView = lazyCell((m) => m.JsonView);

export interface FieldCellProps {
  value?: unknown;
  type: PatternsFieldType;
  /** Stable id for cells that render WDS Tags (document, multi-document). */
  fieldId?: string;
}

function _FieldCell(props: FieldCellProps) {
  const { dateFormatters } = useWixPatternsContainer();
  switch (props.type) {
    case 'LONG_TEXT':
      return (
        <Text size="small" ellipsis maxLines={3}>
          {props.value as React.ReactNode}
        </Text>
      );
    case 'DATE':
      return (
        <Text size="small" ellipsis maxLines={1}>
          {props.value
            ? dateFormatters.medium.format(
                getDateWithoutTimezone(props.value as string),
              )
            : null}
        </Text>
      );
    case 'DATETIME':
      return (
        <Text size="small" ellipsis maxLines={1}>
          {props.value
            ? dateFormatters.mediumTime.format(new Date(props.value as string))
            : null}
        </Text>
      );
    case 'BOOLEAN':
      return (
        <Box
          align="center"
          verticalAlign="middle"
          color={props.value ? 'G10' : 'D10'}
        >
          {props.value ? <Confirm /> : <Minus />}
        </Box>
      );
    case 'URL':
      return (
        <TextButton
          as="a"
          rel="noopener"
          target="_blank"
          href={props.value as string}
          ellipsis
        >
          {props.value as React.ReactNode}
        </TextButton>
      );
    case 'IMAGE':
      return (
        <ImageView value={props.value as string | null} dataHook="image-view" />
      );
    case 'VIDEO':
      return (
        <ImageView value={props.value as string | null} dataHook="video-view" />
      );
    case 'AUDIO':
      return (
        <CellAudioView
          value={props.value as string | null}
          dataHook="audio-view"
        />
      );
    case 'MEDIA_GALLERY':
      return (
        <CellMediaGalleryView
          data={props.value as WixCodeGalleryItem[] | null}
          dataHook="media-gallery-view"
        />
      );
    case 'DOCUMENT':
      return (
        <CellDocumentView
          value={props.value as string | null | undefined}
          dataHook="document-view"
          fieldId={props.fieldId ?? ''}
        />
      );
    case 'MULTI_DOCUMENT':
      return (
        <CellMultiDocumentView
          value={props.value as string[] | null | undefined}
          dataHook="multi-document-view"
          fieldId={props.fieldId ?? ''}
        />
      );
    case 'ARRAY':
      return (
        <Text size="small" ellipsis maxLines={1}>
          {(props.value as unknown[] | undefined)?.join?.(', ')}
        </Text>
      );
    case 'ADDRESS':
      return (
        <CellAddressView data={props.value as CellAddressViewProps['data']} />
      );
    case 'RICH_TEXT':
      return <CellRichTextView value={props.value as string | null} />;
    case 'RICH_CONTENT':
      return <CellRichContentView value={props.value} />;
    case 'COLOR':
      return <CellColorView value={props.value as string | undefined} />;
    case 'OBJECT':
      return <JsonView data={props.value} />;
    default:
      return (
        <Text size="small" ellipsis maxLines={1}>
          {props.value as React.ReactNode}
        </Text>
      );
  }
}

export const FieldCell = observer(_FieldCell);
