/**
 * External dependencies.
 */
import { SelectControl, TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies.
 */
import API from '@spectra-pro-helpers/api';
import urls from '@spectra-pro-constants/urls';

/**
 * Renders controls for selecting or entering an author-related custom meta key.
 *
 * Displays a select control with available author meta fields for the current or specified
 * post and a text input for custom meta keys when selected. Updates the dynamic content
 * settings with the selected or entered meta key.
 *
 * @since x.x.x
 *
 * @param {Object}   props               - The component props.
 * @param {Object}   props.settings      - The dynamic content settings from the context.
 * @param {Function} props.updateSetting - Function to update settings in the context.
 * @param {string}   [props.type='text'] - The type of content ('text' or 'image').
 * @return {Element} The author field selection controls.
 */
const AuthorInfoField = ( { settings, updateSetting, type = 'text' } ) => {
	// State for available author meta keys and loading status.
	const [ authorMetaKeys, setAuthorMetaKeys ] = useState( [] );
	const [ isLoading, setIsLoading ] = useState( true );

	// Initialize API client for fetching author custom fields.
	const authorCustomFieldsAPI = new API( urls.userCustomFields );

	// Get the current post ID from the editor store.
	const currentPostId = useSelect( ( select ) => select( editorStore ).getCurrentPostId(), [] );

	/**
	 * Determines the post ID based on the source type.
	 *
	 * @return {number|null} The post ID or null if not applicable.
	 */
	const getPostId = () => {
		if ( settings.source.type === 'current_post' ) {
			return currentPostId;
		}

		if ( settings.source.type === 'post_type' ) {
			return settings.source?.post_id;
		}

		return null;
	};

	// Fetch author meta fields when source type or post ID changes.
	useEffect( () => {
		/**
		 * Fetches available author meta fields for the specified post.
		 */
		const fetchUserData = async () => {
			const postId = getPostId();
			if ( ! postId ) {
				setAuthorMetaKeys( [] );
				setIsLoading( false );
				return;
			}

			setIsLoading( true );

			try {
				// Fetch author meta fields via API.
				const response = await authorCustomFieldsAPI.list( {
					post_id: postId,
					type,
				} );

				// Transform response data into select options.
				const customFields = Object.entries( response?.data || {} )
					.map( ( [ , val ] ) => {
						if ( val && typeof val === 'object' && 'label' in val && 'value' in val ) {
							return {
								label: val.label,
								value: val.value,
							};
						}
						return null;
					} )
					.filter( Boolean );

				setAuthorMetaKeys( customFields );
			} catch ( error ) {
				// Clear meta keys on error.
				setAuthorMetaKeys( [] );
			} finally {
				setIsLoading( false );
			}
		};

		fetchUserData();
	}, [ settings.source.type, settings.source?.post_id ] );

	// Combine default options with fetched meta fields and custom input option.
	const mergedFields = [
		{ label: __( 'Choose', 'spectra-pro' ), value: '' },
		...authorMetaKeys,
		{ label: __( 'Custom Field', 'spectra-pro' ), value: 'custom' },
	];

	return (
		<>
			{ /* Select control for choosing an author custom field */ }
			<SelectControl
				label={ __( 'Custom Field', 'spectra-pro' ) }
				value={ settings.source.authorField || '' }
				options={ isLoading ? [ { label: __( 'Loading…', 'spectra-pro' ), value: '' } ] : mergedFields }
				onChange={ ( value ) => updateSetting( 'source.authorField', value ) }
				disabled={ isLoading }
			/>

			{ /* Text input for custom meta key when 'custom' is selected */ }
			{ settings.source.authorField === 'custom' && (
				<TextControl
					label={ __( 'Custom Meta Key', 'spectra-pro' ) }
					value={ settings.source.authorMetaKey || '' }
					onChange={ ( value ) => updateSetting( 'source.authorMetaKey', value ) }
				/>
			) }
		</>
	);
};

export default AuthorInfoField;
