import { CrossCircleFill as DontIcon, CheckCircleFill as DoIcon } from '@transferwise/icons';
import { clsx } from 'clsx';
import { ReactNode } from 'react';

import Body from '../body/Body';
import { Typography, CommonProps } from '../common';

type InstructionNode = {
  content: ReactNode;
  ['aria-label']: string;
};

export type InstructionsListProps = CommonProps &
  (
    | {
        dos?: readonly ReactNode[];
        donts?: readonly ReactNode[];
        sort?: 'dosFirst' | 'dontsFirst';
      }
    | {
        dos?: readonly InstructionNode[];
        donts?: readonly InstructionNode[];
        sort?: 'dosFirst' | 'dontsFirst';
      }
  );

const InstructionsList = ({ className, dos, donts, sort = 'dosFirst' }: InstructionsListProps) => {
  const dosInstructions =
    dos?.map((doThis, index) => (
      // eslint-disable-next-line react/no-array-index-key
      <Instruction key={index} item={doThis} type="do" />
    )) ?? null;

  const dontsInstructions =
    donts?.map((dont, index) => (
      // eslint-disable-next-line react/no-array-index-key
      <Instruction key={index} item={dont} type="dont" />
    )) ?? null;

  const orderedInstructions =
    sort === 'dosFirst' ? (
      <>
        {dosInstructions}
        {dontsInstructions}
      </>
    ) : (
      <>
        {dontsInstructions}
        {dosInstructions}
      </>
    );

  return <ul className={clsx('tw-instructions', className)}>{orderedInstructions}</ul>;
};

function Instruction({ item, type }: { item: ReactNode | InstructionNode; type: 'do' | 'dont' }) {
  const isInstructionNode =
    typeof item === 'object' && item !== null && 'content' in item && 'aria-label' in item;
  return (
    <li className="instruction">
      {type === 'do' ? (
        <DoIcon
          size={24}
          className={type}
          title={isInstructionNode ? item['aria-label'] : undefined}
        />
      ) : (
        <DontIcon
          size={24}
          className={type}
          title={isInstructionNode ? item['aria-label'] : undefined}
        />
      )}
      <Body className="text-primary" type={Typography.BODY_LARGE} preserveNewlines>
        {isInstructionNode ? item.content : item}
      </Body>
    </li>
  );
}

export default InstructionsList;
