import { useState, useEffect } from '@wordpress/element';
import {
	Button,
	CheckboxControl,
	SelectControl,
	TextControl,
	Spinner,
} from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';

const TYPE_OPTIONS = [
	{ label: 'Text', value: 'CHAR' },
	{ label: 'Number (integer)', value: 'NUMERIC' },
	{ label: 'Number (decimal)', value: 'DECIMAL' },
	{ label: 'Date', value: 'DATE' },
	{ label: 'Date & Time', value: 'DATETIME' },
	{ label: 'Time', value: 'TIME' },
	{ label: 'Binary', value: 'BINARY' },
	{ label: 'Unsigned integer', value: 'UNSIGNED' },
];

const COMPARE_OPTIONS = [
	{ label: '= (equals)', value: '=' },
	{ label: '!= (not equals)', value: '!=' },
	{ label: '< (less than)', value: '<' },
	{ label: '> (greater than)', value: '>' },
	{ label: '<= (less or equal)', value: '<=' },
	{ label: '>= (greater or equal)', value: '>=' },
	{ label: 'LIKE (contains)', value: 'LIKE' },
	{ label: 'NOT LIKE', value: 'NOT LIKE' },
	{ label: 'IN (one of)', value: 'IN' },
	{ label: 'NOT IN', value: 'NOT IN' },
	{ label: 'BETWEEN', value: 'BETWEEN' },
	{ label: 'NOT BETWEEN', value: 'NOT BETWEEN' },
	{ label: 'EXISTS', value: 'EXISTS' },
	{ label: 'NOT EXISTS', value: 'NOT EXISTS' },
];

export default function MetaKeySelector( { blockConfig, objectType, endpoint, onChange } ) {
	const [ availableKeys, setAvailableKeys ] = useState( [] );
	const [ loading, setLoading ] = useState( false );
	const [ patternInput, setPatternInput ] = useState( '' );
	const [ patternError, setPatternError ] = useState( '' );
	const [ search, setSearch ] = useState( '' );
	const metaKeys = blockConfig.meta_keys || {};
	const metaObjectType = objectType || 'post';
	const postType = blockConfig.post_type || '';

	useEffect( () => {
		setLoading( true );
		let path;
		if ( endpoint ) {
			path = `wlconduit/v1/ext/${ endpoint }`;
		} else {
			path = `wlconduit/v1/meta-keys?object_type=${ metaObjectType }`;
			if ( metaObjectType === 'post' && postType ) {
				path += `&post_type=${ postType }`;
			}
		}
		apiFetch( { path } )
			.then( ( keys ) => setAvailableKeys( keys || [] ) )
			.catch( () => setAvailableKeys( [] ) )
			.finally( () => setLoading( false ) );
	}, [ endpoint, metaObjectType, postType ] );

	function toggleKey( key ) {
		const updated = { ...metaKeys };
		if ( updated[ key ] ) {
			delete updated[ key ];
		} else {
			updated[ key ] = {
				as_field: true,
				as_filter: false,
				type: 'CHAR',
				compare: [ '=' ],
			};
		}
		onChange( updated );
	}

	function updateKeyConfig( key, partial ) {
		const updated = {
			...metaKeys,
			[ key ]: { ...metaKeys[ key ], ...partial },
		};
		onChange( updated );
	}

	function toggleCompare( key, op ) {
		const current = metaKeys[ key ]?.compare || [ '=' ];
		const updated = current.includes( op )
			? current.filter( ( c ) => c !== op )
			: [ ...current, op ];
		updateKeyConfig( key, { compare: updated } );
	}

	function addPatternKey() {
		const trimmed = patternInput.trim();
		if ( ! trimmed ) {
			return;
		}
		if ( ! trimmed.includes( '%' ) ) {
			setPatternError( 'Pattern key must contain a % wildcard.' );
			return;
		}
		if ( metaKeys[ trimmed ] ) {
			setPatternError( 'This pattern key already exists.' );
			return;
		}
		setPatternError( '' );
		onChange( {
			...metaKeys,
			[ trimmed ]: { as_field: true },
		} );
		setPatternInput( '' );
	}

	function removePatternKey( key ) {
		const updated = { ...metaKeys };
		delete updated[ key ];
		onChange( updated );
	}

	const patternKeys = Object.keys( metaKeys ).filter( ( k ) => k.includes( '%' ) );

	function handleRefresh() {
		setLoading( true );
		let path;
		if ( endpoint ) {
			path = `wlconduit/v1/ext/${ endpoint }?refresh=1`;
		} else {
			path = `wlconduit/v1/meta-keys?object_type=${ metaObjectType }&refresh=1`;
			if ( metaObjectType === 'post' && postType ) {
				path += `&post_type=${ postType }`;
			}
		}
		apiFetch( { path } )
			.then( ( keys ) => setAvailableKeys( keys || [] ) )
			.catch( () => {} )
			.finally( () => setLoading( false ) );
	}

	if ( loading ) {
		return <Spinner />;
	}

	return (
		<div className="aic-meta-selector">
			<div className="aic-selector-header">
				<p className="aic-selector-hint">
					Select custom fields to include as data or expose as filters.
				</p>
				<Button variant="tertiary" isSmall onClick={ handleRefresh }>
					Refresh
				</Button>
			</div>

			{ availableKeys.length > 0 && (
				<TextControl
					placeholder="Search meta keys…"
					value={ search }
					onChange={ setSearch }
					className="aic-search-input"
				/>
			) }

			{ availableKeys.length === 0 ? (
				<p>No meta keys found.</p>
			) : (
				availableKeys.filter( ( item ) => {
					if ( ! search ) {
						return true;
					}
					const key = item.key || item;
					return key.toLowerCase().includes( search.toLowerCase() );
				} ).map( ( item ) => {
					const key = item.key || item;
					const isInternal = item.internal || false;
					const isSerialized = item.serialized || false;
					const isSelected = !! metaKeys[ key ];
					const config = metaKeys[ key ] || {};

					return (
						<div key={ key } className={ `aic-meta-item ${ isInternal ? 'aic-meta-item--internal' : '' }` }>
							<CheckboxControl
								label={ isInternal ? `${ key } (internal)` : key }
								checked={ isSelected }
								onChange={ () => toggleKey( key ) }
							/>

							{ isSelected && (
								<div className="aic-meta-config">
									<CheckboxControl
										label="Include as field data"
										checked={ config.as_field !== false }
										onChange={ ( val ) => updateKeyConfig( key, { as_field: val } ) }
									/>
									{ isSerialized ? (
										<p className="aic-meta-serialized-hint">
											Serialized value — filtering not available.
										</p>
									) : (
									<CheckboxControl
										label="Use as filter (LLM can query by this)"
										checked={ !! config.as_filter }
										onChange={ ( val ) => updateKeyConfig( key, { as_filter: val } ) }
									/>
									) }

									{ ! isSerialized && config.as_filter && (
										<>
											<SelectControl
												label="Data type"
												value={ config.type || 'CHAR' }
												options={ TYPE_OPTIONS }
												onChange={ ( val ) => updateKeyConfig( key, { type: val } ) }
											/>
											<div className="aic-compare-options">
												<label>Comparison operators:</label>
												{ COMPARE_OPTIONS.map( ( op ) => (
													<CheckboxControl
														key={ op.value }
														label={ op.label }
														checked={ ( config.compare || [ '=' ] ).includes( op.value ) }
														onChange={ () => toggleCompare( key, op.value ) }
													/>
												) ) }
											</div>
										</>
									) }
								</div>
							) }
						</div>
					);
				} )
			) }

			<div className="aic-dynamic-meta-section">
				<h4>Dynamic Meta Keys</h4>
				<p className="aic-selector-hint">
					Add pattern-based meta keys using % as wildcard (e.g., _course_completed_%).
				</p>
				<div className="aic-dynamic-meta-input">
					<TextControl
						placeholder="_course_completed_%"
						value={ patternInput }
						onChange={ ( val ) => { setPatternInput( val ); setPatternError( '' ); } }
						onKeyDown={ ( e ) => {
							if ( e.key === 'Enter' ) {
								e.preventDefault();
								addPatternKey();
							}
						} }
					/>
					<Button variant="secondary" isSmall onClick={ addPatternKey }>
						Add
					</Button>
				</div>
				{ patternError && (
					<p className="aic-pattern-error" style={ { color: '#cc1818', fontSize: '12px', margin: '4px 0 0' } }>
						{ patternError }
					</p>
				) }
				{ patternKeys.map( ( key ) => (
					<div key={ key } className="aic-dynamic-meta-item">
						<span>{ key }</span>
						<Button isSmall isDestructive variant="tertiary" onClick={ () => removePatternKey( key ) }>
							Remove
						</Button>
					</div>
				) ) }
			</div>
		</div>
	);
}
