import { Box, Text, UseInput } from "./Ink";
import React, { useState } from "react";

type DateInputProps = {
  onValidation: (value: Date) => void;

  useInput: UseInput;
};

const daysInMonth = (year: number, month: number) =>
  new Date(year, month, 0).getDate();

export const DateInput = ({ onValidation, useInput }: DateInputProps) => {
  const [day, setDay] = useState(new Date().getDate());
  const [month, setMonth] = useState(new Date().getMonth());
  const [year, setYear] = useState(new Date().getFullYear());

  const [hoverIndex, setHoverIndex] = useState(0);

  useInput((input, key) => {
    let newYear = year;
    let newMonth = month;
    let newDay = day;

    if (key.return) {
      onValidation(new Date(year, month - 1, day));
    } else if (key.leftArrow) {
      setHoverIndex(Math.max(0, hoverIndex - 1));
    } else if (key.rightArrow) {
      setHoverIndex(Math.min(7, hoverIndex + 1));
    } else if (key.upArrow) {
      switch (hoverIndex) {
        case 0:
          newYear = year + 1000;
          break;
        case 1:
          newYear = year + 100;
          break;
        case 2:
          newYear = year + 10;
          break;
        case 3:
          newYear = year + 1;
          break;
        case 4:
          newMonth = month + 10;
          break;
        case 5:
          newMonth = month + 1;
          break;
        case 6:
          newDay = day + 10;
          break;
        case 7:
          newDay = day + 1;
          break;
      }
    } else if (key.downArrow) {
      switch (hoverIndex) {
        case 0:
          newYear = year - 1000;
          break;
        case 1:
          newYear = year - 100;
          break;
        case 2:
          newYear = year - 10;
          break;
        case 3:
          newYear = year - 1;
          break;
        case 4:
          newMonth = month - 10;
          break;
        case 5:
          newMonth = month - 1;
          break;
        case 6:
          newDay = day - 10;
          break;
        case 7:
          newDay = day - 1;
          break;
      }
    } else {
      const inputAsNumber = Number(input);
      if (isNaN(inputAsNumber)) {
        return;
      }

      switch (hoverIndex) {
        case 0:
        case 1:
        case 2:
        case 3:
          newYear = Number(
            year
              .toString()
              .padStart(4, "0")
              .split("")
              .map((digit, index) => (index === hoverIndex ? input : digit))
              .join(""),
          );
          break;
        case 4:
        case 5:
          newMonth = Number(
            month
              .toString()
              .padStart(2, "0")
              .split("")
              .map((digit, index) => (index === hoverIndex - 4 ? input : digit))
              .join(""),
          );
          break;
        case 6:
        case 7:
          newDay = Number(
            day
              .toString()
              .padStart(2, "0")
              .split("")
              .map((digit, index) => (index === hoverIndex - 6 ? input : digit))
              .join(""),
          );
          break;
      }
    }

    const boundYear = Math.min(9999, Math.max(0, newYear));
    const boundMonth = Math.min(12, Math.max(1, newMonth));
    const boundDay = Math.min(newDay, daysInMonth(boundYear, boundMonth));
    setYear(boundYear);
    setMonth(boundMonth);
    setDay(boundDay);
  });

  return (
    <Box>
      {year
        .toString()
        .padStart(4, "0")
        .split("")
        .map((digit, index) => (
          <Text
            key={`year-${index}`}
            backgroundColor={index === hoverIndex ? "white" : undefined}
            color={index === hoverIndex ? "black" : undefined}
          >
            {digit}
          </Text>
        ))}
      <Text>-</Text>
      {month
        .toString()
        .padStart(2, "0")
        .split("")
        .map((digit, index) => (
          <Text
            key={`month-${index}`}
            backgroundColor={index + 4 === hoverIndex ? "white" : undefined}
            color={index + 4 === hoverIndex ? "black" : undefined}
          >
            {digit}
          </Text>
        ))}
      <Text>-</Text>
      {day
        .toString()
        .padStart(2, "0")
        .split("")
        .map((digit, index) => (
          <Text
            key={`day-${index}`}
            backgroundColor={index + 6 === hoverIndex ? "white" : undefined}
            color={index + 6 === hoverIndex ? "black" : undefined}
          >
            {digit}
          </Text>
        ))}
    </Box>
  );
};
