"use client"

import { useCallback, useState } from "react"
import { toast } from "sonner"
import type { ActionState } from "@/shared/types/action-state"

export interface UseActionMutationOptions<T> {
  /** 成功时显示的 toast 文案。不传则使用 result.message。传 false 则不显示。 */
  successMessage?: string | false
  /** 失败时显示的 toast 文案。不传则使用 result.message。传 false 则不显示。 */
  errorMessage?: string | false
  /** 成功回调 */
  onSuccess?: (data: T | undefined) => void
  /** 失败回调（result.success === false 或抛出异常时） */
  onError?: (error: unknown) => void
}

export interface UseActionMutationResult<T> {
  /** 是否正在执行（try/catch/finally 期间为 true） */
  isWorking: boolean
  /** 执行 mutation。返回 ActionState 以便调用方进一步处理。 */
  mutate: (action: () => Promise<ActionState<T>>) => Promise<ActionState<T> | undefined>
}

/**
 * 通用 Server Action mutation Hook。
 *
 * 用于替代各组件中重复的 `setIsWorking(true) + try/catch/finally + toast` 模式。
 *
 * @example
 * const { mutate, isWorking } = useActionMutation({
 *   onSuccess: () => { setOpen(false); router.refresh() }
 * })
 *
 * const handleDelete = () => mutate(() => deleteSchoolAction(id))
 */
export function useActionMutation<T = unknown>(
  options: UseActionMutationOptions<T> = {}
): UseActionMutationResult<T> {
  const { successMessage, errorMessage, onSuccess, onError } = options
  const [isWorking, setIsWorking] = useState(false)

  const mutate = useCallback(
    async (action: () => Promise<ActionState<T>>): Promise<ActionState<T> | undefined> => {
      setIsWorking(true)
      try {
        const result = await action()
        if (result.success) {
          if (successMessage !== false) {
            toast.success(successMessage ?? result.message ?? "Operation succeeded")
          }
          onSuccess?.(result.data)
        } else {
          if (errorMessage !== false) {
            toast.error(errorMessage ?? result.message ?? "Operation failed")
          }
          onError?.(new Error(result.message ?? "Action returned failure"))
        }
        return result
      } catch (error) {
        if (errorMessage !== false) {
          toast.error(errorMessage ?? "Operation failed")
        }
        onError?.(error)
        return undefined
      } finally {
        setIsWorking(false)
      }
    },
    [successMessage, errorMessage, onSuccess, onError]
  )

  return { isWorking, mutate }
}
