import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { Button, Flex, FlexItem, Notice, SelectControl } from '@wordpress/components';
import { MediaUpload, MediaUploadCheck, PanelColorSettings } from '@wordpress/block-editor';
import IconLibraryModal from './IconLibraryModal';
import { iconLibrary } from '../../icons';
import ReactDOMServer from 'react-dom/server';
import {
	createEffectDefault,
	createInsetDefault,
	createResponsiveValueDefault,
	sanitizeSvg,
} from './iconUtils';

const IconSettings = ( {
	attributes,
	setAttributes,
	showPosition = true,
	activeStyleTab = 'icon',
	showLibraryControls = true,
	showColorControls = true,
	showReset = true,
	showPreview = true,
	resetMode = 'all',
	browseButtonLabel,
	uploadButtonLabel,
	helpText,
	previewLabel,
} ) => {
	const {
		iconType,
		iconName,
		iconCategory,
		customIcon,
		iconSvg,
		iconColor,
		iconColor__hover,
		iconLocation,
	} = attributes;

	const [ isModalOpen, setModalOpen ] = useState( false );
	const [ uploadError, setUploadError ] = useState( '' );
	const [ isUploading, setIsUploading ] = useState( false );
	const isHoverTab = activeStyleTab === 'iconHover';
	const previewSvg = customIcon || iconSvg || '';

	const hasValidIcon =
		( iconType === 'library' &&
			iconCategory &&
			iconName &&
			iconLibrary[ iconCategory ]?.[ iconName ] ) ||
		( iconType === 'custom' &&
			previewSvg &&
			previewSvg.includes( '<svg' ) ) ||
		( previewSvg &&
			previewSvg.includes( '<svg' ) );

	const resetIconSettings = () => {
		setUploadError( '' );
		const selectionReset = {
			iconType: '',
			iconName: '',
			iconCategory: '',
			customIcon: '',
			iconSvg: '',
		};

		if ( resetMode === 'selection' ) {
			setAttributes( selectionReset );
			return;
		}

		setAttributes( {
			...selectionReset,
			iconColor: '',
			iconColor__hover: '',
			iconLocation: 'before',
			iconSize: createResponsiveValueDefault(),
			iconSize__hover: createResponsiveValueDefault(),
			iconPosition: createResponsiveValueDefault(),
			iconPosition__hover: createResponsiveValueDefault(),
			iconInset: createInsetDefault(),
			iconInset__hover: createInsetDefault(),
			iconOverflowX: createResponsiveValueDefault(),
			iconOverflowX__hover: createResponsiveValueDefault(),
			iconOverflowY: createResponsiveValueDefault(),
			iconOverflowY__hover: createResponsiveValueDefault(),
			iconZIndex: createResponsiveValueDefault(),
			iconZIndex__hover: createResponsiveValueDefault(),
			iconEffect: createEffectDefault(),
			iconEffect__hover: createEffectDefault(),
		} );
	};

	const getPreviewColor = isHoverTab ? iconColor__hover || iconColor : iconColor;

	const getIconPreview = () => {
		if ( iconType === 'library' && iconCategory && iconName ) {
			const IconComponent = iconLibrary[ iconCategory ]?.[ iconName ];
			return IconComponent ? (
				<span style={ { color: getPreviewColor } }>
					<IconComponent />
				</span>
			) : null;
		}

		if ( previewSvg && previewSvg.includes( '<svg' ) ) {
			const safeSvg = sanitizeSvg( previewSvg );

			if ( ! safeSvg ) {
				return null;
			}

			return (
				<span
					className="axcelersblocks-custom-icon-preview inline"
					style={ { color: getPreviewColor } }
					dangerouslySetInnerHTML={ { __html: safeSvg } }
				/>
			);
		}

		return null;
	};

	const iconPreview = getIconPreview();
	const selectedIconLabel =
		iconType === 'library' && iconName
			? iconName
			: previewSvg && previewSvg.includes( '<svg' )
				? __( 'Custom SVG', 'axcelersblocks' )
				: '';

	const handleIconUpload = async ( media ) => {
		if ( ! media?.url ) {
			return;
		}

		setUploadError( '' );
		setIsUploading( true );

		try {
			const isSvgAsset =
				media.mime === 'image/svg+xml' ||
				media.subtype === 'svg+xml' ||
				( typeof media.url === 'string' &&
					media.url.toLowerCase().includes( '.svg' ) );

			if ( ! isSvgAsset ) {
				throw new Error( __( 'Please choose an SVG file for icon upload.', 'axcelersblocks' ) );
			}

			const response = await window.fetch( media.url, { credentials: 'same-origin' } );

			if ( ! response.ok ) {
				throw new Error( __( 'Unable to load the uploaded SVG file.', 'axcelersblocks' ) );
			}

			const rawSvg = await response.text();
			const safeSvg = sanitizeSvg( rawSvg );

			if ( ! safeSvg ) {
				throw new Error( __( 'The uploaded file does not contain valid SVG markup.', 'axcelersblocks' ) );
			}

			setAttributes( {
				iconType: 'custom',
				customIcon: safeSvg,
				iconSvg: safeSvg,
				iconName: '',
				iconCategory: '',
			} );
		} catch ( error ) {
			setUploadError(
				error?.message || __( 'Icon upload failed. Please try another SVG.', 'axcelersblocks' )
			);
		} finally {
			setIsUploading( false );
		}
	};

	return (
		<>
			{ showLibraryControls && (
				<>
					<Flex
						align="center"
						justify="space-between"
						className="icon-library-select"
					>
						<FlexItem>
							<Button variant="secondary" onClick={ () => setModalOpen( true ) }>
								{ iconPreview } { browseButtonLabel || __( 'Browse Icon', 'axcelersblocks' ) }
							</Button>
						</FlexItem>
						<FlexItem>
							<MediaUploadCheck>
								<MediaUpload
									onSelect={ handleIconUpload }
									allowedTypes={ [ 'image' ] }
									render={ ( { open } ) => (
										<Button
											variant="secondary"
											onClick={ open }
											isBusy={ isUploading }
										>
											{ uploadButtonLabel || __( 'Upload SVG', 'axcelersblocks' ) }
										</Button>
									) }
								/>
							</MediaUploadCheck>
						</FlexItem>
					</Flex>

					<p className="components-base-control__help">
						{ helpText || __( 'Upload an SVG file or paste SVG markup to use a custom icon.', 'axcelersblocks' ) }
					</p>

					{ uploadError && (
						<Notice status="error" isDismissible={ false }>
							{ uploadError }
						</Notice>
					) }
				</>
			) }

			<IconLibraryModal
				isOpen={ isModalOpen }
				onClose={ () => setModalOpen( false ) }
				onSelect={ ( data ) => {
					setUploadError( '' );
					if ( data.type === 'custom' ) {
						setAttributes( {
							iconType: 'custom',
							customIcon: data.svg,
							iconSvg: data.svg,
							iconName: '',
							iconCategory: '',
						} );
					} else if ( data.type === 'library' && data.name && data.category ) {
						const IconComponent = iconLibrary[ data.category ]?.[ data.name ];
						const svgString = IconComponent
							? ReactDOMServer.renderToStaticMarkup( <IconComponent /> )
							: '';

						setAttributes( {
							iconType: 'library',
							iconName: data.name,
							iconCategory: data.category,
							customIcon: '',
							iconSvg: svgString,
						} );
					} else {
						setAttributes( {
							iconType: '',
							iconName: '',
							iconCategory: '',
							customIcon: '',
							iconSvg: '',
						} );
					}
				} }
				initialValue={ {
					type: iconType || ( previewSvg ? 'custom' : '' ),
					name: iconName,
					category: iconCategory,
					svg: customIcon || iconSvg || '',
				} }
			/>

			{ hasValidIcon && (
				<>
					{ showColorControls && (
						<PanelColorSettings
							title={ __( 'Icon Colors', 'axcelersblocks' ) }
							initialOpen={ false }
							className="icon-color-picker"
							colorSettings={ [
								{
									value: isHoverTab ? iconColor__hover : iconColor,
									onChange: ( color ) =>
										setAttributes(
											isHoverTab
												? { iconColor__hover: color }
												: { iconColor: color }
										),
									label: isHoverTab
										? __( 'Hover Color', 'axcelersblocks' )
										: __( 'Default Color', 'axcelersblocks' ),
								},
							] }
						/>
					) }

					{ showPosition && (
						<SelectControl
							label={ __( 'Icon Position', 'axcelersblocks' ) }
							value={ iconLocation }
							options={ [
								{
									label: __( 'Before', 'axcelersblocks' ),
									value: 'before',
								},
								{
									label: __( 'After', 'axcelersblocks' ),
									value: 'after',
								},
							] }
							onChange={ ( value ) =>
								setAttributes( { iconLocation: value } )
							}
						/>
					) }
				</>
			) }

			{ showReset && (
				<Button
					className="reset-btn"
					onClick={ resetIconSettings }
					label={ __( 'Reset', 'axcelersblocks' ) }
					showTooltip={ true }
				>
					{ __( 'Reset', 'axcelersblocks' ) }
				</Button>
			) }
		</>
	);
};

export default IconSettings;
