import React from 'react';
import { Card as BCard, CardProps as BootstrapCardProps } from 'react-bootstrap';
import Badge from '@atoms/Badge/Badge';
import Button from '@atoms/Button/Button';
import { Icon } from '@foundations/Icons/Icons';
import Slide from '@organisms/Slide/Slide';
import Flip from '@organisms/Flip/Flip';
import "./Datacards.scss"

type bgs = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light';

interface DataCardProps extends Omit<BootstrapCardProps, 'title'> {
  header?: any;
  image?: React.ReactNode;
  title?: React.ReactNode;
  href?: string;
  body?: any;
  children?: React.ReactNode;
  footer?: any;
  //tags and buttons are arrays containing all needed props for the tags and buttons
  tags?: {
    name: string,
    bg: bgs,
    icon?: string
  }[];
  inlinetags?: {
    name: string,
    bg: bgs,
    icon?: string
  }[];
  sourcetags?: {
    name: string,
    bg: bgs,
    icon?: string
  }[];
  buttons?: any;
  variant?: 'basic' | 'flip' | 'slide';
  imagevariant?: 'top' | 'bottom';
  icons?: any;
}

const Datacard = (props: DataCardProps) => {
  const {
    title = undefined,
    href = undefined,
    body = undefined,
    children = undefined,
    image = undefined,
    footer = undefined,
    tags = [],
    sourcetags = [],
    inlinetags = [],
    buttons = [],
    variant = 'basic',
    imagevariant = undefined,
    icons = [],
    ...otherProps
  } = props;

  // extract className from otherProps
  const { className, ...remainProps } = otherProps;

  //render tags as small buttons to later embed in card
  let tagList: React.JSX.Element[] | null = null;
  if (tags) {
    tagList = tags.map((tag: any, index: number) => {
      return (
        //access the tag name and color from the array
        <Badge key={`${tag.name}-${index}`}
          bg={tag.bg}
          subtle
          style={ (variant == 'slide' || variant == 'flip') ? { whiteSpace: 'normal' } : {} }
        >
          {tag.icon && <Icon name={tag.icon} color={tag.bg + "-emphasis"} />}
          {tag.name}
        </Badge>
      );
    });
  }

  //render tags as small buttons to later embed in card
  let inlineTagList: React.JSX.Element[] | null = null;
  if (inlinetags) {
    inlineTagList = inlinetags.map((tag: any, index: number) => {
      return (
        //access the tag name and color from the array
        <Badge key={`${tag.name}-${index}`} bg={tag.bg} subtle>
          {tag.icon && <Icon name={tag.icon} color={tag.bg + "-emphasis"} className="me-1" />}
          {tag.name}
        </Badge>
      );
    });
  }


  let sourceTagList: React.JSX.Element[] | null = null;
  if (sourcetags) {
    sourceTagList = sourcetags.map((tag: any, index: number) => {
      return (
        //access the tag name and color from the array
        <Badge key={`${tag.name}-${index}`} bg={tag.bg} subtle>
          {tag.icon && <Icon name={tag.icon} color={tag.bg + "-emphasis"} className="me-1" />}
          {tag.name}
        </Badge>
      );
    });
  }

  //render links as icon buttons to later embed in card
  let buttonList: React.JSX.Element[] | null = null;
  if (buttons) {
    buttonList = buttons.map((button: any, index: number) => {
      return (
        <Button key={`${button.name}-${index}`} iconName={button.iconName || ""} variant={button.variant}>{button.name}</Button>
      );
    });
  }

  //render icons to later embed in card
  let iconList: React.JSX.Element[] | null = null;
  const iconColor = variant == 'slide' || variant == 'flip' ? 'light' : 'muted';
  if (icons) {
    iconList = icons.map((icon: any, i: number) => {
      const iconClassName = i === icons.length - 1 ? 'fs-2' : 'me-3 fs-2';
      return <Icon key={`${icon}-${i}`} name={icon} color={iconColor} className={iconClassName} />
    });
  };

  let thumbnail: React.ReactNode | null = null;
  if (image) {
    if (typeof image === 'string') {
      thumbnail = <img
        src={image}
        alt={`Cover of '${title}'`}
        className="img-fluid rounded-top"
      />
    } else {
      thumbnail = image;
    }
  } else {
    thumbnail = (
      <div className="align-items-center justify-content-center" style={{ display: "flex", width: "100%", aspectRatio: "2/3" }}>
        {icons.map((icon: any, i: number) => (
          <Icon key={`${icon}-${i}`} name={icon} color={"muted"} className={"me-3 fs-2"} />
        ))}
      </div>
    )
  }

  const FrontCard =
    <BCard className="card-front" border="primary" {...remainProps}>
      {thumbnail}
      {title && 
        <BCard.Header>{title}</BCard.Header>
      }
    </BCard>

  const BackCard =
    <BCard className="card-back border border-0 text-bg-primary" text="white" {...remainProps}>
      <BCard.Header className="border-0">
        {href ? <a href={href} className='link-light text-decoration-none stretched-link'>{title}</a> : title}
      </BCard.Header>
      <BCard.Body className="pt-0">
        <div className="d-flex gap-2">{inlineTagList}{sourceTagList}</div>
        {tags && <div className="d-flex flex-wrap gap-2 mt-2">{tagList}</div>}
        {buttons && <div>{buttonList}</div>}
        {body && <BCard.Text className='pt-3 small text-light fw-light'>{body}</BCard.Text>}
      </BCard.Body>
      {children}
      <div className='w-100 position-absolute bottom-0 rounded-bottom start-0 d-flex flip-fade p-2 pt-4'>{iconList}</div>
      {footer && <BCard.Footer>{footer}</BCard.Footer>}
    </BCard>

  // Horizontal data cards
  switch (variant) {
    case 'slide':
      return (
        <Slide className={className}>
          {FrontCard}
          {BackCard}
        </Slide>
      )
    case 'flip':
      return (
        <Flip className={className || ''}>
          {FrontCard}
          {BackCard}
        </Flip>
      )
    default:
      return (
        <BCard className={`${className || ''} anim-glow`} {...remainProps}>
          <BCard.Body>
            <BCard.Title>
              {href ? <a href={href} className="custom-link text-decoration-none stretched-link">{title}</a> : title}
              {inlineTagList && <div className="d-inline-block small ms-2">{inlineTagList}</div>}
            </BCard.Title>
            <div className="d-flex">{tags && <div className="d-flex flex-wrap gap-2 mb-2">{tagList}</div>}{sourcetags && <div className='ms-auto'>{sourceTagList}</div>}</div>
            {body && <BCard.Text className="fw-light mb-2">{body}</BCard.Text>}
            {buttons && <div>{buttonList}</div>}
            <div className='w-100 d-flex'>{iconList}</div>
          </BCard.Body>
          {children}
          {footer && <BCard.Footer className="">{footer}</BCard.Footer>}
        </BCard>
      )
  }
}

export default Datacard;
export { Datacard, DataCardProps };