// Import necessary modules and components
import { FieldErrors, Resolver, SubmitHandler, useForm } from "react-hook-form";
import { AdminDatasourceProd } from "../../data/datasource/api/admin_datasource";
import { AdminRepositoryProd } from "../../data/repository/admin_repository";
import { AdminPasswordValues } from "../../data/datasource/api/entities/admin_form_values";
import { useState } from "react";
import axios, { AxiosError } from "axios";
import { toast } from "react-toastify";

// Initialize data source and repository for admin
const adminDatasource = new AdminDatasourceProd();
const adminRepository = new AdminRepositoryProd(adminDatasource);

// Define resolver for form validation
const resolver: Resolver<AdminPasswordValues> = async (data) => {
  const errors: FieldErrors<AdminPasswordValues> = {};

  // Validate previous password
  if (!data.prevPassword) {
    errors.prevPassword = {
      type: "required",
      message: "Se requiere la contraseña actual",
    };
  }

  // Validate new password
  if (!data.newPassword) {
    errors.newPassword = {
      type: "required",
      message: "Se requiere una nueva contraseña",
    };
  } else if (data.newPasswordConfirm !== data.newPassword) {
    errors.newPasswordConfirm = {
      type: "validate",
      message: "Las contraseñas deben coincidir",
    };
  }

  // Validate new password confirmation
  if (!data.newPasswordConfirm) {
    errors.newPasswordConfirm = {
      type: "required",
      message: "Se requiere confirmar la nueva contraseña",
    };
  }

  return {
    values: Object.keys(errors).length > 0 ? {} : data,
    errors: errors,
  };
};

// Custom hook for changing admin password
export const useAdminChangePassword = (
  setChangePasswordWindowVisibility: (visibility: boolean) => void
) => {
  // Initialize form handling and state management
  const {
    register,
    handleSubmit,
    formState: { errors },
    setError,
  } = useForm<AdminPasswordValues>({ resolver });
  const [errorMessage, setErrorMessage] = useState("");

  // Handle form submission
  const onSubmit: SubmitHandler<AdminPasswordValues> = (
    data: AdminPasswordValues
  ) => {
    const fetch = async () => {
      try {
        const token = localStorage.getItem("token") || "";
        await adminRepository.changePassword(
          token,
          data.prevPassword,
          data.newPassword
        );
        setChangePasswordWindowVisibility(false);
      } catch (error: any) {
        if (axios.isAxiosError(error)) {
          error as AxiosError;
          switch (error.code) {
            case axios.AxiosError.ERR_BAD_REQUEST:
              setErrorMessage("Acceso no autorizado");
              setError("prevPassword", {
                type: "validate",
                message: "Contraseña incorrecta",
              });
              break;
            case axios.AxiosError.ERR_NETWORK:
              setErrorMessage("Conexión con el servidor fallida");
              break;
          }
        }
        throw new Error();
      }
    };
    toast.promise(fetch(), {
      pending: "Actualizando contraseña...",
      success: "La contraseña se ha actualizado",
      error: errorMessage,
    });
  };

  return { register, handleSubmit, errors, onSubmit };
};
