/**
 * Global Settings → General → Icons: branded library list.
 */
import { useEffect, useState } from '@wordpress/element';
import {
	Button,
	TextareaControl,
	TextControl,
	ToggleControl,
	SelectControl,
} from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import {
	defaultIconLibraries,
	ensureIconStylesheets,
} from '../../shared/iconRegistry';

/**
 * Built-in libraries that cannot be configured (URL, type, catalog, etc.).
 *
 * @param {string} id Library id.
 * @return {boolean}
 */
function isLockedIconLibrary( id ) {
	const key = String( id || '' ).toLowerCase();
	return key === 'dashicons' || key === 'lucide';
}

/**
 * @param {string} id
 * @param {string} label
 */
function libraryMark( id, label ) {
	const key = String( id || '' ).toLowerCase();
	if ( key === 'dashicons' ) {
		return { kind: 'dash', icon: 'wordpress', tone: 'dash' };
	}
	if ( key === 'lucide' ) {
		return { kind: 'text', text: 'Lu', tone: 'lucide' };
	}
	if ( key === 'fa' || key.startsWith( 'fa' ) ) {
		return { kind: 'text', text: 'FA', tone: 'fa' };
	}
	if ( key === 'material' || key.includes( 'material' ) ) {
		return { kind: 'text', text: 'MI', tone: 'material' };
	}
	const letter = String( label || id || '?' )
		.trim()
		.charAt( 0 )
		.toUpperCase();
	return { kind: 'text', text: letter || 'C', tone: 'custom' };
}

/**
 * @param {object} props
 * @param {Array} props.libraries
 * @param {Function} props.onChange
 * @param {boolean} props.saving
 * @param {Function} props.onSave
 */
export default function IconLibrariesPanel( {
	libraries,
	onChange,
	saving,
	onSave,
} ) {
	const list =
		Array.isArray( libraries ) && libraries.length
			? libraries
			: defaultIconLibraries();
	const [ expandedId, setExpandedId ] = useState( '' );
	const [ importError, setImportError ] = useState( '' );

	useEffect( () => {
		ensureIconStylesheets( list.filter( ( l ) => l.enabled ) );
	}, [ list ] );

	const updateLib = ( id, patch ) => {
		if ( isLockedIconLibrary( id ) ) {
			// Dashicons + Lucide: always on, not configurable.
			return;
		}
		onChange(
			list.map( ( lib ) =>
				lib.id === id ? { ...lib, ...patch } : lib
			)
		);
	};

	const addCustom = () => {
		const id = `custom-${ Date.now().toString( 36 ) }`;
		onChange( [
			...list,
			{
				id,
				label: __( 'Custom library', 'joc-blockora-morph' ),
				enabled: true,
				builtin: false,
				type: 'font-class',
				stylesheetUrl: '',
				classTemplate: 'my-icon my-icon-{id}',
				textContent: false,
				spriteUrl: '',
				catalog: [],
			},
		] );
		setExpandedId( id );
	};

	const removeLib = ( id ) => {
		if ( isLockedIconLibrary( id ) ) {
			return;
		}
		onChange( list.filter( ( lib ) => lib.id !== id || lib.builtin ) );
	};

	const importCatalog = ( id, raw ) => {
		if ( isLockedIconLibrary( id ) ) {
			return;
		}
		setImportError( '' );
		try {
			const parsed = JSON.parse( raw );
			const items = Array.isArray( parsed )
				? parsed
				: Array.isArray( parsed?.catalog )
				? parsed.catalog
				: null;
			if ( ! items ) {
				throw new Error( 'Expected a JSON array of { id, label }' );
			}
			const catalog = items
				.map( ( item ) => {
					const iconId = String( item?.id || '' )
						.trim()
						.replace( /[^a-z0-9_-]/gi, '' );
					if ( ! iconId ) {
						return null;
					}
					return {
						id: iconId,
						label: String( item.label || iconId ),
						keywords: Array.isArray( item.keywords )
							? item.keywords.map( String )
							: [],
					};
				} )
				.filter( Boolean );
			updateLib( id, { catalog } );
		} catch ( e ) {
			setImportError(
				e?.message ||
					__( 'Invalid catalog JSON.', 'joc-blockora-morph' )
			);
		}
	};

	const enabledCount = list.filter(
		( l ) => l.id === 'dashicons' || l.id === 'lucide' || l.enabled
	).length;

	return (
		<section className="bm-icons-panel">
			<div className="bm-icons-panel__banner">
				<div className="bm-icons-panel__banner-copy">
					<p className="bm-icons-panel__eyebrow">
						{ __( 'Content icons', 'joc-blockora-morph' ) }
					</p>
					<h2 className="bm-icons-panel__title">
						{ __( 'Icon libraries', 'joc-blockora-morph' ) }
					</h2>
					<p className="bm-icons-panel__lede">
						{ __(
							'Enable fonts for button and content pickers. Dashicons and Lucide are built-in and always on. Add a stylesheet URL for Font Awesome, Material, or a custom set. Gutenberg block icons (inserter identity) use a separate Dashicons + Lucide + emoji picker.',
							'joc-blockora-morph'
						) }
					</p>
				</div>
				<div className="bm-icons-panel__banner-aside">
					<div className="bm-icons-panel__stat">
						<span className="bm-icons-panel__stat-value">
							{ enabledCount }
						</span>
						<span className="bm-icons-panel__stat-label">
							{ __( 'enabled', 'joc-blockora-morph' ) }
						</span>
					</div>
					<div className="bm-icons-panel__actions">
						<button
							type="button"
							className="bm-btn bm-btn--ghost"
							onClick={ addCustom }
						>
							{ __( 'Add custom', 'joc-blockora-morph' ) }
						</button>
						<button
							type="button"
							className="bm-btn bm-btn--primary"
							onClick={ onSave }
							disabled={ saving }
						>
							{ saving
								? __( 'Saving…', 'joc-blockora-morph' )
								: __( 'Save icons', 'joc-blockora-morph' ) }
						</button>
					</div>
				</div>
			</div>

			<ul className="bm-icons-list">
				{ list.map( ( lib ) => {
					const locked = isLockedIconLibrary( lib.id );
					const open = ! locked && expandedId === lib.id;
					const mark = libraryMark( lib.id, lib.label );
					const count = Array.isArray( lib.catalog )
						? lib.catalog.length
						: 0;
					const hasSheet = Boolean(
						String( lib.stylesheetUrl || '' ).trim()
					);
					const isOn =
						lib.id === 'dashicons' ||
						lib.id === 'lucide' ||
						Boolean( lib.enabled );
					return (
						<li
							key={ lib.id }
							className={
								'bm-icons-lib' +
								( open ? ' is-open' : '' ) +
								( isOn ? ' is-enabled' : '' ) +
								( locked ? ' is-locked' : '' )
							}
						>
							<div className="bm-icons-lib__row">
								<div
									className={
										'bm-icons-lib__mark bm-icons-lib__mark--' +
										mark.tone
									}
									aria-hidden="true"
								>
									{ mark.kind === 'dash' ? (
										<span
											className={
												'dashicons dashicons-' +
												mark.icon
											}
										/>
									) : (
										<span>{ mark.text }</span>
									) }
								</div>

								<div className="bm-icons-lib__identity">
									<div className="bm-icons-lib__name-row">
										<strong className="bm-icons-lib__name">
											{ lib.label || lib.id }
										</strong>
										{ locked ? (
											<span className="bm-icons-lib__chip">
												{ __(
													'Built-in',
													'joc-blockora-morph'
												) }
											</span>
										) : lib.builtin ? (
											<span className="bm-icons-lib__chip">
												{ __(
													'Preset',
													'joc-blockora-morph'
												) }
											</span>
										) : (
											<span className="bm-icons-lib__chip bm-icons-lib__chip--custom">
												{ __(
													'Custom',
													'joc-blockora-morph'
												) }
											</span>
										) }
										<span
											className={
												'bm-icons-lib__chip' +
												( isOn
													? ' bm-icons-lib__chip--on'
													: ' bm-icons-lib__chip--off' )
											}
										>
											{ isOn
												? __(
														'On',
														'joc-blockora-morph'
												  )
												: __(
														'Off',
														'joc-blockora-morph'
												  ) }
										</span>
									</div>
									<p className="bm-icons-lib__summary">
										{ lib.id === 'dashicons'
											? __(
													'WordPress core — always on, not configurable',
													'joc-blockora-morph'
											  )
											: lib.id === 'lucide'
											? __(
													'Bundled SVG set — always on, not configurable',
													'joc-blockora-morph'
											  )
											: hasSheet
											? sprintf(
													/* translators: %d: catalog size */
													__(
														'%d icons in catalog',
														'joc-blockora-morph'
													),
													count
											  )
											: __(
													'Add a stylesheet URL, then Save',
													'joc-blockora-morph'
											  ) }
									</p>
								</div>

								<div className="bm-icons-lib__controls">
									<ToggleControl
										label={ __(
											'Enable',
											'joc-blockora-morph'
										) }
										checked={
											lib.id === 'dashicons' ||
											lib.id === 'lucide'
												? true
												: Boolean( lib.enabled )
										}
										disabled={
											lib.id === 'dashicons' ||
											lib.id === 'lucide'
										}
										help={
											lib.id === 'dashicons' ||
											lib.id === 'lucide'
												? __(
														'Always on',
														'joc-blockora-morph'
												  )
												: locked
												? __(
														'Not configurable',
														'joc-blockora-morph'
												  )
												: undefined
										}
										onChange={ ( next ) => {
											if (
												lib.id === 'dashicons' ||
												lib.id === 'lucide'
											) {
												return;
											}
											updateLib( lib.id, {
												enabled: Boolean( next ),
											} );
										} }
										__nextHasNoMarginBottom
									/>
									{ locked ? (
										<span
											className="bm-icons-lib__locked"
											title={ __(
												'This library cannot be configured',
												'joc-blockora-morph'
											) }
										>
											<span
												className="dashicons dashicons-lock"
												aria-hidden="true"
											/>
											<span className="screen-reader-text">
												{ __(
													'Not configurable',
													'joc-blockora-morph'
												) }
											</span>
										</span>
									) : (
										<button
											type="button"
											className={
												'bm-icons-lib__expand' +
												( open ? ' is-open' : '' )
											}
											aria-expanded={ open }
											onClick={ () =>
												setExpandedId(
													open ? '' : lib.id
												)
											}
										>
											{ open
												? __(
														'Close',
														'joc-blockora-morph'
												  )
												: __(
														'Configure',
														'joc-blockora-morph'
												  ) }
											<span
												className="dashicons dashicons-arrow-down-alt2"
												aria-hidden="true"
											/>
										</button>
									) }
								</div>
							</div>

							{ open ? (
								<div className="bm-icons-lib__body">
									<div className="bm-icons-lib__fields">
										<TextControl
											label={ __(
												'Label',
												'joc-blockora-morph'
											) }
											value={ lib.label || '' }
											onChange={ ( next ) =>
												updateLib( lib.id, {
													label: next,
												} )
											}
											__nextHasNoMarginBottom
											__next40pxDefaultSize
										/>
										<SelectControl
											label={ __(
												'Type',
												'joc-blockora-morph'
											) }
											value={ lib.type || 'font-class' }
											options={ [
												{
													label: 'Font / CSS class',
													value: 'font-class',
												},
												{
													label: 'SVG sprite',
													value: 'svg-sprite',
												},
												{
													label: 'SVG inline (PHP map)',
													value: 'svg-inline',
												},
												{
													label: 'CSS mask',
													value: 'css-mask',
												},
											] }
											onChange={ ( next ) =>
												updateLib( lib.id, {
													type: next,
												} )
											}
											__nextHasNoMarginBottom
											__next40pxDefaultSize
										/>
										<TextControl
											label={ __(
												'Stylesheet URL',
												'joc-blockora-morph'
											) }
											help={ __(
												'FA: all.min.css · Material: …/material-icons.min.css · Line Awesome: …/line-awesome.min.css',
												'joc-blockora-morph'
											) }
											value={ lib.stylesheetUrl || '' }
											onChange={ ( next ) => {
												const patch = {
													stylesheetUrl: next,
												};
												if (
													( lib.id === 'fa' ||
														lib.id ===
															'material' ) &&
													! String(
														next || ''
													).trim()
												) {
													patch.catalog = [];
												}
												updateLib( lib.id, patch );
											} }
											__nextHasNoMarginBottom
											__next40pxDefaultSize
										/>
										{ lib.type === 'svg-sprite' ? (
											<TextControl
												label={ __(
													'Sprite URL',
													'joc-blockora-morph'
												) }
												value={ lib.spriteUrl || '' }
												onChange={ ( next ) =>
													updateLib( lib.id, {
														spriteUrl: next,
													} )
												}
												__nextHasNoMarginBottom
												__next40pxDefaultSize
											/>
										) : lib.type === 'svg-inline' ? (
											<p className="bm-icons-lib__note">
												{ __(
													'Icons live in a PHP map and are inlined only when used on the page — nothing heavy is enqueued up front.',
													'joc-blockora-morph'
												) }
											</p>
										) : (
											<TextControl
												label={ __(
													'Class template',
													'joc-blockora-morph'
												) }
												help={ __(
													'FA: fa-solid fa-{id} · Line Awesome: las la-{id} · Material: material-icons + ligature text',
													'joc-blockora-morph'
												) }
												value={
													lib.classTemplate || ''
												}
												onChange={ ( next ) =>
													updateLib( lib.id, {
														classTemplate: next,
													} )
												}
												__nextHasNoMarginBottom
												__next40pxDefaultSize
											/>
										) }
									</div>

									{ lib.type === 'font-class' ? (
										<ToggleControl
											label={ __(
												'Put icon id as text (Material ligatures)',
												'joc-blockora-morph'
											) }
											help={
												lib.textContent
													? __(
															'Save loads the icon list from package metadata when available.',
															'joc-blockora-morph'
													  )
													: undefined
											}
											checked={ Boolean(
												lib.textContent
											) }
											onChange={ ( next ) =>
												updateLib( lib.id, {
													textContent:
														Boolean( next ),
												} )
											}
											__nextHasNoMarginBottom
										/>
									) : null }

									<div className="bm-icons-lib__catalog-bar">
										<span>
											{ sprintf(
												/* translators: %d: catalog size */
												__(
													'%d icons stored',
													'joc-blockora-morph'
												),
												count
											) }
										</span>
										<span>
											{ __(
												'Catalog refreshes on Save when the URL or template changes.',
												'joc-blockora-morph'
											) }
										</span>
									</div>

									<CatalogImport
										onImport={ ( raw ) =>
											importCatalog( lib.id, raw )
										}
									/>
									{ importError &&
									expandedId === lib.id ? (
										<p className="bm-icons-lib__error">
											{ importError }
										</p>
									) : null }
									{ ! lib.builtin ? (
										<button
											type="button"
											className="bm-icons-lib__remove"
											onClick={ () =>
												removeLib( lib.id )
											}
										>
											{ __(
												'Remove library',
												'joc-blockora-morph'
											) }
										</button>
									) : null }
								</div>
							) : null }
						</li>
					);
				} ) }
			</ul>
		</section>
	);
}

function CatalogImport( { onImport } ) {
	const [ raw, setRaw ] = useState( '' );
	const [ open, setOpen ] = useState( false );
	if ( ! open ) {
		return (
			<p className="bm-icons-lib__note">
				<button
					type="button"
					className="bm-icons-lib__linkish"
					onClick={ () => setOpen( true ) }
				>
					{ __(
						'Or import catalog JSON manually…',
						'joc-blockora-morph'
					) }
				</button>
			</p>
		);
	}
	return (
		<div className="bm-icons-lib__import">
			<TextareaControl
				label={ __( 'Import catalog JSON', 'joc-blockora-morph' ) }
				help={ __(
					'Paste [{ "id": "house", "label": "House", "keywords": ["home"] }, …]',
					'joc-blockora-morph'
				) }
				value={ raw }
				onChange={ setRaw }
				rows={ 4 }
			/>
			<div className="bm-icons-panel__actions">
				<Button
					variant="secondary"
					disabled={ ! raw.trim() }
					onClick={ () => {
						onImport( raw );
						setRaw( '' );
					} }
				>
					{ __( 'Import catalog', 'joc-blockora-morph' ) }
				</Button>
				<Button variant="tertiary" onClick={ () => setOpen( false ) }>
					{ __( 'Hide', 'joc-blockora-morph' ) }
				</Button>
			</div>
		</div>
	);
}
