'use client';

import { useTransition } from 'react';
import { useFeedback } from '@/app/_hooks/use-feedback';

/**
 * 화면이 기다려야 하는 동작을 전역 스피너와 함께 돌린다 — `useTransition`을 그대로 쓰되
 * 진행 중 표시를 붙인 것이다.
 *
 * 삭제처럼 확인 얼럿이 닫힌 뒤에 진행되는 동작은 표시가 행 아이콘 하나뿐이라 눌렸는지조차
 * 알기 어렵다. 그런 자리에 쓴다 — 버튼이 스스로 "저장 중"을 보여주는 자리에는 쓰지 않는다.
 *
 * 스피너를 켜는 것은 transition 밖에서 한다. 안에서 켜면 낮은 우선순위로 밀려 늦게 그려진다.
 * 끄는 것은 안에서 해야 갱신된 화면이 준비될 때까지 스피너가 남는다.
 */
export function useBlockingAction(): [
  boolean,
  (action: () => void | Promise<void>) => void,
] {
  const { showSpinner, hideSpinner } = useFeedback();
  const [isPending, startTransition] = useTransition();

  function run(action: () => void | Promise<void>) {
    showSpinner();
    startTransition(async () => {
      try {
        await action();
      } finally {
        hideSpinner();
      }
    });
  }

  return [isPending, run];
}
