import { keyframes } from '@emotion/react';
import styled from '@emotion/styled';
import { useMemo } from 'react';
import SineCycle from './SineCycle';

const Wrapper = styled.div``;
const fadeUp = keyframes`
  0% {
    transform: translateY(5px);
    opacity: 0;
  }
  100% {
    transform: translateY(0px);
    opacity: 1;
  }
`;
const LinePlaceholder = styled.div`
  height: 17px;
`;
const Line = styled.div<{ done: boolean; color?: string }>`
  display: flex;
  justify-content: space-between;
  position: relative;
  align-items: flex-end;
  font-family: Architekt;
  font-size: 14px;
  height: 17px;
  opacity: ${({ done }) => (done ? 0.5 : 1)};
  transform: translateY(0px);
  color: ${({ color }) => (color ? color : '#fff')};
  animation: ${({ done }) => (done ? 'none' : fadeUp)} 0.5s ease;
`;
const LineMain = styled.div``;
const LineSuffix = styled.div`
  canvas {
    margin-bottom: -4px;
  }
`;

export type LoadingLine = { text: string; progress: number };
const LoadingTerminal = ({
  title,
  lines,
  maxLines,
  done,
  color,
}: {
  title?: string;
  lines: LoadingLine[];
  maxLines: number;
  done: boolean;
  color?: string;
}) => {
  const paddedLines = useMemo(() => {
    const result = [...lines];
    for (let i = result.length; i < maxLines + (!!title ? 2 : 0); i++) {
      result.push({ text: '', progress: 0 });
    }
    return result;
  }, [lines, maxLines, title]);

  return (
    <Wrapper>
      {title && (
        <>
          <Line color={color} done>
            {title}
          </Line>
          <Line done />
        </>
      )}
      {paddedLines.map((line, index) => {
        if (!line.text) return <LinePlaceholder key={index} />;
        const isInProgress = !done && line.progress < 1;
        const lineText = `${line.text}${isInProgress ? '...' : ''}`;
        const progressText = isInProgress
          ? line.progress > 0
            ? `[ ${(line.progress * 100).toFixed(0)}% ]`
            : ''
          : '[ Done ]';
        return (
          <Line key={index} done={!isInProgress} color={color}>
            <LineMain>{lineText}</LineMain>
            {line.text && (
              <LineSuffix>
                <span style={{ display: 'contents' }}>
                  {isInProgress && <SineCycle height={18} width={22} speed={3} color={color} />}
                </span>
                <span>{progressText}</span>
              </LineSuffix>
            )}
          </Line>
        );
      })}
    </Wrapper>
  );
};

export default LoadingTerminal;
