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

export default function TaxonomySelector( { blockConfig, objectType, endpoint, onChange } ) {
	const [ availableTaxonomies, setAvailableTaxonomies ] = useState( [] );
	const [ termsCache, setTermsCache ] = useState( {} );
	const [ loadingTax, setLoadingTax ] = useState( false );
	const [ loadingTerms, setLoadingTerms ] = useState( {} );
	const [ search, setSearch ] = useState( '' );
	const taxonomies = blockConfig.taxonomies || {};
	const taxObjectType = objectType || blockConfig.post_type || 'post';

	useEffect( () => {
		setLoadingTax( true );
		const path = endpoint
			? `wlconduit/v1/ext/${ endpoint }`
			: `wlconduit/v1/taxonomies?object_type=${ taxObjectType }`;
		apiFetch( { path } )
			.then( ( data ) => setAvailableTaxonomies( data || [] ) )
			.catch( () => setAvailableTaxonomies( [] ) )
			.finally( () => setLoadingTax( false ) );
	}, [ endpoint, taxObjectType ] );

	function loadTerms( taxonomy, refresh = false ) {
		if ( termsCache[ taxonomy ] && ! refresh ) {
			return;
		}

		setLoadingTerms( ( prev ) => ( { ...prev, [ taxonomy ]: true } ) );
		const refreshParam = refresh ? '&refresh=1' : '';
		apiFetch( { path: `wlconduit/v1/terms?taxonomy=${ taxonomy }${ refreshParam }` } )
			.then( ( data ) => {
				setTermsCache( ( prev ) => ( { ...prev, [ taxonomy ]: data || [] } ) );
			} )
			.catch( () => {} )
			.finally( () => {
				setLoadingTerms( ( prev ) => ( { ...prev, [ taxonomy ]: false } ) );
			} );
	}

	function toggleTaxonomy( taxSlug ) {
		const updated = { ...taxonomies };
		if ( updated[ taxSlug ] ) {
			delete updated[ taxSlug ];
		} else {
			updated[ taxSlug ] = {
				as_field: true,
				as_filter: false,
				terms: [],
			};
			loadTerms( taxSlug );
		}
		onChange( updated );
	}

	function updateTaxConfig( taxSlug, partial ) {
		const updated = {
			...taxonomies,
			[ taxSlug ]: { ...taxonomies[ taxSlug ], ...partial },
		};

		// Load terms when enabling as filter.
		if ( partial.as_filter && ! termsCache[ taxSlug ] ) {
			loadTerms( taxSlug );
		}

		onChange( updated );
	}

	function toggleTerm( taxSlug, termSlug ) {
		const currentTerms = taxonomies[ taxSlug ]?.terms || [];
		const updatedTerms = currentTerms.includes( termSlug )
			? currentTerms.filter( ( t ) => t !== termSlug )
			: [ ...currentTerms, termSlug ];

		updateTaxConfig( taxSlug, { terms: updatedTerms } );
	}

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

	return (
		<div className="aic-taxonomy-selector">
			<p className="aic-selector-hint">
				Select taxonomies to include as data or expose as filters.
				When used as a filter, pick which terms the AI can filter by.
			</p>

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

			{ availableTaxonomies.length === 0 ? (
				<p>No taxonomies found for this post type.</p>
			) : (
				availableTaxonomies.filter( ( tax ) => {
					if ( ! search ) {
						return true;
					}
					const term = search.toLowerCase();
					return ( tax.name || '' ).toLowerCase().includes( term )
						|| ( tax.label || '' ).toLowerCase().includes( term );
				} ).map( ( tax ) => {
					const isSelected = !! taxonomies[ tax.name ];
					const isInternal = tax.internal || false;
					const config = taxonomies[ tax.name ] || {};
					const terms = termsCache[ tax.name ] || [];
					const isLoadingTerms = loadingTerms[ tax.name ];

					return (
						<div key={ tax.name } className={ `aic-taxonomy-item ${ isInternal ? 'aic-taxonomy-item--internal' : '' }` }>
							<CheckboxControl
								label={ isInternal ? `${ tax.label } (internal)` : tax.label }
								checked={ isSelected }
								onChange={ () => toggleTaxonomy( tax.name ) }
							/>

							{ isSelected && (
								<div className="aic-taxonomy-config">
									<CheckboxControl
										label="Include term names as field data"
										checked={ config.as_field !== false }
										onChange={ ( val ) => updateTaxConfig( tax.name, { as_field: val } ) }
									/>
									<CheckboxControl
										label="Use as filter (AI can filter posts by this taxonomy)"
										checked={ !! config.as_filter }
										onChange={ ( val ) => updateTaxConfig( tax.name, { as_filter: val } ) }
									/>

									{ config.as_filter && (
										<div className="aic-terms-selector">
											<div className="aic-terms-header">
												<label>Allowed terms:</label>
												<Button
													variant="tertiary"
													isSmall
													onClick={ () => loadTerms( tax.name, true ) }
												>
													Refresh
												</Button>
											</div>

											{ isLoadingTerms ? (
												<Spinner />
											) : terms.length === 0 ? (
												<p>No terms found.</p>
											) : (
												terms.map( ( term ) => (
													<CheckboxControl
														key={ term.slug }
														label={ `${ term.name } (${ term.count })` }
														checked={ ( config.terms || [] ).includes( term.slug ) }
														onChange={ () => toggleTerm( tax.name, term.slug ) }
													/>
												) )
											) }
										</div>
									) }
								</div>
							) }
						</div>
					);
				} )
			) }
		</div>
	);
}
