import { useState } from 'react' import { publishReview } from '@/lib/articleMutations' import { nostrService } from '@/lib/nostr' import { t } from '@/lib/i18n' import type { ReviewFormProps } from './reviewFormTypes' import type { Article } from '@/types/nostr' export interface ReviewFormController { pubkey: string | null content: string title: string text: string loading: boolean error: string | null setContent: (value: string) => void setTitle: (value: string) => void setText: (value: string) => void handleSubmit: (e: React.FormEvent) => Promise } export function useReviewFormController(params: { article: ReviewFormProps['article'] pubkey: string | null onSuccess?: () => void }): ReviewFormController { const [content, setContent] = useState('') const [title, setTitle] = useState('') const [text, setText] = useState('') const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const handleSubmit = buildReviewSubmitHandler({ article: params.article, pubkey: params.pubkey, content, title, text, setLoading, setError, reset: () => resetFields({ setContent, setTitle, setText }), ...(params.onSuccess ? { onSuccess: params.onSuccess } : {}), }) return { pubkey: params.pubkey, content, title, text, loading, error, setContent, setTitle, setText, handleSubmit, } } function buildReviewSubmitHandler(params: { article: Article pubkey: string | null content: string title: string text: string setLoading: (loading: boolean) => void setError: (error: string | null) => void reset: () => void onSuccess?: () => void }): (e: React.FormEvent) => Promise { return async (e: React.FormEvent): Promise => { e.preventDefault() const {pubkey} = params if (!pubkey) { return } const contentError = validateRequiredContent(params.content) if (contentError) { params.setError(contentError) return } await submitReview({ ...params, pubkey }) } } async function submitReview(params: { article: Article pubkey: string content: string title: string text: string setLoading: (loading: boolean) => void setError: (error: string | null) => void reset: () => void onSuccess?: () => void }): Promise { params.setLoading(true) params.setError(null) try { await publishReview(buildPublishReviewParams({ article: params.article, reviewerPubkey: params.pubkey, content: params.content, title: params.title, text: params.text })) params.reset() params.onSuccess?.() } catch (submitError) { params.setError(submitError instanceof Error ? submitError.message : t('review.form.error.publishFailed')) } finally { params.setLoading(false) } } function validateRequiredContent(content: string): string | null { if (!content.trim()) { return t('review.form.error.contentRequired') } return null } function buildPublishReviewParams(params: { article: Article reviewerPubkey: string content: string title: string text: string }): { articleId: string seriesId: string category: 'science-fiction' | 'scientific-research' authorPubkey: string reviewerPubkey: string content: string title?: string text?: string authorPrivateKey: string } { const privateKey = nostrService.getPrivateKey() if (!privateKey) { throw new Error(t('review.form.error.noPrivateKey')) } const category = normalizeArticleCategory(params.article) const seriesId = params.article.seriesId ?? '' return { articleId: params.article.id, seriesId, category, authorPubkey: params.article.pubkey, reviewerPubkey: params.reviewerPubkey, content: params.content.trim(), ...(params.title.trim() ? { title: params.title.trim() } : {}), ...(params.text.trim() ? { text: params.text.trim() } : {}), authorPrivateKey: privateKey, } } function normalizeArticleCategory(article: Article): 'science-fiction' | 'scientific-research' { if (article.category === 'author-presentation') { return 'science-fiction' } return article.category === 'scientific-research' ? 'scientific-research' : 'science-fiction' } function resetFields(params: { setContent: (value: string) => void setTitle: (value: string) => void setText: (value: string) => void }): void { params.setContent('') params.setTitle('') params.setText('') }