import { __ } from '@wordpress/i18n';
import {
	PanelBody,
	SelectControl,
	ToggleControl,
	RangeControl,
	__experimentalToggleGroupControl as ToggleGroupControl,
	__experimentalToggleGroupControlOption as ToggleGroupControlOption,
	__experimentalNumberControl as NumberControl,
	Spinner,
	Notice,
	FormTokenField,
	BaseControl,
} from '@wordpress/components';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { useRef, useEffect, useMemo } from "@wordpress/element";
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import ServerSideRender from '@wordpress/server-side-render';
import AnimationControls from '../components/animations/AnimationControl';
import AnimatedBlockWrapper from '../components/animations/AnimatedBlockWrapper';
import { ReorderableMultiSelect } from '../components/ReorderableMultiSelect';
import BorderPanel from "../components/BorderPanel/BorderPanel";
import { initSwiper } from "../../../assets/js/slider";
import VisibilityControls from "../components/visibility/VisibilityControls";
import {getVisibilityClasses} from "../components/blockStyleUtils";

const ELEMENT_OPTIONS = [
	{ key: 'title', label: __('Title', 'lead-gen') },
	{ key: 'categories', label: __('Categories', 'lead-gen') },
	{ key: 'meta', label: __('Meta', 'lead-gen') },
	{ key: 'content', label: __('Content', 'lead-gen') },
	{ key: 'image', label: __('Image', 'lead-gen') },
	{ key: 'read_more', label: __('Read More', 'lead-gen') },
];

const META_ITEMS_OPTIONS = [
	{ key: 'author', label: __('Author', 'lead-gen') },
	{ key: 'date', label: __('Date', 'lead-gen') },
	{ key: 'date_time', label: __('Date/Time', 'lead-gen') },
	{ key: 'reading_time', label: __('Reading Time', 'lead-gen') },
];

const Edit = ({ name, attributes, setAttributes }) => {
	const {
		layout,
		elements,
		metaItems,
		excerptLength,
		columns,
		customQuery,
		postType,
		taxonomy = '',
		terms = [],
		numberOfPosts,
		titleHtmlTag,
		imagePlacement,
		pagination,
		sliderControls,
		animationEntrance,
		animationDuration,
		animationDelay,
	} = attributes;

	const blockProps = useBlockProps();

	const wrapperRef = useRef(null);

	useEffect(() => {
		if (layout !== 'slider') return;
		if (!wrapperRef.current) return;
		const observer = new MutationObserver(() => {
			const slider = wrapperRef.current.querySelector('.posts__slider-wrapper');
			if (slider && !slider.dataset.initialized) {
				initSwiper( slider, { allowTouchMove: false } );
				slider.dataset.initialized = '1';
			}
		});

		observer.observe(wrapperRef.current, {
			childList: true,
			subtree: true,
		});

		return () => observer.disconnect();
	}, []);

	// Post types
	const { postTypes = [], hasResolvedPostTypes } = useSelect((select) => {
		const core = select(coreStore);
		const args = { per_page: -1 };
		return {
			postTypes: core.getPostTypes(args) || [],
			hasResolvedPostTypes: core.hasFinishedResolution('getPostTypes', [args]),
		};
	}, []);

	const postTypeOptions = useMemo(() => {
		return postTypes
			.filter((pt) => pt?.viewable && pt?.slug !== 'attachment')
			.map((pt) => ({
				label: pt?.labels?.singular_name || pt?.name || pt?.slug,
				value: pt?.slug,
			}));
	}, [postTypes]);

	const { taxonomies = [], hasResolvedTaxonomies } = useSelect(
		(select) => {
			const core = select(coreStore);
			const args = { type: postType || 'post', per_page: -1, context: 'view' };
			return {
				taxonomies: core.getTaxonomies(args) || [],
				hasResolvedTaxonomies: core.hasFinishedResolution('getTaxonomies', [args]),
			};
		},
		[postType],
	);

	const taxonomyOptions = useMemo(() => {
		return (taxonomies || [])
			.filter((tx) => tx?.show_ui !== false)
			.map((tx) => ({
				label: tx?.labels?.singular_name || tx?.name || tx?.slug,
				value: tx?.slug,
			}));
	}, [taxonomies]);

	// Terms for the chosen taxonomy
	const { termsList = [], hasResolvedTerms } = useSelect(
		(select) => {
			if (!taxonomy) return { termsList: [], hasResolvedTerms: true };
			const core = select(coreStore);
			const query = { per_page: 100, hide_empty: false };
			return {
				termsList: core.getEntityRecords('taxonomy', taxonomy, query) || [],
				hasResolvedTerms: core.hasFinishedResolution('getEntityRecords', [
					'taxonomy',
					taxonomy,
					query,
				]),
			};
		},
		[taxonomy],
	);

	// Build maps for the token field
	const termIdToName = useMemo(() => {
		const map = new Map();
		termsList.forEach((t) => map.set(t.id, t.name));
		return map;
	}, [termsList]);

	const nameToTermId = useMemo(() => {
		const map = new Map();
		termsList.forEach((t) => map.set(t.name, t.id));
		return map;
	}, [termsList]);

	const termNameSuggestions = useMemo(() => termsList.map((t) => t.name), [termsList]);

	const selectedTokens = useMemo(() => {
		terms.map((id) => termIdToName.get(id)).filter(Boolean)
	}, [terms, termIdToName]);

	const wrapperClassName = [
		'lg-block lg-block__posts posts',
		layout === 'grid'
			? `posts__grid posts__grid--${columns} posts__img--${imagePlacement}`
			: `posts__img--${imagePlacement}`,
		getVisibilityClasses(attributes),
	].join(' ');

	return (
		<AnimatedBlockWrapper
			animationEntrance={animationEntrance}
			animationDuration={animationDuration}
			animationDelay={animationDelay}
			attributes={attributes}
			{...blockProps}
			className={wrapperClassName}
		>
			<InspectorControls>
				<PanelBody title={__('Layout', 'lead-gen')} initialOpen>
					<ToggleGroupControl
						label={__('Layout Type', 'lead-gen')}
						value={layout}
						isBlock
						__nextHasNoMarginBottom
						__next40pxDefaultSize
						onChange={(val) => setAttributes({ layout: val })}
					>
						<ToggleGroupControlOption value="grid" label="Grid" />
						<ToggleGroupControlOption value="list" label="List" />
						<ToggleGroupControlOption value="slider" label="Slider" />
					</ToggleGroupControl>
					{layout !== 'list' && (
						<RangeControl
							label={__(
								layout === 'grid' ? 'Columns' : 'Slides Per View',
								'lead-gen'
							)}
							value={columns}
							onChange={(val) => setAttributes({ columns: val })}
							min={1}
							max={6}
						/>
					)}
					{layout !== 'slider' && (
						<ToggleControl
							label={__('Pagination', 'lead-gen')}
							checked={pagination}
							onChange={(val) => setAttributes({ pagination: val })}
						/>
					)}
					{layout === 'slider' && (
						<ToggleControl
							label={__('Slider Controls', 'lead-gen')}
							checked={sliderControls}
							onChange={(val) => setAttributes({ sliderControls: val })}
						/>
					)}
				</PanelBody>
				<PanelBody title={__('Query', 'lead-gen')}>
					<ToggleControl
						label={__('Custom Query', 'lead-gen')}
						checked={customQuery}
						onChange={(val) => setAttributes({ customQuery: val })}
					/>
					{customQuery ? (
						<>
							<SelectControl
								label={__('Post Type', 'lead-gen')}
								value={postType || 'post'}
								options={
									postTypeOptions.length
										? postTypeOptions
										: [
											{ label: __('Posts', 'lead-gen'), value: 'post' },
											{ label: __('Pages', 'lead-gen'), value: 'page' },
										]
								}
								onChange={(val) => {
									setAttributes({
										postType: val,
										taxonomy: '',
										terms: [],
									});
								}}
								disabled={!hasResolvedPostTypes}
								help={!hasResolvedPostTypes ? __('Loading post types…', 'lead-gen') : undefined}
							/>
							<SelectControl
								label={__('Taxonomy', 'lead-gen')}
								value={taxonomy}
								options={[
									{ label: __('Select a taxonomy', 'lead-gen'), value: '' },
									...taxonomyOptions,
								]}
								onChange={(val) => setAttributes({ taxonomy: val, terms: [] })}
								disabled={!hasResolvedTaxonomies}
								help={!hasResolvedTaxonomies ? __('Loading taxonomies…', 'lead-gen') : undefined}
							/>
							{taxonomy ? (
								<div className="lg-taxonomy-terms">
									{!hasResolvedTerms && <Spinner />}
									{hasResolvedTerms && termsList.length === 0 && (
										<Notice status="info" isDismissible={false}>
											{__('No terms found for this taxonomy', 'lead-gen')}
										</Notice>
									)}
									{hasResolvedTerms && termsList.length > 0 && (
										<FormTokenField
											label={__('Terms', 'lead-gen')}
											value={selectedTokens}
											suggestions={termNameSuggestions}
											__experimentalShowHowTo={false}
											onChange={(tokens) => {
												// Map token names to IDs, ignore unknown tokens
												const ids = tokens
													.map((name) => nameToTermId.get(name))
													.filter((id) => typeof id === 'number');
												// Deduplicate
												const unique = Array.from(new Set(ids));
												setAttributes({ terms: unique });
											}}
											// Optional; keeps suggestions filtered as you type
											onInputChange={() => { }}
											// Allow only from suggestions
											tokenizeOnSpace
										/>
									)}
								</div>
							) : null}
							<RangeControl
								label={__('Number of Posts', 'lead-gen')}
								value={numberOfPosts}
								onChange={(val) => setAttributes({ numberOfPosts: val })}
								min={1}
								max={20}
							/>
						</>
					) : null}
				</PanelBody>
				<PanelBody title={__('Post Settings', 'lead-gen')}>
					<BaseControl label="Order of Elements">
						<ReorderableMultiSelect
							options={ELEMENT_OPTIONS}
							selectedKeys={elements}
							onChangeSelected={(next) => setAttributes({ elements: next })}
						/>
					</BaseControl>
					{elements.includes('image') ? (
						<ToggleGroupControl
							label={__('Image Placement', 'lead-gen')}
							value={imagePlacement}
							isBlock
							__nextHasNoMarginBottom
							__next40pxDefaultSize
							onChange={(val) => setAttributes({ imagePlacement: val })}
						>
							<ToggleGroupControlOption value="none" label="None" />
							<ToggleGroupControlOption value="top" label="Top" />
							<ToggleGroupControlOption value="left" label="Left" />
							<ToggleGroupControlOption value="right" label="Right" />
						</ToggleGroupControl>
					) : null}
					{elements.includes('title') ? (
						<ToggleGroupControl
							label={__('Title HTML Tag', 'lead-gen')}
							value={titleHtmlTag}
							isBlock
							__nextHasNoMarginBottom
							__next40pxDefaultSize
							onChange={(val) => setAttributes({ titleHtmlTag: val })}
						>
							<ToggleGroupControlOption value="h1" label="H1" />
							<ToggleGroupControlOption value="h2" label="H2" />
							<ToggleGroupControlOption value="h3" label="H3" />
							<ToggleGroupControlOption value="h4" label="H4" />
							<ToggleGroupControlOption value="h5" label="H5" />
							<ToggleGroupControlOption value="h6" label="H6" />
						</ToggleGroupControl>
					) : null}
					{elements.includes('content') ? (
						<NumberControl
							label={__('Excerpt Length', 'lead-gen')}
							__next40pxDefaultSize
							isShiftStepEnabled
							onChange={(val) => setAttributes({ excerptLength: val })}
							shiftStep={1}
							value={excerptLength}
						/>
					) : null}
					{elements.includes('meta') ? (
						<BaseControl label="Order of Meta Elements">
							<ReorderableMultiSelect
								options={META_ITEMS_OPTIONS}
								selectedKeys={metaItems}
								onChangeSelected={(next) => setAttributes({ metaItems: next })}
							/>
						</BaseControl>
					) : null}
				</PanelBody>

				<BorderPanel
					attributes={attributes}
					setAttributes={setAttributes}
				/>
				<VisibilityControls attributes={attributes} setAttributes={setAttributes} />
				<AnimationControls attributes={attributes} setAttributes={setAttributes} />
			</InspectorControls>
			<div ref={wrapperRef}>
				<ServerSideRender block={name} attributes={attributes} />
			</div>
		</AnimatedBlockWrapper>
	);
};

export default Edit;
