import React from "react";

import styles from "./Timeline.module.css";

interface TimelineData {
  time: string;
  text: string;
}

interface TimelineProps {
  data: TimelineData[];
  /** Whether the time is transformed to uppercase. */
  isTimeUppercase?: boolean;
  /** Width of the middle timeline line, in pixels */
  lineWidth?: number;
  /** Width of the outer circles on the timeline, in pixels. */
  outerCircleWidth?: number;
  /** Width of the inner circles on the timeline, in pixels. */
  innerCircleWidth?: number;
  /** Width of time label, in pixels. */
  timeWidth?: number;
  /** Width of text label, in pixels. */
  textWidth?: number;
  /** Distance between the time label AND the text label to middle line, in pixels. */
  gap?: number;
  className?: string;
}

export function Timeline({
  data,
  isTimeUppercase = true,
  lineWidth = 5,
  outerCircleWidth = 30,
  innerCircleWidth = 15,
  timeWidth = 200,
  textWidth = 300,
  gap = 50,
  className,
}: TimelineProps) {
  const largerMiddleElement =
    outerCircleWidth > lineWidth ? outerCircleWidth : lineWidth;
  const width = timeWidth + gap + largerMiddleElement + gap + textWidth;
  if (innerCircleWidth > outerCircleWidth) {
    throw new Error(
      `<Timeline /> - innerCircleWidth (${innerCircleWidth}) is larger than outerCircleWidth (${outerCircleWidth})`
    );
  }

  return (
    <div
      className={
        className ? `${className} ${styles.wrapper}` : `${styles.wrapper}`
      }
      style={{ width: width }}
    >
      <div
        className={styles.line}
        style={{
          width: lineWidth,
          left: width / 2 - lineWidth / 2,
        }}
      />
      <div className={styles.timelineSections}>
        {data.map((datum) => (
          <TimelineSection
            key={datum.time}
            datum={datum}
            width={width}
            isTimeUppercase={isTimeUppercase}
            outerCircleWidth={outerCircleWidth}
            innerCircleWidth={innerCircleWidth}
            timeWidth={timeWidth}
            textWidth={textWidth}
            gap={gap}
          />
        ))}
      </div>
    </div>
  );
}

interface TimelineSectionProps {
  datum: TimelineData;
  width: number;
  isTimeUppercase: boolean;
  outerCircleWidth: number;
  innerCircleWidth: number;
  timeWidth: number;
  textWidth: number;
  gap: number;
}

function TimelineSection({
  datum,
  width,
  isTimeUppercase,
  outerCircleWidth,
  innerCircleWidth,
  timeWidth,
  textWidth,
  gap,
}: TimelineSectionProps) {
  return (
    <div className={styles.timelineSection} style={{ gap: gap }}>
      <div
        className={styles.time}
        style={{
          width: timeWidth,
          marginLeft: (width - 2 * gap - outerCircleWidth) / 2 - timeWidth,
        }}
      >
        {isTimeUppercase ? datum.time.toUpperCase() : datum.time}
      </div>
      <div
        className={styles.circle}
        style={{
          width: outerCircleWidth,
          height: outerCircleWidth,
          borderRadius: outerCircleWidth,
        }}
      >
        <div
          className={styles.innerCircle}
          style={{
            width: innerCircleWidth,
            height: innerCircleWidth,
            borderRadius: innerCircleWidth,
          }}
        />
      </div>
      <div
        className={styles.text}
        style={{
          width: textWidth,
          marginRight: (width - 2 * gap - outerCircleWidth) / 2 - textWidth,
        }}
      >
        {datum.text}
      </div>
    </div>
  );
}
