import { useEffect, useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { api } from '../api';
import PreviewModal from '../components/PreviewModal';
import LibraryCardThumb from '../components/LibraryCardThumb';
import LibrarySkeleton from '../components/LibrarySkeleton';
import { useLibraryFilter } from '../components/LibraryFilterContext';
import BlocksListFilters, {
	categoryOptionsFromTree,
	blockMatchesCategory,
} from '../components/BlocksListFilters';
import { isProActive } from '../extensibility';
import { refreshButtonLibrary } from '../../shared/buttonLibrary';

function tagTone( slug = '' ) {
	const key = String( slug ).toLowerCase();
	if ( /hero|landing/.test( key ) ) {
		return 'primary';
	}
	if ( /shop|commerce|product|store/.test( key ) ) {
		return 'success';
	}
	if ( /social|testimonial|proof/.test( key ) ) {
		return 'secondary';
	}
	if ( /form|checkout|contact/.test( key ) ) {
		return 'warning';
	}
	if ( /nav|header|menu/.test( key ) ) {
		return 'tertiary';
	}
	const tones = [ 'primary', 'success', 'secondary', 'warning', 'tertiary', 'muted' ];
	let hash = 0;
	for ( let i = 0; i < key.length; i++ ) {
		hash = ( hash + key.charCodeAt( i ) * ( i + 1 ) ) % tones.length;
	}
	return tones[ hash ];
}

function isProLocked( block ) {
	return Boolean( block?.isPro ) && ! isProActive();
}

export default function Library( { onNavigate } ) {
	const { activeCat, setActiveCat, categories, categoryTree, featuredCount } =
		useLibraryFilter();
	const [ blocks, setBlocks ] = useState( [] );
	const [ query, setQuery ] = useState( '' );
	const [ selected, setSelected ] = useState( null );
	const [ loading, setLoading ] = useState( true );
	const [ importing, setImporting ] = useState( false );

	useEffect( () => {
		api.get( '/system-blocks' )
			.then( ( blks ) => {
				setBlocks( blks.items || [] );
			} )
			.finally( () => setLoading( false ) );
	}, [] );

	const categoryOptions = useMemo(
		() =>
			categoryOptionsFromTree( categoryTree, {
				includeFeatured: featuredCount > 0,
			} ),
		[ categoryTree, featuredCount ]
	);

	const filtered = useMemo( () => {
		const q = query.trim().toLowerCase();
		return blocks
			.filter( ( b ) => {
				if ( activeCat === 'featured' ) {
					if ( ! b.isFeatured ) {
						return false;
					}
				} else if ( activeCat !== 'all' ) {
					if ( ! blockMatchesCategory( b, activeCat ) ) {
						return false;
					}
				}
				if ( ! q ) {
					return true;
				}
				const hay = `${ b.name || '' } ${ b.description || '' } ${ b.categoryName || '' } ${ ( b.categorySlugs || [] ).join( ' ' ) } ${ b.variant || '' }`.toLowerCase();
				return hay.includes( q );
			} )
			.sort( ( a, b ) => {
				const byName = String( a.name || '' ).localeCompare(
					String( b.name || '' ),
					undefined,
					{ sensitivity: 'base' }
				);
				if ( byName !== 0 ) {
					return byName;
				}
				return String( a.variant || '' ).localeCompare(
					String( b.variant || '' ),
					undefined,
					{ sensitivity: 'base' }
				);
			} );
	}, [ blocks, activeCat, query ] );

	const onImport = async ( block, { name, icon } ) => {
		setImporting( true );
		try {
			const payload = {
				name,
				icon,
				cssVars: block.cssVars,
				defaultAttrs: block.defaultAttrs,
				postTypes: [ 'post', 'page' ],
			};
			if ( block.ownerPack || block.ownerSlug ) {
				payload.ownerSlug = block.ownerSlug || block.slug;
				payload.ownerVariant = block.ownerVariant || block.variant || 'default';
			} else {
				payload.systemBlockId = block.id;
			}
			const created = await api.post( '/user-blocks', payload );
			await refreshButtonLibrary();
			setSelected( null );
			onNavigate( `editor/${ created.id }`, { userBlock: created } );
		} catch ( e ) {
			window.alert( e?.message || __( 'Import failed.', 'joc-blockora-morph' ) );
		}
		setImporting( false );
	};

	const clearFilters = () => {
		setQuery( '' );
		setActiveCat( 'all' );
	};

	const activeLabel =
		activeCat === 'all'
			? __( 'All categories', 'joc-blockora-morph' )
			: activeCat === 'featured'
				? __( 'Featured', 'joc-blockora-morph' )
				: categories.find( ( c ) => c.slug === activeCat )?.name ||
				  categoryTree?.find( ( c ) => c.slug === activeCat )?.name ||
				  categoryOptions.find( ( o ) => o.value === activeCat )?.label ||
				  activeCat;

	return (
		<div className="bm-rise mx-auto w-full max-w-canvas px-gutter py-stack-lg font-sans">
			<header className="mb-stack-md space-y-1">
				<h1 className="text-display-sm text-on-background">
					{ __( 'JBM Library', 'joc-blockora-morph' ) }
				</h1>
				<p className="max-w-lg text-body-lg text-on-surface-variant">
					{ __(
						'Discover and deploy high-fidelity components designed for high-conversion web experiences.',
						'joc-blockora-morph'
					) }
				</p>
			</header>

			{ ! loading ? (
				<BlocksListFilters
					query={ query }
					onQueryChange={ setQuery }
					category={ activeCat }
					onCategoryChange={ setActiveCat }
					categoryOptions={ categoryOptions }
					searchPlaceholder={ __( 'Search templates…', 'joc-blockora-morph' ) }
					resultCount={ filtered.length }
					totalCount={ blocks.length }
					activeLabel={ activeLabel }
					onClear={ clearFilters }
				/>
			) : null }

			{ loading ? (
				<LibrarySkeleton variant="grid" count={ 6 } />
			) : (
			<div className="bm-lib-grid">
				{ filtered.map( ( block ) => {
						const tone = tagTone( block.categorySlug );
						const locked = isProLocked( block );
						return (
							<button
								key={ block.id }
								type="button"
								className="bm-bento bento-card bm-lib-card group w-full text-left"
								onClick={ () => setSelected( block ) }
							>
								<div className="bm-lib-card__media">
									<LibraryCardThumb block={ block } />
									<div
										className="bm-lib-card__scrim"
										aria-hidden="true"
									/>
									<div className="bm-lib-card__overlay">
										<span className="bm-lib-card__preview-btn">
											<span
												className="dashicons dashicons-visibility"
												aria-hidden="true"
											/>
											{ __( 'Preview', 'joc-blockora-morph' ) }
										</span>
									</div>
									<span
										className={ `bm-lib-card__badge is-${ tone }` }
									>
										{ block.categoryName }
									</span>
									{ ( block.categorySlugs || [] )
										.filter(
											( s ) =>
												s &&
												s !== block.categorySlug
										)
										.slice( 0, 2 )
										.map( ( slug ) => (
											<span
												key={ slug }
												className={ `bm-lib-card__badge is-${ tagTone(
													slug
												) }` }
											>
												{ slug }
											</span>
										) ) }
									{ block.isPro && (
										<span className="bm-lib-card__pro">
											{ __( 'Pro', 'joc-blockora-morph' ) }
										</span>
									) }
								</div>
								<div className="bm-lib-card__body">
									<h3 className="bm-lib-card__title">
										{ block.name }
									</h3>
									<p className="bm-lib-card__desc">
										{ block.description }
									</p>
									<div className="bm-lib-card__meta">
										<span className="bm-lib-card__variant">
											{ block.variant }
										</span>
										{ locked ? (
											<span className="bm-lib-card__status is-locked">
												<span
													className="dashicons dashicons-lock"
													aria-hidden="true"
												/>
												{ __( 'Pro required', 'joc-blockora-morph' ) }
											</span>
										) : (
											<span className="bm-lib-card__status is-ready">
												<span
													className="dashicons dashicons-yes-alt"
													aria-hidden="true"
												/>
												{ __( 'Import ready', 'joc-blockora-morph' ) }
											</span>
										) }
									</div>
								</div>
							</button>
						);
					} ) }
				{ filtered.length === 0 && (
					<p className="col-span-full text-body-md text-on-surface-variant">
						{ __( 'No blocks match your filters.', 'joc-blockora-morph' ) }
					</p>
				) }
			</div>
			) }

			{ selected && (
				<PreviewModal
					block={ selected }
					importing={ importing }
					browseList={ filtered }
					onBrowseSelect={ setSelected }
					onClose={ () => ( importing ? null : setSelected( null ) ) }
					onImport={ onImport }
				/>
			) }
		</div>
	);
}
