import React, {
  useContext,
  useEffect,
  useState,
  useRef,
  useMemo,
  useCallback,
} from "react";

//npm imports
import styled, { withTheme } from "styled-components/macro";
import { useParams, useNavigate, Link } from "react-router-dom";

//component imports
import { useTranslation } from "react-i18next";
import InputField from "../../Components/InputField/InputField";
import SelectInput from "../../Components/SelectInput/SelectInput";
import {
  Caption12,
  HeaderMedium28,
  Text33,
  SpecialHeader36,
} from "../../Components/Text/Text";
import ButtonWide, {
  StyledButtonWide,
} from "../../Components/ButtonWide/ButtonWide";
import Checkbox from "../../Components/Checkbox/Checkbox";
import BrainsterNextLogo from "../../Components/BrainsterNextLogo/BrainsterNextLogo";
import ArrowBack from "../../Components/ArrowBack/ArrowBack";

//hooks
import useArrayLength from "../../Hooks/useArrayLength";

//other imports
import { GlobalContext } from "../../Context/GlobalContext";
import { API } from "../../Consts/Api";
import coin_full from "./Static/coin-full.png";
import coin_vertical from "./Static/coin-vertical.png";
import coin_horizontal from "./Static/coin-horizontal.png";
import coin_distorted from "./Static/coin-full-distorted.png";
import application_form_background from "./Static/application-form-background.png";
import application_form_background_mobile from "./Static/application-form-background-mobile.png";
import { nextHeader } from "./Static/nextHeader";
import background from "./Static/backgroung.png";
import theme from "../../Consts/Theme";

const ApplicationFormWrapper = styled.section`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  position: relative;
  background-image: url(${background});
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;

  & > main {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background-color: ${(props) => props.theme.black};
    border-radius: 15px;
  }
  @media (max-width: 825px) {
    display: flex;
    align-items: center;
    flex-direction: column;
    background-color: ${(props) => props.theme.veryLightGray};
    padding-left: 16px;
    padding-right: 16px;
    background-size: unset;

    & > main {
      width: 100%;
      min-height: 75vh;
      form {
        ${HeaderMedium28} {
          display: none;
        }
      }
    }
  }
  @media (max-width: 550px) {
    & > aside {
      .header-container-mobile,
      .logo-and-arrow-container {
        width: 92%;
      }
      .coin-vertical {
        width: 100px;
      }
    }
    & > main {
      align-items: flex-start;
    }
  }
`;

const StyledSuccessMessage = styled.div`
  text-align: center;
  margin-top: 30px;
  margin-bottom: 50px;

  @media (max-width: 992px) { 
    margin-bottom: 20px;
    p {
      font-size: 20px;
      line-height: normal;
    }
  }

`

const StyledApplicationForm = styled.form`
  padding: 75px 100px;
  ${HeaderMedium28} {
    width: 82%;
    margin-bottom: 44px;
    font-size: 21px;
  }
  .birth-date-container {
    width: 100%;
    .birthDateInputsContainer {
      width: 100%;
      display: grid;
      grid-template-columns: 1fr;
      gap: 16px;
    }
  }
  .year-and-phone-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
  }
  .name-inputs-container,
  .email-and-phone-container {
    width: 100%;
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
  }

  .email-and-phone-container {
    margin-bottom: 36px;
  }
  ${Caption12}.error {
    color: ${(props) => props.theme.textError};
    height: 14px;
    margin-top: 8px;
  }
  & > ${Caption12} {
    margin-bottom: 16px;
  }

  @media (max-width: 992px) {
    width: 100%;
    padding: 55px 16px 30px;


  }

  @media (max-width: 1015px) {
    ${HeaderMedium28} {
      width: 100%;
    }
  }

  @media (max-width: 550px) {
    .birth-date-container {
      .birthDateInputsContainer {
        width: 100%;
        display: grid;
        grid-template-columns: 1fr;
        gap: 16px;
        .select-input__single-value {
          padding-left: 4px;
        }
        .select-input__value-container {
          padding: 2px 4px;
        }
        .select-input__indicators {
          margin-right: 8px;
          .select-input__indicator {
            padding: 0;
          }
          svg {
            transform: scale(0.99);
          }
        }
      }
    }
    .name-inputs-container,
    .email-and-phone-container {
      grid-template-columns: 1fr;
      gap: 0px;
    }
    .name-inputs-container,
    .birth-date-container {
      margin-bottom: 0px;
      .css-1hb7zxy-IndicatorsContainer {
        width: 25px;
      }
    }
    .email-and-phone-container {
      margin-bottom: 16px;
    }
    .year-and-phone-container {
      grid-template-columns: 1fr;
    }
    .error {
    }
    ${StyledButtonWide} {
      margin-top: 24px;
      margin-bottom: 40px;
    }
  }
`;


const RegistrationForm = (props) => {
  const { t } = useTranslation();
  const {
    userInfo,
    setUserInfo,
    termsAgreement,
    setDuration
  } = useContext(GlobalContext);
  //The birthDate is handled manually becuase it consists of 3 different fields and the
  //element #birthDateError displays the errors if there are any
  const resetErrors = {
    name: [],
    surname: [],
    email: [],
    highschool: [],
    birthDate: [],
    academyId: [],
    no_term: [],
    limit_exceeded: [],
  };
  const [errors, setErrors] = useState(resetErrors);
  const [result, setResult] = useState(false);

  const nameInputRef = useRef();
  const phoneInputRef = useRef();
  const highschoolInputRef = useRef();

  //needed for select inputs as options and for updating userInfo.birthDate
  const [days, setDays] = useState([
    { value: null, label: t("registration_form.form.birth_date.day") },
  ]);
  const [selectedDay, setSelectedDay] = useState(days[0]);
  const [months, setMonths] = useState([
    { value: null, label: t("registration_form.form.birth_date.month") },
  ]);
  const [selectedMonth, setSelectedMonth] = useState(months[0]);
  const [years, setYears] = useState([
    { value: null, label: t("registration_form.form.birth_date.year") },
  ]);
  const [selectedYear, SetSelectedYear] = useState(years[0]);

  const formRef = useRef();

  let params = useParams();
  let navigate = useNavigate();

  const allMonths = useMemo(
    () => [
      t("registration_form.form.birth_date.all_months.jan"),
      t("registration_form.form.birth_date.all_months.feb"),
      t("registration_form.form.birth_date.all_months.mar"),
      t("registration_form.form.birth_date.all_months.apr"),
      t("registration_form.form.birth_date.all_months.may"),
      t("registration_form.form.birth_date.all_months.jun"),
      t("registration_form.form.birth_date.all_months.jul"),
      t("registration_form.form.birth_date.all_months.aug"),
      t("registration_form.form.birth_date.all_months.sep"),
      t("registration_form.form.birth_date.all_months.oct"),
      t("registration_form.form.birth_date.all_months.nov"),
      t("registration_form.form.birth_date.all_months.dec"),
    ],
    [t]
  );
  useEffect(() => {
    let days = [
      { value: null, label: t("registration_form.form.birth_date.day") },
    ];
    for (let i = 0; i < 31; i++) {
      days.push({ value: i + 1, label: i + 1 });
    }
    let mnths = [
      { value: null, label: t("registration_form.form.birth_date.month") },
    ];
    allMonths.forEach((month, index) => {
      mnths.push({ value: index + 1, label: month });
    });
    let year = new Date();
    let years = [
      { value: null, label: t("registration_form.form.birth_date.year") },
    ];
    for (let i = year.getFullYear() - 15; i > 1960; i--) {
      years.push({ value: i, label: i });
    }
    setDays(days);
    setMonths(mnths);
    setYears(years);
    //eslint-disable-next-line
  }, []);

  useEffect(() => {
    setUserInfo({
      ...userInfo,
      birthDate: { ...userInfo.birthDate, day: selectedDay.value },
    });
    //eslint-disable-next-line
  }, [selectedDay.value, setUserInfo]);
  useEffect(() => {
    setUserInfo({
      ...userInfo,
      birthDate: { ...userInfo.birthDate, month: selectedMonth.value },
    });
    //eslint-disable-next-line
  }, [selectedMonth.value, setUserInfo]);
  useEffect(() => {
    setUserInfo({
      ...userInfo,
      birthDate: { ...userInfo.birthDate, year: selectedYear.value },
    });
    //eslint-disable-next-line
  }, [selectedYear.value, setUserInfo]);

  const applyStudent = async (e, userInfo, academyId) => {
    e.preventDefault();
    if (termsAgreement) {
      let user = {
        name: userInfo.name,
        highschool: userInfo.highschool,
        birth_date: userInfo.birthDate,
        phone: userInfo.phone,
        referred_by: params.referralGuid || userInfo.referred_by || null,
      };
      API.axios
        .post(API.createApiRoute("registration"), user)
        .then((response) => {
          if (response.data.success) {
            let guid = localStorage.getItem("guid");
            navigate(API.createRoute("result", { GUID: guid }));
                localStorage.removeItem("guid");

            if (response.data.data.guid) {
              setUserInfo({
                ...userInfo,
                guid: response.data.data.guid,
                academy_id: null,
              });
              
            }
          } else {
            setErrors({ ...errors, no_term: [response.data.message] });
          }
        })
        .catch((error) => {
          if (error?.response?.status === 422) {
            setErrors({
              ...resetErrors,
              ...error.response.data.errors,
              limit_exceeded: error.response.data.errors.additional || [],
              birthDate: [
                error.response.data.errors["birth_date.day"] ||
                  error.response.data.errors["birth_date.month"] ||
                  error.response.data.errors["birth_date.year"],
              ],
            });
          } else {
            setErrors({ ...errors, ...error.response.data.errors.additional });
          }
        });
    } else {
      setErrors({ ...errors, terms: t("errors.terms") });
    }
  };

  useEffect(() => {
    errors.terms && termsAgreement && setErrors({ ...errors, terms: false });
    //eslint-disable-next-line
  }, [errors.terms, termsAgreement]);

  useEffect(() => {
    !userInfo.academyId &&
      params.academyId &&
      setUserInfo({ ...userInfo, academyId: params.academyId });
    //eslint-disable-next-line
  }, [params, userInfo.academyId, setUserInfo]);

  //if there is data about the user in backend already
  //repopulate inputs with that data
  useEffect(() => {
    if (
      userInfo.name !== "" &&
      userInfo.name !== undefined &&
      nameInputRef.current
    ) {
      nameInputRef.current.value = userInfo.name;
    }
    if (
      userInfo.highschool !== "" &&
      userInfo.highschool !== undefined &&
      nameInputRef.current
    ) {
      highschoolInputRef.current.value = userInfo.highschool;
    }
    if (userInfo.birthDate?.day) {
      let days = [
        { value: null, label: t("registration_form.form.birth_date.day") },
      ];
      for (let i = 0; i < 31; i++) {
        days.push({ value: i + 1, label: i + 1 });
      }
      days.forEach(
        (day) => day.value === userInfo.birthDate.day && setSelectedDay(day)
      );
    }
    if (userInfo.birthDate?.day) {
      let mnths = [
        { value: null, label: t("registration_form.form.birth_date.month") },
      ];
      allMonths.forEach((month, index) => {
        mnths.push({ value: index + 1, label: month });
      });

      mnths.forEach(
        (month) =>
          month.value === userInfo.birthDate.month && setSelectedMonth(month)
      );
    }
    if (userInfo.birthDate?.year) {
      let year = new Date();
      let years = [
        { value: null, label: t("registration_form.form.birth_date.year") },
      ];
      for (let i = year.getFullYear() - 13; i > 1940; i--) {
        years.push({ value: i, label: i });
      }

      years.forEach(
        (year) =>
          year.value === userInfo.birthDate.year && SetSelectedYear(year)
      );
    }

    if (
      userInfo.phone !== "" &&
      userInfo.phone !== undefined &&
      phoneInputRef.current
    ) {
      phoneInputRef.current.value = userInfo.phone;
    }
  }, [
    userInfo.name,
    userInfo.surname,
    userInfo.email,
    userInfo.phone,
    userInfo.highschool,
    userInfo.birthDate?.day,
    userInfo.birthDate?.month,
    userInfo.birthDate?.year,
    userInfo.academyId,
    setSelectedDay,
    SetSelectedYear,
    setSelectedMonth,
    allMonths,
    t,
  ]);

  //if there is an error on the users name input and user makes a change in name input, remove the error
  useEffect(() => {
    errors.name.length > 0 && setErrors({ ...errors, name: [] });
    //eslint-disable-next-line
  }, [userInfo.name]);
  //if there is an error on the users surname input and user makes a change in surname input, remove the error
  useEffect(() => {
    errors.surname.length > 0 && setErrors({ ...errors, surname: [] });
    //eslint-disable-next-line
  }, [userInfo.surname]);
  //if there is an error on the users email input and user makes a change in email input, remove the error
  useEffect(() => {
    errors.email.length > 0 && setErrors({ ...errors, email: [] });
    //eslint-disable-next-line
  }, [userInfo.email]);

  useEffect(() => {
    errors?.phone?.length > 0 && setErrors({ ...errors, phone: [] });
    //eslint-disable-next-line
  }, [userInfo.phone]);

  useEffect(() => {
    errors.highschool.length > 0 && setErrors({ ...errors, highschool: [] });
    //eslint-disable-next-line
  }, [userInfo.highschool]);

  useEffect(() => {
    errors.birthDate.length > 0 && setErrors({ ...errors, birthDate: [] });
    //eslint-disable-next-line
  }, [userInfo?.birthDate]);

  const submitOnEnter = useCallback(
    (e) => {
      //it triggers by pressing the enter key
      if (e.keyCode === 13) {
        applyStudent(e, userInfo, params.academyId);
      }
      //eslint-disable-next-line
    },
    [applyStudent, params.academyId]
  );

  useEffect(() => {
    window.addEventListener("keydown", submitOnEnter);

    return () => {
      window.removeEventListener("keydown", submitOnEnter);
    };
  }, [submitOnEnter]);


  useEffect(() => {
    let guid = localStorage.getItem("guid");
      API.axios.get(API.createApiRoute("result", { GUID: guid }))
          .then(response => response.data.success && setResult(response.data.data))
          .catch(error => console.error(error.response))
      setDuration(false)
      //eslint-disable-next-line
  }, [])

  return (
    <ApplicationFormWrapper>
      {/* <aside>
        <div className="logo-and-arrow-container">
          <Link to={API.createRoute("home")}>
            <ArrowBack color={props.theme.white} />
          </Link>
          <BrainsterNextLogo
            color={props.theme.white}
            className="brainster-logo"
          />
        </div>
        <div className="header-container ">
          <SpecialHeader36 color={props.theme.white}>
            {t("registration_form.join")}
          </SpecialHeader36>
          <div>{nextHeader}</div>
        </div>
        <img className="coin-full" src={coin_full} alt="coin" />
        <img className="coin-horizontal" src={coin_horizontal} alt="coin" />
        <img className="coin-vertical" src={coin_vertical} alt="coin" />
        <img className="coin-distorted" src={coin_distorted} alt="coin" />
      </aside> */}

      <BrainsterNextLogo color={theme.white} />
      <StyledSuccessMessage>
      {result && result.completed ? 
<>
<Text33 color={theme.white} fontWeight={700} >
          {t("registration_form.success_part_one")}
        </Text33>
        <Text33 color={theme.white} fontWeight={700}>
          {t("registration_form.success_part_two")}
        </Text33>
</> : <>
<Text33 color={theme.white} fontWeight={700}>{ t("result.main.failed.header")}</Text33>
</>
}
        
      </StyledSuccessMessage>

      <main>
        <StyledApplicationForm
          ref={formRef}
          onSubmit={(e) => applyStudent(e, userInfo, params.academyId)}
        >
          <HeaderMedium28
            color={props.theme.danger_select}
            className="header-title"
          >
            {t("registration_form.header")}
          </HeaderMedium28>
          <div className="name-inputs-container">
            <InputField
              type="text"
              required
              name="given-name"
              ref={nameInputRef}
              onChange={() =>
                setUserInfo({ ...userInfo, name: nameInputRef.current.value })
              }
              autocomplete="family-name"
              label={t("registration_form.form.name")}
              placeholder={t("registration_form.form.name")}
              value={nameInputRef.current?.value}
              errors={errors.name}
            />
          </div>

          <div className="year-and-phone-container">
            <InputField
              required
              type="tel"
              name="tel"
              ref={phoneInputRef}
              onChange={() =>
                setUserInfo({ ...userInfo, phone: phoneInputRef.current.value })
              }
              autocomplete="tel"
              label={t("registration_form.form.phone")}
              placeholder={t("registration_form.form.phone")}
              value={phoneInputRef.current?.value}
              className="phone-input-container"
              errors={errors.phone}
            />

            <div className="birth-date-container">
              <Caption12 color={props.theme.gray2}>
                {t("registration_form.form.birth_date.label")}*
              </Caption12>
              <div className="birthDateInputsContainer">
                <div className="birth-date-input-container year-input">
                  <SelectInput
                    data={years}
                    selectedOption={selectedYear}
                    onChange={SetSelectedYear}
                    error={errors?.birthDate?.length > 0}
                  />
                </div>
              </div>
              <Caption12 id="birthDateError" className="error">
                {useArrayLength(errors.birthDate) &&
                  errors.birthDate.map((error, index) => (
                    <React.Fragment key={index}>
                      <span>{error}</span>
                      <br />
                    </React.Fragment>
                  ))}
              </Caption12>
            </div>
          </div>
          <InputField
            type="text"
            required
            name="highschool"
            ref={highschoolInputRef}
            onChange={() =>
              setUserInfo({
                ...userInfo,
                highschool: highschoolInputRef.current.value,
              })
            }
            label={t("registration_form.form.highschool")}
            placeholder={t("registration_form.form.highschool")}
            value={highschoolInputRef.current?.value}
            className="email-input-container"
            errors={errors.highschool}
          />
          <Caption12 color={props.theme.textError}>
            {useArrayLength(errors.no_term) &&
              errors.no_term.map((error, index) => (
                <span key={index}>
                  <span>{error}</span>
                  <br />
                </span>
              ))}
          </Caption12>
          <Caption12 color={props.theme.textError}>
            {useArrayLength(errors.limit_exceeded) &&
              errors.limit_exceeded.map((error, index) => (
                <span key={index}>
                  <span>{error}</span>
                  <br />
                </span>
              ))}
          </Caption12>
          <ButtonWide
            type="submit"
            text={t("general.continue")}
            disabled={!termsAgreement}
          />
        </StyledApplicationForm>
      </main>
    </ApplicationFormWrapper>
  );
};

export default withTheme(RegistrationForm);
