import { useState, useCallback } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
import apiFetch from '@wordpress/api-fetch';
import type { SubmittedDocument, SubmissionResponse } from '../types';
import type { SavedSubmission } from './usePostContent';
import { REST_SUBMIT_PATH, ERRORS_TEXT } from '../shared/constants';

interface UseDocumentReviewReturn {
	isSubmitting: boolean;
	error: string | null;
	results: SubmittedDocument | null;
	submit: (title: string, content: string) => Promise<void>;
	reset: () => void;
}

export const useDocumentReview = (
	postId: number | null,
	postType: string,
	savedSubmission: SavedSubmission | null,
): UseDocumentReviewReturn => {
	const { receiveEntityRecords } = useDispatch(coreDataStore);
	const [isSubmitting, setIsSubmitting] = useState(false);
	const [error, setError] = useState<string | null>(null);
	const [results, setResults] = useState<SubmittedDocument | null>(
		savedSubmission
			? {
					id: savedSubmission.documentId,
					title: savedSubmission.submittedTitle,
					createdAt: savedSubmission.submittedAt,
				}
			: null,
	);

	const submit = useCallback(
		async (title: string, content: string) => {
			if (!content.trim() || postId === null) {
				setResults(null);
				setError(
					postId === null
						? ERRORS_TEXT.postIdMissing
						: ERRORS_TEXT.noContent,
				);

				return;
			}

			setIsSubmitting(true);
			setError(null);
			setResults(null);

			try {
				const data = await apiFetch<SubmissionResponse>({
					path: REST_SUBMIT_PATH,
					method: 'POST',
					data: {
						post_id: postId,
						title,
						content,
					},
				});

				if (data.document) {
					setResults(data.document);

					// Sync the editor's entity cache with the meta the BE already
					// persisted, avoiding a dirty state in the editor
					receiveEntityRecords('postType', postType, {
						id: postId,
						meta: {
							_cdraft_document_id: data.document.id,
							_cdraft_submitted_at: data.document.createdAt,
							_cdraft_submitted_title: data.document.title,
						},
					});
				}
			} catch (caught) {
				let message = 'Unknown error';

				if (caught instanceof Error) {
					message = caught.message;
				} else if (
					typeof caught === 'object' &&
					caught !== null &&
					'message' in caught
				) {
					const { message: errorMessage } = caught;
					message = String(errorMessage);
				}

				setError(message);
			} finally {
				setIsSubmitting(false);
			}
		},
		[postId, postType, receiveEntityRecords],
	);

	const reset = useCallback(() => {
		setResults(null);
		setError(null);
	}, []);

	return {
		isSubmitting,
		error,
		results,
		submit,
		reset,
	};
};
