"use client";

import {
  createContext,
  useCallback,
  useContext,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import { LoadingModal } from "@/app/components/ui/loading-modal";

type LoadingModalOptions = {
  message?: string;
  title?: string;
  ariaLabel?: string;
};

type LoadingModalContextValue = {
  isOpen: boolean;
  showLoading: (options?: LoadingModalOptions | string) => void;
  hideLoading: () => void;
};

const defaultOptions: Required<LoadingModalOptions> = {
  title: "Tunggu sebentar....",
  message: "Jangan tutup, proses sedang berlangsung",
  ariaLabel: "Memproses",
};

const LoadingModalContext = createContext<LoadingModalContextValue | null>(null);

export function LoadingModalProvider({ children }: { children: ReactNode }) {
  const [isOpen, setIsOpen] = useState(false);
  const [options, setOptions] = useState<Required<LoadingModalOptions>>(defaultOptions);

  const showLoading = useCallback((input?: LoadingModalOptions | string) => {
    const nextOptions =
      typeof input === "string"
        ? { ...defaultOptions, message: input }
        : { ...defaultOptions, ...input };

    setOptions(nextOptions);
    setIsOpen(true);
  }, []);

  const hideLoading = useCallback(() => {
    setIsOpen(false);
  }, []);

  const value = useMemo(
    () => ({
      isOpen,
      showLoading,
      hideLoading,
    }),
    [isOpen, showLoading, hideLoading],
  );

  return (
    <LoadingModalContext.Provider value={value}>
      {children}
      <LoadingModal
        open={isOpen}
        title={options.title}
        message={options.message}
        ariaLabel={options.ariaLabel}
      />
    </LoadingModalContext.Provider>
  );
}

export function useLoadingModal() {
  const context = useContext(LoadingModalContext);

  if (!context) {
    throw new Error("useLoadingModal harus dipakai di dalam LoadingModalProvider");
  }

  return context;
}
