import { CustomField, CustomFieldType } from '@wix/bex-core';
import {
  Text,
  TextProps,
  Layout,
  Cell,
  Box,
  Heading,
  TextButton,
} from '@wix/design-system';
import React from 'react';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import { observer } from 'mobx-react-lite';
import { FileCardList } from '../FileCard/FileCardList';
import { getDateWithoutTimezone } from '../../utils/datesUtil';

interface CustomFieldsViewWidgetSectionProps {
  customFields: CustomField[];
  fieldValues: Record<string, any>;
  namespace: string;
  title?: string;
}

const _CustomFieldsViewWidgetSection = ({
  customFields,
  fieldValues,
  namespace,
  title,
}: CustomFieldsViewWidgetSectionProps) => {
  const container = useWixPatternsContainer();
  const { translate: t, dateFormatters } = container;

  const valueWrapper = (value: any, props: TextProps) => {
    if (typeof value === 'string' && !/\s/.test(value)) {
      // if there are no space symbols we apply ellipsis (e.g. for links, emails, etc.)
      return (
        <Text {...props} overflowWrap="break-word">
          {value}
        </Text>
      );
    }

    if (typeof value !== 'string' && React.isValidElement(value)) {
      return value;
    }
    return <Text {...props}>{value}</Text>;
  };

  const getViewValue = (
    value: any,
    type: CustomFieldType,
    valueDataHook: string,
  ) => {
    const textProps: TextProps = {
      dataHook: valueDataHook,
      size: 'small',
      secondary: true,
    };

    // It is relevant only to app sections. User fields that are null/undefined will be filtered before and won't be displayed
    if (value === undefined || value === null) {
      return valueWrapper('-', textProps);
    }

    let newValue = value;

    switch (type) {
      case 'dropdown': {
        newValue = value;
        break;
      }
      case 'multiSelect': {
        newValue = value.join(', ');
        break;
      }
      case 'files': {
        const files = Array.isArray(value) ? value : [value];
        return <FileCardList files={files} showDownloadCTA showDetails />;
      }
      case 'date':
        newValue = dateFormatters.medium.format(getDateWithoutTimezone(value));
        break;
      case 'dateTime':
        newValue = dateFormatters.mediumTime.format(new Date(value));
        break;
      case 'checkbox':
        newValue = value
          ? t('cairo.customFields.booleanValue.true')
          : t('cairo.customFields.booleanValue.false');
        break;
      case 'url':
        newValue = (
          <TextButton
            as="a"
            rel="noopener"
            target="_blank"
            size="small"
            href={value}
            ellipsis
            dataHook={valueDataHook}
          >
            {value}
          </TextButton>
        );
        break;
      default:
        break;
    }
    return valueWrapper(newValue, textProps);
  };

  return (
    <Box
      width="100%"
      direction="vertical"
      dataHook={`custom-field-section-${namespace}`}
    >
      <Layout gap="SP3" dataHook={`custom-field-section-${namespace}`}>
        {title && (
          <Cell span={12}>
            <Heading
              size="tiny"
              ellipsis
              dataHook={`custom-field-section-title-${namespace}`}
            >
              {title}
            </Heading>
          </Cell>
        )}
        <Cell span={12}>
          <Box
            display="grid"
            rowGap="18PX"
            columnGap="24PX"
            gridTemplateColumns="repeat(auto-fill, minmax(248px, 1fr))"
          >
            {customFields.map((field) => (
              <Box
                key={field.id}
                flexGrow={1}
                flexShrink={1}
                flexBasis={0}
                minWidth="248px"
              >
                <CustomFieldCell
                  key={field.id}
                  field={field}
                  value={getViewValue(
                    fieldValues[field.id],
                    field.type,
                    `custom-field-value-${namespace}-${field.id}`,
                  )}
                  labelDataHook={`custom-field-label-${namespace}-${field.id}`}
                />
              </Box>
            ))}
          </Box>
        </Cell>
      </Layout>
    </Box>
  );
};

export const CustomFieldsViewWidgetSection = observer(
  _CustomFieldsViewWidgetSection,
);

const CustomFieldCell = ({
  field,
  value,
  labelDataHook,
}: {
  field: CustomField;
  value: JSX.Element;
  labelDataHook: string;
}) => {
  return (
    <Cell key={field.id}>
      <Box direction="vertical" gap="SP1">
        <Text weight="normal" size="small" ellipsis dataHook={labelDataHook}>
          {field.label || field.id}:
        </Text>
        {value}
      </Box>
    </Cell>
  );
};
