import {
  Connector,
  CircleSubject,
  Annotation,
  HtmlLabel,
} from "@visx/annotation";
import { Group } from "@visx/group";
import { LinePath } from "@visx/shape";
import React, { useState } from "react";

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

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

interface TimelineProps {
  data: TimelineData[];
  /** Width of the entire timeline, in pixels. */
  width: number;
  /** Height of the entire timeline, in pixels. */
  height: number;
  /** Padding top and bottom, in pixels. */
  padding: number;
  /** Location of timeline width-wise, in pixels. Default is width / 2. */
  timelinePosition?: number;
  /** Distance between consecutive nodes on timeline, in pixels. Default is evenly spaced. padding is not calculated if user specifies this value. */
  nodeGap?: number;
  /** Whether the time is transformed to uppercase */
  isTimeUppercase?: boolean;
  /** Offset between the line and the time label, in pixels (negative for left offset, positive for right offset). */
  timeXOffset?: number;
  /** Width of time label, in pixels. */
  timeWidth?: number;
  /** Offset between the line and the text label, in pixels (negative for left offset, positive for right offset). */
  textXOffset?: number;
  /** Width of text label, in pixels. */
  textWidth?: number;
  /** Height of text label, in pixels. */
  textHeight?: number;
  className?: string;
}

export default function Timeline({
  data,
  width,
  height,
  padding = 20,
  timelinePosition = width / 2,
  nodeGap = data.length > 1
    ? (height - 2 * padding) / (data.length - 1)
    : height - 2 * padding,
  isTimeUppercase = true,
  timeXOffset = -30,
  timeWidth = 100,
  textXOffset = 30,
  textWidth = 100,
  textHeight = 100,
  className,
}: TimelineProps) {
  const dataWithPositions = data.map((data, i) => ({
    x: timelinePosition,
    y: i * nodeGap + padding,
    time: isTimeUppercase ? data.time.toUpperCase() : data.time,
    text: data.text,
  }));

  return (
    <svg className={className} width={width} height={height}>
      <LinePath
        data={dataWithPositions.map((data) => [data.x, data.y])}
        stroke="#fff"
        strokeWidth={10}
      />
      {dataWithPositions.map((data, i) => (
        <TimelineAnnotation
          positionData={data}
          timeXOffset={timeXOffset}
          timeWidth={timeWidth}
          textXOffset={textXOffset}
          textWidth={textWidth}
          textHeight={textHeight}
          key={`${data.time}${i}`}
        />
      ))}
    </svg>
  );
}

interface TimelineAnnotationProps {
  positionData: {
    x: number;
    y: number;
    time: string;
    text: string;
  };
  timeXOffset: number;
  timeWidth: number;
  textXOffset: number;
  textWidth: number;
  textHeight: number;
}

function TimelineAnnotation({
  positionData,
  timeXOffset,
  timeWidth,
  textXOffset,
  textWidth,
  textHeight,
}: TimelineAnnotationProps) {
  const [hover, setHover] = useState(false);

  function handleMouseEnter() {
    setHover(true);
  }

  function handleMouseLeave() {
    setHover(false);
  }
  console.log(hover);
  return (
    <Group>
      <Annotation x={positionData.x} y={positionData.y} dx={timeXOffset} dy={0}>
        <Connector />
        <HtmlLabel showAnchorLine={false} verticalAnchor="start">
          <h1
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
            className={`${styles.timebox} ${hover ? styles.timeboxHover : ""}`}
            style={{ width: timeWidth }}
          >
            {positionData.time}
          </h1>
        </HtmlLabel>
      </Annotation>
      <Annotation x={positionData.x} y={positionData.y} dx={textXOffset} dy={0}>
        <Connector />
        <CircleSubject
          onMouseEnter={handleMouseEnter}
          onMouseLeave={handleMouseLeave}
          radius={10}
          fill="#000"
        />
        <CircleSubject radius={4} fill="red" />
        <HtmlLabel showAnchorLine={false} verticalAnchor="start">
          <div
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
            className={styles.textbox}
            style={{ width: textWidth, height: textHeight }}
          >
            <p
              className={styles.textboxText}
              style={{ maxHeight: textHeight - 10 }}
            >
              {positionData.text}
            </p>
          </div>
        </HtmlLabel>
      </Annotation>
    </Group>
  );
}
