import {
  Box,
  CardGalleryItem,
  CardGalleryItemProps,
  Image,
  ImageProps,
} from '@wix/design-system';
import React, { cloneElement, isValidElement, ReactNode } from 'react';
import { FiltersMap, KeyedItem } from '@wix/bex-core';
import { GridBaseState, ItemActionsState } from '../../state';
import { observer } from 'mobx-react-lite';
import { useGridItemActions } from './useGridItemActions';
import { MessageActionModal } from '../ActionModal';
import { ActionCell } from '../ActionCell';
import type { Preset } from './Grid.types';
import { useToolbarCollectionContext } from '../ToolbarCollectionContext';

export interface GridCardItemProps<T, F extends FiltersMap> {
  children?: ReactNode;
  state: GridBaseState<T, F>;
  keyedItem: KeyedItem<T>;
  index: number;
  rowIndex?: number;
  columnIndex?: number;
  actionCell?: ActionCell<T, F>;
  preset?: Preset;
  renderItem?: (item: T, index: number) => Partial<CardGalleryItemProps>;
  draggable?: boolean;
  droppable?: boolean;
  dragging?: boolean;
  dragHandleProps?: CardGalleryItemProps['dragHandleProps'];
  domRef?: (node: HTMLElement | null) => void;
}

function _GridCardItem<T, F extends FiltersMap>(
  props: GridCardItemProps<T, F>,
) {
  const {
    state,
    keyedItem,
    index,
    actionCell,
    preset,
    renderItem,
    draggable,
    droppable,
    dragging,
    dragHandleProps,
  } = props;
  const toolbarState = useToolbarCollectionContext();

  const [itemActionsState] = React.useState(
    () =>
      new ItemActionsState({
        collection: state.collection,
        keyedItem,
        fade: 'idle',
        reportBi: toolbarState.reportBi,
      }),
  );

  const { item } = keyedItem;

  const {
    collection,
    calcGridProps: { cardFooterSize },
  } = state;
  const { itemName } = collection;

  const renderProps = renderItem?.(item, index) ?? {};

  const { backgroundImageNode } = renderProps;
  const imagePlacement = renderProps.imagePlacement ?? state.imagePlacement;

  const { primaryAction, settingsMenu } = useGridItemActions({
    actionCell,
    item,
    index,
    gridState: state,
    keyedItem,
    itemActionsState,
    imagePlacement,
  });

  const textProps = (() => {
    if (preset === 'empty') {
      return {
        title: undefined,
        subtitle: undefined,
        footer: undefined,
      };
    }

    return {
      title: renderProps?.title || itemName(item) || <>&#8203;</>,
      subtitle:
        preset === 'full' || preset === 'footer'
          ? renderProps?.subtitle || <>&#8203;</>
          : undefined,
      footer:
        preset === 'footer' ? (
          <Box height="42px" direction="vertical">
            {renderProps?.footer}
          </Box>
        ) : undefined,
    };
  })();

  const primaryActionProps = React.useMemo(() => {
    const merged = {
      ...(primaryAction ?? renderProps?.primaryActionProps),
    };

    return Object.keys(merged).length > 0 ? merged : undefined;
  }, [primaryAction, renderProps?.primaryActionProps]);

  return (
    <>
      <CardGalleryItem
        tabIndex={0}
        dataHook="grid-card-item"
        {...renderProps}
        skin="outlined"
        size={cardFooterSize}
        imagePlacement={imagePlacement}
        backgroundImageNode={
          backgroundImageNode == null ? (
            <Image borderRadius={0} height="100%" />
          ) : isValidElement<ImageProps>(backgroundImageNode) ? (
            cloneElement(backgroundImageNode, {
              style: {
                borderRadius: 0,
              },
            })
          ) : (
            backgroundImageNode
          )
        }
        {...textProps}
        primaryActionProps={primaryActionProps}
        settingsMenu={settingsMenu ?? renderProps.settingsMenu}
        draggable={draggable}
        dragging={dragging}
        droppable={droppable}
        dragHandleProps={dragHandleProps}
      />
      <MessageActionModal
        state={itemActionsState.confirmModal}
        {...itemActionsState.confirmModal.value}
      />
    </>
  );
}

export const GridCardItem = observer(_GridCardItem);
