import React from "react";
import { useDispatch } from "react-redux";

import { actions } from "@/store";
import InputWrapper from "../input-wrapper/input-wrapper";
import InputItem from "../input-item/input-item";
import Button from "../button/button";
import useSteps from "../../../hooks/palmistry/use-steps";
import { useSession } from "@/hooks/session/useSession";
import { ESourceAuthorization } from "@/api/resources/User";
import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales";

enum Field {
  year = "year",
  month = "month",
  day = "day",
}

const dateDivider = "-";

export default function StepBirthdate() {
  const { translate } = useTranslations(ELocalesPlacement.PalmistryV0);
  const steps = useSteps();
  const dispatch = useDispatch();
  const { updateSession } = useSession();

  const [year, setYear] = React.useState("");
  const [month, setMonth] = React.useState("");
  const [day, setDay] = React.useState("");
  const [fieldsWithErrors, setFieldsWithErrors] = React.useState(
    new Set() as Set<Field>
  );
  const [errorIsVisible, setErrorIsVisible] = React.useState(false);

  React.useEffect(() => {
    const [storedYear, storedMonth, storedDay] =
      steps.storedValue.split(dateDivider);

    if (storedYear) setYear(storedYear);
    if (storedMonth) setMonth(storedMonth);
    if (storedDay) setDay(storedDay);
  }, [steps.storedValue]);

  const onChangeYear = (value: string) => {
    const yearNumber = Number(value);

    if (Number.isNaN(yearNumber) || yearNumber > new Date().getFullYear()) {
      return;
    }

    setFieldsWithErrors((prevValue) => {
      const newValue = new Set(prevValue);

      if (value !== "" && yearNumber < 1924) {
        newValue.add(Field.year);
      } else {
        newValue.delete(Field.year);
      }

      return newValue;
    });

    setYear(value);
  };

  const onChangeMonth = (value: string) => {
    const monthNumber = Number(
      Number(value).toString().replace(/\D/g, "").slice(0, 2)
    );

    if (Number.isNaN(monthNumber) || monthNumber > 12) {
      return;
    }

    setFieldsWithErrors((prevValue) => {
      const newValue = new Set(prevValue);

      if (value !== "" && (monthNumber < 1 || monthNumber > 12)) {
        newValue.add(Field.year);
      } else {
        newValue.delete(Field.year);
      }

      return newValue;
    });

    if (monthNumber < 10) {
      setMonth(`0${monthNumber}`);
    } else {
      setMonth(`${monthNumber}`);
    }
  };

  const onChangeDay = (value: string) => {
    const dayNumber = Number(value);
    const monthNumber = Number(month);

    setFieldsWithErrors((prevValue) => {
      const newValue = new Set(prevValue);

      if (value !== "" && dayNumber === 0) {
        newValue.add(Field.day);
      } else {
        newValue.delete(Field.day);
      }

      return newValue;
    });

    if (
      Number.isNaN(dayNumber) ||
      !monthNumber ||
      (monthNumber === 2 && dayNumber > 29) ||
      ([4, 6, 9, 11].includes(monthNumber) && dayNumber > 30) ||
      dayNumber > 31
    ) {
      return;
    }

    if (dayNumber < 10) {
      setDay(`0${dayNumber}`);
    } else {
      setDay(`${dayNumber}`);
    }
  };

  const onFocus = (field: Field) => {
    if (fieldsWithErrors.has(field) && fieldsWithErrors.size === 1) {
      setErrorIsVisible(false);
    }
  };

  const onBlur = (field: Field) => {
    if (fieldsWithErrors.has(field)) {
      setErrorIsVisible(true);
    }
  };

  const formIsValid = Boolean(year && month && day && !fieldsWithErrors.size);

  const onNext = async () => {
    if (!formIsValid) return;

    const birthdate = [year, month, day].join(dateDivider);

    await updateSession(
      { profile: { birthdate: `${birthdate} 00:00` } },
      ESourceAuthorization["aura.palmistry"]
    );

    dispatch(actions.form.addDate(birthdate));

    steps.saveCurrent(birthdate);

    steps.goNext();
  };

  return (
    <>
      <h3 className="palmistry-container__header">
        {translate("/birthdate.title")}
      </h3>

      <p className="palmistry-container__description">
        {translate("/birthdate.text")}
      </p>

      <div className="palmistry-container__form-birthday">
        <InputWrapper>
          <InputItem
            label={translate("/birthdate.year")}
            placeholder={translate("/birthdate.yyyy")}
            inputMode="numeric"
            maxLength={4}
            type="text"
            value={year}
            onChange={onChangeYear}
            onFocus={() => onFocus(Field.year)}
            onBlur={() => onBlur(Field.year)}
          />

          <InputItem
            label={translate("/birthdate.month")}
            placeholder={translate("/birthdate.mm")}
            inputMode="numeric"
            type="text"
            value={month}
            onChange={onChangeMonth}
            onFocus={() => onFocus(Field.month)}
            onBlur={() => onBlur(Field.month)}
          />

          <InputItem
            label={translate("/birthdate.day")}
            placeholder={translate("/birthdate.dd")}
            inputMode="numeric"
            type="text"
            value={day}
            onChange={onChangeDay}
            onFocus={() => onFocus(Field.day)}
            onBlur={() => onBlur(Field.day)}
          />
        </InputWrapper>

        <h3
          className={[
            "palmistry-container__error-text",
            errorIsVisible ? "palmistry-container__error-text_visible" : "",
          ].join(" ")}
        >
          Date not found. Please check your details and try again.
        </h3>
      </div>

      <Button type="button" disabled={!formIsValid} onClick={onNext} active>
        {translate("next")}
      </Button>
    </>
  );
}
