/**
 * Searchable Gutenberg / My Blocks identity icon picker.
 * Dashicons + Lucide + emoji (identity only — not content/button icons).
 */
import { useEffect, useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import {
	blockIdentityCatalog,
	cachedLucideIdentitySvg,
	fetchLucideIdentitySvg,
	normalizeBlockIdentityIcon,
	parseBlockIdentityIcon,
} from '../../shared/blockIdentityIcon';
import { normalizeInlineSvg } from '../../shared/iconRegistry';

const PREVIEW_LIMIT = 120;

/**
 * @param {object} props
 * @param {import('../../shared/blockIdentityIcon').BlockIdentityItem} props.item
 */
function IdentityGlyph( { item } ) {
	const [ svg, setSvg ] = useState( () =>
		item.kind === 'lucide' ? cachedLucideIdentitySvg( item.value ) : ''
	);

	useEffect( () => {
		if ( item.kind !== 'lucide' ) {
			return undefined;
		}
		let cancelled = false;
		const cached = cachedLucideIdentitySvg( item.value );
		if ( cached ) {
			setSvg( cached );
			return undefined;
		}
		fetchLucideIdentitySvg( item.value ).then( ( next ) => {
			if ( ! cancelled ) {
				setSvg( next || '' );
			}
		} );
		return () => {
			cancelled = true;
		};
	}, [ item.kind, item.value ] );

	if ( item.kind === 'emoji' ) {
		return (
			<span className="bm-icon-picker__emoji" aria-hidden="true">
				{ item.value }
			</span>
		);
	}

	if ( item.kind === 'lucide' ) {
		const html =
			normalizeInlineSvg( svg ) ||
			'<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="3" opacity="0.25"/></svg>';
		return (
			<span
				className="bm-icon-picker__svg"
				aria-hidden="true"
				dangerouslySetInnerHTML={ { __html: html } }
			/>
		);
	}

	return (
		<span
			className={ `dashicons dashicons-${ item.value } bm-dashicon` }
			aria-hidden="true"
		/>
	);
}

/**
 * @param {object}   props
 * @param {string}   props.value
 * @param {Function} props.onChange
 * @param {string}   [props.label]
 */
export default function IconPicker( { value, onChange, label } ) {
	const current = normalizeBlockIdentityIcon( value || 'screenoptions' );
	const parsed = parseBlockIdentityIcon( current );
	const [ query, setQuery ] = useState( '' );
	const [ source, setSource ] = useState( 'all' );

	const catalog = useMemo( () => blockIdentityCatalog(), [] );

	const filtered = useMemo( () => {
		const q = query.trim().toLowerCase();
		return catalog.filter( ( item ) => {
			if ( source !== 'all' && item.kind !== source ) {
				return false;
			}
			if ( ! q ) {
				return true;
			}
			const hay = [ item.ref, item.label, ...item.keywords ]
				.join( ' ' )
				.toLowerCase();
			return hay.includes( q );
		} );
	}, [ catalog, query, source ] );

	const visible = useMemo( () => {
		if ( query.trim() || source === 'emoji' || source === 'dashicons' ) {
			return filtered;
		}
		if ( filtered.length > PREVIEW_LIMIT ) {
			return filtered.slice( 0, PREVIEW_LIMIT );
		}
		return filtered;
	}, [ filtered, query, source ] );

	const currentItem = useMemo( () => {
		const hit = catalog.find( ( item ) => item.ref === current );
		if ( hit ) {
			return hit;
		}
		if ( parsed?.kind === 'emoji' ) {
			return {
				kind: 'emoji',
				value: parsed.value,
				ref: current,
				label: parsed.value,
				keywords: [ 'emoji' ],
			};
		}
		if ( parsed?.kind === 'lucide' ) {
			return {
				kind: 'lucide',
				value: parsed.value,
				ref: current,
				label: parsed.value,
				keywords: [ 'lucide' ],
			};
		}
		return {
			kind: 'dashicons',
			value: parsed?.value || 'screenoptions',
			ref: parsed?.value || 'screenoptions',
			label: parsed?.value || 'screenoptions',
			keywords: [],
		};
	}, [ catalog, current, parsed ] );

	const filters = [
		{ id: 'all', label: __( 'All', 'joc-blockora-morph' ) },
		{ id: 'dashicons', label: __( 'Dashicons', 'joc-blockora-morph' ) },
		{ id: 'lucide', label: __( 'Lucide', 'joc-blockora-morph' ) },
		{ id: 'emoji', label: __( 'Emoji', 'joc-blockora-morph' ) },
	];

	return (
		<div className="bm-icon-picker">
			{ label ? (
				<span className="bm-icon-picker__label">{ label }</span>
			) : null }
			<div className="bm-icon-picker__current">
				<IdentityGlyph item={ currentItem } />
				<code>{ current }</code>
			</div>
			<input
				type="search"
				className="bm-icon-picker__search bm-field-input"
				value={ query }
				onChange={ ( e ) => setQuery( e.target.value ) }
				placeholder={ __(
					'Search icons…',
					'joc-blockora-morph'
				) }
				aria-label={ __( 'Search icons', 'joc-blockora-morph' ) }
			/>
			<div
				className="bm-icon-picker__filters"
				role="tablist"
				aria-label={ __( 'Icon source', 'joc-blockora-morph' ) }
			>
				{ filters.map( ( f ) => (
					<button
						key={ f.id }
						type="button"
						role="tab"
						aria-selected={ source === f.id }
						className={
							'bm-icon-picker__filter' +
							( source === f.id ? ' is-active' : '' )
						}
						onClick={ () => setSource( f.id ) }
					>
						{ f.label }
					</button>
				) ) }
			</div>
			<div
				className="bm-icon-picker__grid"
				role="listbox"
				aria-label={ label || __( 'Icons', 'joc-blockora-morph' ) }
			>
				{ visible.map( ( item ) => (
					<button
						key={ item.ref }
						type="button"
						role="option"
						aria-selected={ current === item.ref }
						title={ item.label }
						className={
							current === item.ref
								? 'bm-icon-picker__item is-active'
								: 'bm-icon-picker__item'
						}
						onClick={ () => onChange( item.ref ) }
					>
						<IdentityGlyph item={ item } />
					</button>
				) ) }
			</div>
			{ ! query.trim() &&
			( source === 'all' || source === 'lucide' ) &&
			filtered.length > visible.length ? (
				<p className="bm-icon-picker__hint">
					{ __(
						'Showing a preview — type to search the full Lucide set.',
						'joc-blockora-morph'
					) }
				</p>
			) : null }
		</div>
	);
}
