import { useCallback, useRef, useState } from 'react'
import type { Product } from '@platform-modules/commerce-catalog'
import { reviveProduct } from '@platform-modules/commerce-catalog-react'
import type { CreateVendorProductWire } from './client.js'
import { useMarketplaceContext } from './MarketplaceProvider.js'

export function useCreateVendorProduct(): {
  create: (input: CreateVendorProductWire) => Promise<Product>
  pending: boolean
  result: Product | undefined
  error: Error | undefined
  reset: () => void
} {
  const { client } = useMarketplaceContext('useCreateVendorProduct')
  const [result, setResult] = useState<Product | undefined>()
  const [error, setError] = useState<Error | undefined>()
  const [pending, setPending] = useState(false)

  const inflightRef = useRef(0)
  const latestTagRef = useRef(0)

  const create = useCallback((input: CreateVendorProductWire): Promise<Product> => {
    const tag = ++latestTagRef.current
    inflightRef.current++
    setPending(inflightRef.current > 0)

    return client
      .createVendorProduct(input)
      .then((wire) => {
        const revived = reviveProduct(wire)
        if (latestTagRef.current === tag) {
          setResult(revived)
          setError(undefined)
        }
        return revived
      })
      .catch((e: unknown) => {
        if (latestTagRef.current === tag) {
          setError(e instanceof Error ? e : new Error(String(e)))
          setResult(undefined)
        }
        throw e
      })
      .finally(() => {
        inflightRef.current--
        setPending(inflightRef.current > 0)
      })
  }, [client])

  const reset = useCallback(() => {
    // Orphan any in-flight create so its later resolve/reject no-ops on visible
    // state (same model as useSubmitReview); finally still decrements inflightRef.
    latestTagRef.current++
    setResult(undefined)
    setError(undefined)
  }, [])

  return { create, pending, result, error, reset }
}
