"use client";

import AuthButton from "@/components/auth/AuthButton";
import AuthHead from "@/components/auth/AuthHead";
import AuthPasswordInput from "@/components/auth/AuthPasswordInput";
import AuthOtpInput from "@/components/auth/AuthOtpInput";
import Container from "@/components/elements/Container";
import Link from "next/link";
import React, { useMemo, useState } from "react";
import useAxios from "@/hooks/useAxios";
import { useFormik } from "formik";
import * as yup from "yup";
import { useRouter } from "next/navigation";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import LocalePageShell from "@/components/i18n/LocalePageShell";

function ChangePassword() {
  const { t } = useTranslation("common");
  const router = useRouter();
  const { request, loading } = useAxios();
  const [otpError, setOtpError] = useState(false);

  const resetIdentifier = useMemo(
    () =>
      typeof window !== "undefined"
        ? localStorage.getItem("reset_identifier")
        : null,
    []
  );
  const resetChannel = useMemo(
    () =>
      typeof window !== "undefined"
        ? localStorage.getItem("reset_channel")
        : null,
    []
  );
  const isEmailReset = resetChannel === "email";

  const schema = useMemo(
    () =>
      yup.object().shape({
        otp: yup
          .string()
          .matches(/^\d{6}$/, t("auth.otpInvalid"))
          .required(t("auth.otpRequired")),
        password: yup
          .string()
          .required(t("auth.passwordRequired"))
          .min(8, t("auth.passwordMin"))
          .matches(
            /^(?=.*[a-zA-Zآ-ی])(?=.*\d).{8,}$/,
            t("auth.passwordLettersNumbers")
          ),
        confirmPassword: yup
          .string()
          .required(t("auth.confirmPasswordRequired"))
          .oneOf([yup.ref("password")], t("auth.confirmPasswordMismatch")),
      }),
    [t]
  );

  const formik = useFormik({
    initialValues: {
      otp: "",
      password: "",
      confirmPassword: "",
    },
    validationSchema: schema,
    onSubmit: async (values) => {
      if (!resetIdentifier) {
        toast.error(t("auth.getResetCodeFirst"));
        router.push("/forget-password");
        return;
      }

      const isMobile = /^09\d{9}$/.test(resetIdentifier);
      try {
        await request("POST", "/login/change_password", {
          ...(isMobile
            ? { mobile: resetIdentifier }
            : { email: resetIdentifier }),
          otp: values.otp.trim(),
          new_password: values.password,
        });
        localStorage.removeItem("reset_identifier");
        localStorage.removeItem("reset_channel");
        toast.success(t("auth.passwordChangedSuccess"));
        router.push("/login-with-username");
      } catch (err: unknown) {
        setOtpError(true);
        const message =
          (err as { response?: { data?: { message?: string } } })?.response?.data
            ?.message || t("auth.changePasswordFailed");
        toast.error(message);
      }
    },
  });

  return (
    <LocalePageShell>
      <Container>
        <div className="p-4 flex flex-col items-center h-screen justify-center">
          <AuthHead title={t("auth.changePasswordTitle")} />
          <p className="text-sm text-gray-500 text-center mb-4 max-w-sm">
            {isEmailReset
              ? t("auth.changePasswordEmailHint")
              : t("auth.changePasswordMobileHint")}
          </p>
          <form
            onSubmit={formik.handleSubmit}
            className="w-full max-w-sm flex flex-col items-center"
          >
            <AuthOtpInput
              className="mt-3"
              value={formik.values.otp}
              onChange={(otp) => {
                formik.setFieldValue("otp", otp);
                setOtpError(false);
              }}
              error={
                otpError || Boolean(formik.touched.otp && formik.errors.otp)
              }
              disabled={loading}
            />
            {formik.touched.otp && formik.errors.otp && (
              <small className="text-red-500 mt-2">{formik.errors.otp}</small>
            )}

            <AuthPasswordInput
              name="password"
              placeholder={t("auth.newPasswordPlaceholder")}
              wrapperClassName="mt-4"
              className={`border ${
                formik.touched.password && formik.errors.password
                  ? "border-red-500 dark:border-red-500"
                  : "border-gray-300"
              }`}
              value={formik.values.password}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            />
            {formik.touched.password && formik.errors.password && (
              <small className="text-red-500 mt-2 block">
                {formik.errors.password}
              </small>
            )}

            <AuthPasswordInput
              name="confirmPassword"
              placeholder={t("auth.confirmPasswordPlaceholder")}
              wrapperClassName="mt-4"
              className={`border ${
                formik.touched.confirmPassword && formik.errors.confirmPassword
                  ? "border-red-500 dark:border-red-500"
                  : "border-gray-300"
              }`}
              value={formik.values.confirmPassword}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            />
            {formik.touched.confirmPassword && formik.errors.confirmPassword && (
              <small className="text-red-500 mt-2 block">
                {formik.errors.confirmPassword}
              </small>
            )}

            <AuthButton
              type="submit"
              className="mt-5"
              loading={loading}
              disabled={loading || formik.values.otp.length !== 6}
            >
              {t("auth.changePassword")}
            </AuthButton>
          </form>

          <Link href="/forget-password">
            <small className="text-[#667AC1] font-bold text-xs mt-8 block">
              {t("auth.resendCodeLink")}
            </small>
          </Link>
          <Link href="/login-with-username">
            <small className="text-[#FF5C00] font-bold text-xs mt-4 block">
              {t("auth.backToLogin")}
            </small>
          </Link>
        </div>
      </Container>
    </LocalePageShell>
  );
}

export default ChangePassword;
