import TableStatusText from './TableStatusText';
import StatusIcon from '../statusIcon';
import { Flag } from '@wise/art';
import React, { ImgHTMLAttributes } from 'react';
import { clsx } from 'clsx';
import Body from '../body';
import Money, { MoneyProps } from '../money';
import AvatarView, { AvatarViewProps } from '../avatarView';

interface TableCellTypeProp {
  type: 'leading' | 'text' | 'currency' | 'status' | 'media';
}

// `Media`, `Leading` and `Status` cell types have 2 text fields: `primaryText` and `secondaryText`
interface TableCellTextProps {
  primaryText?: string;
  secondaryText?: string;
}

// `Leading`, `Text` and `Currency` cells' types can have a status indicator with `error` or `success` values
interface TableCellStatusProp {
  status?: 'error' | 'success';
}

export interface TableCellMedia extends TableCellTypeProp, TableCellTextProps {
  media?: ImgHTMLAttributes<HTMLImageElement>;
}

export interface TableCellLeading
  extends TableCellTypeProp, TableCellTextProps, TableCellStatusProp {
  avatar?: Pick<AvatarViewProps, 'badge' | 'imgSrc' | 'profileName' | 'profileType'> & {
    asset?: AvatarViewProps['children'];
    /** @deprecated Use `"imgSrc" instead. */
    src?: AvatarViewProps['imgSrc'];
  };
}

export interface TableCellText extends TableCellTypeProp, TableCellStatusProp {
  text?: string;
}

export interface TableCellCurrency extends TableCellTypeProp, TableCellStatusProp {
  primaryCurrency?: MoneyProps;
  secondaryCurrency?: MoneyProps;
  flag?: boolean;
}

export interface TableCellStatus extends TableCellTypeProp, TableCellTextProps {
  sentiment?: 'negative' | 'neutral' | 'positive' | 'warning' | 'pending';
}

export interface TableCellType {
  cell?: TableCellLeading & TableCellText & TableCellCurrency & TableCellStatus & TableCellMedia;
  alignment?: 'left' | 'right';
}

// These properties should be exported only on the lib level to prevent visual issues because of incorrect usage.
export interface TableCellProps extends TableCellType {
  className?: string;
  colSpan?: number;
  children?: React.ReactNode;
}

const TableCell = ({ cell, alignment = 'left', className, colSpan, children }: TableCellProps) => {
  const getContentMedia = () => {
    let mediaContent = null;

    if (cell?.type === 'leading' && cell?.avatar) {
      mediaContent = (
        <AvatarView size={40} {...cell.avatar} imgSrc={cell.avatar.imgSrc ?? cell.avatar.src}>
          {cell.avatar.asset}
        </AvatarView>
      );
    }

    if (cell?.type === 'currency' && cell?.primaryCurrency?.currency && cell?.flag !== false) {
      mediaContent = (
        <Flag code={cell?.primaryCurrency?.currency?.toLowerCase()} intrinsicSize={24} />
      );
    }

    if (cell?.type === 'status') {
      mediaContent = <StatusIcon size={24} sentiment={cell?.sentiment ?? 'neutral'} />;
    }

    if (cell?.type === 'media' && cell.media) {
      // eslint-disable-next-line jsx-a11y/alt-text
      mediaContent = <img {...cell.media} />;
    }

    if (mediaContent) {
      return (
        <div
          aria-hidden="true"
          className="np-table-content-media"
          data-testid="np-table-content-media"
        >
          {mediaContent}
        </div>
      );
    }
  };

  const formatCurrencyValue = (currency?: MoneyProps) => {
    if (currency) {
      return <Money amount={currency.amount} currency={currency.currency} alwaysShowDecimals />;
    }

    return '';
  };

  return (
    <td
      className={clsx(
        'np-table-cell',
        cell?.type ? `np-table-cell--${cell?.type}` : '',
        `np-table-cell--${alignment}`,
        className,
      )}
      colSpan={colSpan}
    >
      {cell?.type === 'text' && cell?.text && (
        <TableStatusText text={cell?.text} status={cell?.status} />
      )}
      {cell?.type && ['leading', 'currency', 'status', 'media'].includes(cell?.type) && (
        <div
          className={clsx('np-table-content', {
            'np-table-content--reversed': alignment === 'right',
          })}
          data-testid="np-table-content"
        >
          {getContentMedia()}
          <div className="np-table-content-body">
            {(cell?.primaryCurrency ?? cell?.primaryText) && (
              <TableStatusText
                text={
                  cell?.type === 'currency'
                    ? formatCurrencyValue(cell?.primaryCurrency)
                    : (cell?.primaryText ?? '')
                }
                status={cell?.type !== 'status' ? cell?.status : undefined}
                typography="default-bold"
              />
            )}
            {(cell?.secondaryCurrency ?? cell?.secondaryText) && (
              <Body>
                {cell?.type === 'currency'
                  ? formatCurrencyValue(cell?.secondaryCurrency)
                  : cell?.secondaryText}
              </Body>
            )}
          </div>
        </div>
      )}
      {children}
    </td>
  );
};

export default TableCell;
