import { isArray, isString } from 'lodash';
import React, { useState } from 'react';
import { SilkeColor } from '../../silke-theme-provider';
import { SilkeBox } from '../silke-box';
import { SilkeCheckbox } from '../silke-checkbox';
import { SilkeContextMenu } from '../silke-context-menu';
import { SilkeImage, SilkeImageColorBackdrop } from '../silke-image';
import { SilkeOverflowMenu, SilkeOverflowMenuItem } from '../silke-overflow-menu';
import { SilkeTag, SilkeTagProps } from '../silke-tag';
import { SilkeText } from '../silke-text';
import styles from './silke-card.scss';
import { SilkeButton } from '../silke-button';

type SilkeCardProps = {
  title: React.ReactNode;
  subTitle?: React.ReactNode;
  image?: string | React.ReactElement | string[];
  autoFocus?: boolean;
  text?: string;
  customTags?: React.ReactNode;
  menu?: SilkeOverflowMenuItem[];
  colorBackdrop?: boolean | SilkeColor;
  tags?: SilkeTagProps[];
  tagsTop?: SilkeTagProps[];
  link?: string;
  selected?: boolean;

  checked?: boolean;
  onCheck?: (checked: boolean) => void;
  /** Shows info icon in label */
  onMore?: () => void;

  /**
   * Show overflow menu above menu button
   */
  overflowMenuAbove?: boolean;
  // overflowRibbonIcon?: SilkeIcons | React.ReactElement;
  // overflowRibbonTooltip?: string;
} & Omit<React.HTMLAttributes<HTMLDivElement>, 'title' | 'children'>;

const stopPropagation = (e: React.MouseEvent) => {
  e.stopPropagation();
};

export const SilkeCard = React.forwardRef(
  (
    {
      image,
      title,
      subTitle,
      text,
      className,
      link,
      overflowMenuAbove,
      menu,
      tags,
      customTags,
      tagsTop,
      colorBackdrop,
      checked,
      selected,
      onCheck,
      onMore,
      ...rest
    }: SilkeCardProps,
    cardRef,
  ) => {
    const [showContextMenu, setShowContextMenu] = useState(false);

    let cl = styles.card;
    if (className) cl += ' ' + className;
    if (colorBackdrop) cl += ' ' + styles.colorBackdrop;
    if (tags?.length) cl += ' ' + styles.hasTags;
    if (checked) cl += ' ' + styles.checked;
    if (selected) cl += ' ' + styles.selected;

    return (
      <SilkeBox
        tag={link ? 'link' : 'div'}
        to={link}
        ref={cardRef}
        column
        role={link ? 'link' : undefined}
        tabIndex={rest.onClick ? 1 : undefined}
        aria-label={rest.onClick && isString(title) ? title : undefined}
        className={cl}
        onContextMenu={(e: MouseEvent) => {
          e.preventDefault();
          setShowContextMenu(true);
        }}
        {...(rest as any)}
      >
        <SilkeBox className={styles.imageWrapper} overflow="hidden" column bg="surface-1">
          {image &&
            (isArray(image) ? (
              <CardImageFolder images={image} />
            ) : isString(image) ? (
              colorBackdrop === true ? (
                <SilkeImageColorBackdrop
                  src={image}
                  className={styles.backdrop}
                  align="center"
                  flex
                >
                  <SilkeImage
                    className={styles.img + ' ' + styles.shadow}
                    src={image}
                    overflow="hidden"
                  />
                </SilkeImageColorBackdrop>
              ) : isString(colorBackdrop) ? (
                <SilkeBox
                  className={styles.backdrop}
                  align="center"
                  flex
                  bg={colorBackdrop as SilkeColor}
                >
                  <SilkeImage className={styles.img} src={image} overflow="hidden" />
                </SilkeBox>
              ) : (
                <SilkeImage className={styles.img} src={image} />
              )
            ) : (
              image
            ))}

          {onCheck && (
            <SilkeBox
              className={styles.checkbox}
              rounded="tiny"
              onClick={(e: React.MouseEvent) => e.stopPropagation()}
              onMouseDown={(e: React.MouseEvent) => e.stopPropagation()}
            >
              <SilkeCheckbox value={checked} onChange={onCheck} />
            </SilkeBox>
          )}
          {tagsTop && (
            <SilkeBox gap="xxs" className={styles.tagsTop}>
              {tagsTop?.map((tagContent, i) => (
                <SilkeTag key={i} kind="secondary" {...tagContent} />
              ))}
            </SilkeBox>
          )}
          {(tags || customTags) && (
            <SilkeBox gap="xxs" className={styles.tags}>
              {customTags}
              {tags?.map((tagContent, i) => (
                <SilkeTag
                  key={i}
                  kind="secondary"
                  {...tagContent}
                  onClick={tagContent.link ? stopPropagation : tagContent.onClick}
                />
              ))}
            </SilkeBox>
          )}
        </SilkeBox>
        <SilkeBox gap="m" column flex>
          <SilkeBox vAlign="center">
            <SilkeBox
              flex
              column
              gap="xs"
              className={`${styles.cardText} ${styles.overflowHidden}`}
            >
              <SilkeText
                size="base"
                flex
                overflow
                className={styles.title}
                title={typeof title === 'string' ? title : undefined}
              >
                {title}
              </SilkeText>
              {subTitle && (
                <SilkeText size="small" tag="small" color="neutral-70" className={styles.subTitle}>
                  {subTitle}
                </SilkeText>
              )}
            </SilkeBox>
            {onMore && (
              <SilkeButton
                size="s"
                className={styles.overflowMenu}
                icon="tooltip"
                onClick={(e) => {
                  e.stopPropagation();
                  onMore();
                }}
              />
            )}
            {menu && (
              <SilkeOverflowMenu
                tabIndex={-1}
                size="s"
                className={styles.overflowMenu}
                items={menu}
                data-testid="overflow-menu"
                targetOrigin={overflowMenuAbove ? 'bottom-right' : 'top-right'}
                anchorOrigin={overflowMenuAbove ? 'top-right' : 'bottom-right'}
              />
            )}
          </SilkeBox>
          {text && (
            <SilkeText flex className={styles.cardText}>
              {text}
            </SilkeText>
          )}
        </SilkeBox>
        {showContextMenu && menu && (
          <SilkeContextMenu
            items={menu}
            target={cardRef as React.MutableRefObject<HTMLDivElement>}
            onRequestClose={() => setShowContextMenu(false)}
          />
        )}
      </SilkeBox>
    );
  },
);

SilkeCard.displayName = 'SilkeCard';

function CardImageFolder({ images }: { images: string[] }) {
  return (
    <SilkeBox className={styles.folder} vAlign="center" column bg="neutral-5">
      <svg className={styles.folderTab} viewBox="0 0 93 16">
        <path d="M14 0C7 0 0 6 0 16H93L77 3C76 2 73 0 70 0H14Z" />
      </svg>
      <div className={styles.folderGrid}>
        {[0, 1, 2, 3, 4, 5].map((i) => (
          <SilkeBox key={i} rounded="tiny" bg="surface-3" overflow="hidden" column>
            {images[i] && <SilkeImage src={images[i]} />}
          </SilkeBox>
        ))}
      </div>
    </SilkeBox>
  );
}
