import { useState } from 'react' import type { Article } from '@/types/nostr' import type { AlbyInvoice } from '@/types/alby' import { paymentService } from '@/lib/payment' import { nostrService } from '@/lib/nostr' type UseArticlePaymentResult = { loading: boolean error: string | null paymentInvoice: AlbyInvoice | null handleUnlock: () => Promise handlePaymentComplete: () => Promise handleCloseModal: () => void } export function useArticlePayment( article: Article, pubkey: string | null, onUnlockSuccess?: () => void, connect?: () => Promise ): UseArticlePaymentResult { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const [paymentInvoice, setPaymentInvoice] = useState(null) const [paymentHash, setPaymentHash] = useState(null) const handleUnlock = (): Promise => unlockArticlePayment({ article, pubkey, connect, onUnlockSuccess, setLoading, setError, setPaymentInvoice, setPaymentHash, }) const handlePaymentComplete = (): Promise => checkPaymentAndUnlock({ article, pubkey, paymentHash, onUnlockSuccess, setError, setPaymentInvoice, setPaymentHash, }) const handleCloseModal = (): void => resetPaymentModalState({ setPaymentInvoice, setPaymentHash }) return { loading, error, paymentInvoice, handleUnlock, handlePaymentComplete, handleCloseModal, } } async function unlockArticlePayment(params: { article: Article pubkey: string | null connect: (() => Promise) | undefined onUnlockSuccess: (() => void) | undefined setLoading: (value: boolean) => void setError: (value: string | null) => void setPaymentInvoice: (value: AlbyInvoice | null) => void setPaymentHash: (value: string | null) => void }): Promise { if (!params.pubkey) { await ensureConnectedOrError({ connect: params.connect, setLoading: params.setLoading, setError: params.setError, }) return } params.setLoading(true) params.setError(null) try { const paymentResult = await paymentService.createArticlePayment({ article: params.article, userPubkey: params.pubkey, }) if (!paymentResult.success || !paymentResult.invoice || !paymentResult.paymentHash) { params.setError(paymentResult.error ?? 'Failed to create payment invoice') return } params.setPaymentInvoice(paymentResult.invoice) params.setPaymentHash(paymentResult.paymentHash) void checkPaymentAndUnlock({ article: params.article, pubkey: params.pubkey, paymentHash: paymentResult.paymentHash, onUnlockSuccess: params.onUnlockSuccess, setError: params.setError, setPaymentInvoice: params.setPaymentInvoice, setPaymentHash: params.setPaymentHash, }) } catch (e) { const errorMessage = e instanceof Error ? e.message : 'Failed to process payment' console.error('Payment processing error:', e) params.setError(errorMessage) } finally { params.setLoading(false) } } async function ensureConnectedOrError(params: { connect: (() => Promise) | undefined setLoading: (value: boolean) => void setError: (value: string | null) => void }): Promise { if (!params.connect) { params.setError('Please connect with Nostr first') return } params.setLoading(true) try { await params.connect() } finally { params.setLoading(false) } } async function checkPaymentAndUnlock(params: { article: Article pubkey: string | null paymentHash: string | null onUnlockSuccess: (() => void) | undefined setError: (value: string | null) => void setPaymentInvoice: (value: AlbyInvoice | null) => void setPaymentHash: (value: string | null) => void }): Promise { if (!params.paymentHash || !params.pubkey) { return } try { const hasPaid = await paymentService.waitForArticlePayment({ paymentHash: params.paymentHash, articleId: params.article.id, articlePubkey: params.article.pubkey, amount: params.article.zapAmount, recipientPubkey: params.pubkey, timeout: 300000, }) if (!hasPaid) { return } const content = await nostrService.getPrivateContent(params.article.id, params.article.pubkey) if (!content) { params.setError('Content not available. Please contact the author.') return } resetPaymentModalState({ setPaymentInvoice: params.setPaymentInvoice, setPaymentHash: params.setPaymentHash }) params.onUnlockSuccess?.() } catch (e) { console.error('Payment check error:', e) } } function resetPaymentModalState(params: { setPaymentInvoice: (value: AlbyInvoice | null) => void setPaymentHash: (value: string | null) => void }): void { params.setPaymentInvoice(null) params.setPaymentHash(null) }