import { __ } from '@wordpress/i18n';
import { Button, ColorPicker, Dropdown, PanelBody } from '@wordpress/components';
import { rotateRight } from '@wordpress/icons';
import TypographyControl from '../Typography';
import BackgroundControl from '../Background';
import BorderControl from '../Border';
import SpacingControls from '../Spacing';
import EffectControl from '../Effect';
import UnitValueControl from '../../controls/UnitValueControl';
import { useDevice } from '../../controls/DeviceContext';
import OutlineIcon from '../icons/OutlineIcon';
import {
	createEffectDefault,
	createResponsiveValueDefault,
	createLayersDefault,
	createBorderDefault,
	createBorderRadiusDefault,
	createSpacingDefault,
} from '../../settings/iconUtils';

const cap = ( s ) => s.charAt( 0 ).toUpperCase() + s.slice( 1 );
export const createOutlineDeviceDefault = () => ( { width: '', style: 'none', color: '', sides: {}, isLinkActive: true } );
export const createOutlineDefault = () => ( {
	desktop: createOutlineDeviceDefault(),
	tablet: createOutlineDeviceDefault(),
	mobile: createOutlineDeviceDefault(),
} );

// Reusable outline control (width / style / color + offset). Operates on generic
// `outline` and `outlineOffset` keys of whatever attributes/setter it receives, so
// it works for any namespace (link states, button states, …) via a remap wrapper.
export function OutlineControls( { attributes, setAttributes } ) {
	const { activeDevice } = useDevice();
	const outline = attributes.outline || createOutlineDefault();
	const outlineOffset = attributes.outlineOffset || createResponsiveValueDefault();
	const deviceVal = outline[ activeDevice ] || createOutlineDeviceDefault();
	const styles = [
		{ label: __( 'None', 'axcelersblocks' ), value: 'none' },
		{ label: __( 'Solid', 'axcelersblocks' ), value: 'solid' },
		{ label: __( 'Dashed', 'axcelersblocks' ), value: 'dashed' },
		{ label: __( 'Dotted', 'axcelersblocks' ), value: 'dotted' },
		{ label: __( 'Double', 'axcelersblocks' ), value: 'double' },
	];

	const updateOutline = ( patch ) => setAttributes( {
		outline: { ...outline, [ activeDevice ]: { ...deviceVal, ...patch } },
	} );
	const setOffset = ( value ) => setAttributes( {
		outlineOffset: { ...outlineOffset, [ activeDevice ]: value },
	} );
	const reset = () => setAttributes( {
		outline: { ...outline, [ activeDevice ]: createOutlineDeviceDefault() },
		outlineOffset: { ...outlineOffset, [ activeDevice ]: '' },
	} );

	const styleLabel = styles.find( ( s ) => s.value === deviceVal.style )?.label || __( 'Select Style', 'axcelersblocks' );

	return (
		<PanelBody
			className="outline-controls-wrapper"
			title={
					<span className="title">
						<OutlineIcon />
						{ __( 'Outline', 'axcelersblocks' ) }
					</span>
			}
			initialOpen={ false }
		>
			{/* Same compact Width + Style + Color row as the Border control, for visual consistency. */}
			<div className="border-control">
				<div className="border-control-header">
					<h3>{ __( 'Outline', 'axcelersblocks' ) }</h3>
					<Button icon={ rotateRight } onClick={ reset } label={ __( 'Reset', 'axcelersblocks' ) } showTooltip />
				</div>
				<div className="border-control-linked">
					<UnitValueControl
						label={ __( 'Width', 'axcelersblocks' ) }
						value={ deviceVal.width || '' }
						onChange={ ( value ) => updateOutline( { width: value } ) }
						placeholder="e.g., 2px"
						preset="borderWidth"
					/>
					<Dropdown
						className="border-style"
						position="bottom right"
						renderToggle={ ( { isOpen, onToggle } ) => (
							<Button variant="secondary" onClick={ onToggle } aria-expanded={ isOpen }>
								{ styleLabel }
							</Button>
						) }
						renderContent={ ( { onClose } ) => (
							<div className="border-style-options">
								{ styles.map( ( option ) => (
									<Button
										key={ option.value }
										variant="secondary"
										style={ { textAlign: 'left' } }
										onClick={ () => { updateOutline( { style: option.value } ); onClose(); } }
									>
										{ option.label }
									</Button>
								) ) }
							</div>
						) }
					/>
					<Dropdown
						className="border-color"
						position="bottom right"
						renderToggle={ ( { isOpen, onToggle } ) => (
							<Button variant="secondary" onClick={ onToggle } aria-expanded={ isOpen } label={ __( 'Outline Color', 'axcelersblocks' ) } showTooltip>
								<span style={ { backgroundColor: deviceVal.color || 'transparent' } } />
							</Button>
						) }
						renderContent={ () => (
							<ColorPicker
								color={ deviceVal.color || '#000000' }
								onChangeComplete={ ( color ) => updateOutline( { color: color.hex } ) }
							/>
						) }
					/>
				</div>
				<UnitValueControl
					label={ __( 'Outline Offset', 'axcelersblocks' ) }
					value={ outlineOffset[ activeDevice ] || '' }
					onChange={ setOffset }
					placeholder="e.g., 2px"
					preset="spacing"
				/>
			</div>
		</PanelBody>
	);
}

/**
 * Style controls for the <a class="uniqueClass-link"> wrapper.
 *
 * state=base   → reads/writes link* attributes       (Linked tab)
 * state=hover  → reads/writes linkHover* attributes  (Linked Hover tab)
 * state=focus  → reads/writes linkFocus* attributes  (Linked Focus tab)
 * state=active → reads/writes linkActive* attributes (Linked Active tab)
 */
export default function LinkStyleControls( { attributes, setAttributes, isHover = false, state = 'base' } ) {
	const prefixMap = {
		base: 'link',
		hover: 'linkHover',
		focus: 'linkFocus',
		active: 'linkActive',
	};
	const prefix = isHover ? 'linkHover' : ( prefixMap[ state ] || 'link' );
	const la = ( name ) => attributes[ `${ prefix }${ cap( name ) }` ];

	const mappedAttributes = {
		textColor:        la( 'textColor' )        || createResponsiveValueDefault(),
		fontSize:         la( 'fontSize' )         || createResponsiveValueDefault(),
		fontWeight:       la( 'fontWeight' )       || createResponsiveValueDefault(),
		fontStyle:        la( 'fontStyle' )        || createResponsiveValueDefault(),
		textDecoration:   la( 'textDecoration' )   || createResponsiveValueDefault(),
		textTransform:    la( 'textTransform' )    || createResponsiveValueDefault(),
		lineHeight:       la( 'lineHeight' )       || createResponsiveValueDefault(),
		letterSpacing:    la( 'letterSpacing' )    || createResponsiveValueDefault(),
		fontFamily:       la( 'fontFamily' )       || createResponsiveValueDefault(),
		backgroundColor:  la( 'backgroundColor' )  || createResponsiveValueDefault(),
		backgroundLayers: la( 'backgroundLayers' ) || createLayersDefault(),
		border:           la( 'border' )           || createBorderDefault(),
		borderRadius:     la( 'borderRadius' )     || createBorderRadiusDefault(),
		outline:          la( 'outline' )          || createOutlineDefault(),
		outlineOffset:    la( 'outlineOffset' )    || createResponsiveValueDefault(),
		padding:          la( 'padding' )          || createSpacingDefault(),
		margin:           la( 'margin' )           || createSpacingDefault(),
		effect:           la( 'effect' )           || createEffectDefault(),
	};

	const setLinkAttributes = ( nextAttributes ) => {
		const out = {};
		Object.entries( nextAttributes ).forEach( ( [ key, value ] ) => {
			out[ `${ prefix }${ cap( key ) }` ] = value;
		} );
		setAttributes( out );
	};

	return (
		<>
			<TypographyControl
				attributes={ mappedAttributes }
				setAttributes={ setLinkAttributes }
				activeStyleTab="main"
			/>
			<BackgroundControl
				attributes={ mappedAttributes }
				setAttributes={ setLinkAttributes }
				activeStyleTab="main"
			/>
			<BorderControl
				attributes={ mappedAttributes }
				setAttributes={ setLinkAttributes }
				activeStyleTab="main"
			/>
			{ [ 'focus', 'active' ].includes( state ) && (
				<OutlineControls
					attributes={ mappedAttributes }
					setAttributes={ setLinkAttributes }
				/>
			) }
			<SpacingControls
				attributes={ mappedAttributes }
				setAttributes={ setLinkAttributes }
				activeStyleTab="main"
			/>
			<EffectControl
				attributes={ mappedAttributes }
				setAttributes={ setLinkAttributes }
				activeStyleTab="main"
			/>
		</>
	);
}
