import {memo, useEffect, useCallback, useMemo, forwardRef} from '@wordpress/element';
import FieldRenderer from '../../../design/FieldRenderer';
import SummaryRenderer from './SummaryRenderer';

const Section = forwardRef(( {entityData, section, allMetaData, onDataChange, availableConditions, compatibleConditions, i18n, setDependentFields, setCompatibleConditions, injectedFields, isCollapsed, onToggleSection, sectionId, onSetDirty}, ref ) => {

	const handleToggle = useCallback( () => {
		onToggleSection( sectionId );
	}, [onToggleSection, sectionId] );


	const { controllerFields, regularFields } = useMemo(() => {
		const controllers = [];
		const regulars = [];

		// Make sure, that section.fields exist
		(section.fields || []).forEach(field => {
			if (field.controls_dependencies === true) {
				controllers.push(field);
			} else {
				regulars.push(field);
			}
		});

		return { controllerFields: controllers, regularFields: regulars };
	}, [section.fields]);

	// Find the master field
	const controllerField = useMemo(
		() => section.fields.find( f => f.controls_dependencies === true ),
		[section.fields]
	);
	const selectedOption = useMemo( () => {
		if ( ! controllerField ) {
			return null;
		}
		const selectedValue = allMetaData[controllerField.id];
		return controllerField.options ? controllerField.options[selectedValue] : null;
	}, [controllerField, allMetaData] );

	// Take care of dependent fields and the condition-compatibility restriction
	useEffect( () => {
		if ( typeof setDependentFields === 'function' ) {
			setDependentFields( selectedOption?.dependent_fields || [] );
		}
		if ( typeof setCompatibleConditions === 'function' ) {
			setCompatibleConditions( selectedOption?.compatible_conditions ?? null );
		}
	}, [selectedOption, setDependentFields, setCompatibleConditions] );

	// Narrows the condition catalog to whatever the currently selected type allows
	const conditionsForBuilder = useMemo( () => {
		if ( !availableConditions || !Array.isArray( compatibleConditions ) ) {
			return availableConditions;
		}
		return Object.fromEntries(
			Object.entries( availableConditions ).map( ( [id, config] ) => [
				id,
				{...config, incompatibleWithType: !compatibleConditions.includes( id )}
			] )
		);
	}, [availableConditions, compatibleConditions] );

	const conditionsField = useMemo( () => ({id: 'conditions_tree', type: 'conditions'}), [] );

	const renderFieldList = (fields) => {
		if (!Array.isArray(fields) || fields.length === 0) return null;
		return fields.map(field => (
			<FieldRenderer
				ref={ref}
				key={field.id}
				field={field}
				allMetaData={allMetaData}
				onDataChange={onDataChange}
				entityData={entityData}
				onSetDirty={onSetDirty}
				fields={fields}
				variantClass={field.class}
			/>
		));
	};

	return (
		<div className={`adpresso-modal-section ${isCollapsed ? 'is-collapsed' : 'is-open'}`}>
			<h2 className="adpresso-modal-section-title" onClick={handleToggle}>
				{section.title}
			</h2>
			{isCollapsed ? (
				<div className="adpresso-modal-section-summary" onClick={handleToggle}>
					<SummaryRenderer section={section} allMetaData={allMetaData} entityData={entityData} i18n={i18n} availableConditions={availableConditions}/>
				</div>
			) : (
				<div className="adpresso-modal-section-fields">

					{section.id === 'adpresso_conditions' ? (
						// Special case: Conditions
						<FieldRenderer field={conditionsField}
									   allMetaData={allMetaData}
									   onDataChange={onDataChange}
									   availableConditions={conditionsForBuilder}
									   entityData={entityData}
						/>
					) : (
						// Default section with sorted order
						<>
							{renderFieldList(controllerFields)}
							{renderFieldList(Array.isArray(injectedFields) ? injectedFields : [])}
							{renderFieldList(regularFields)}
						</>
					)}
				</div>
			)}
		</div>
	);
});

export default memo( Section );
