/**
 * Editor UI for the "Restricted Content" block.
 *
 * The InspectorControls sidebar exposes the block's restriction mode and rule
 * settings. The gate is intentionally NOT applied in the editor — authors must
 * see and edit the blocks they are protecting; gating happens only on the
 * frontend via render.php.
 */
import {
	InspectorControls,
	useBlockProps,
	useInnerBlocksProps,
} from '@wordpress/block-editor';
import {
	PanelBody,
	Notice,
	ToggleControl,
	SelectControl,
	TextareaControl,
	TextControl,
	__experimentalNumberControl as NumberControl,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

import AsyncTokenSelect from './components/AsyncTokenSelect';
import FeatureCombobox from './components/FeatureCombobox';
import StaticTokenSelect from './components/StaticTokenSelect';

const cfg = window.ArraySubsGutenberg || {};
const STATUS_OPTIONS = cfg.statuses || [];
const ROLE_OPTIONS = cfg.roles || [];

export default function Edit( { attributes, setAttributes } ) {
	const {
		mode,
		visShow,
		visFallback,
		status,
		roles,
		products,
		variations,
		purchased,
		lifetimeSpent,
		condition,
		feature,
		featureMatch,
		featureValue,
		featureOp,
		aggregation,
		message,
		loginRequired,
		showToAdmins,
	} = attributes;

	const blockProps = useBlockProps( {
		className: 'arraysubs-restricted-container is-restricted',
	} );
	const { children: innerChildren, ...innerWrapperProps } = useInnerBlocksProps(
		blockProps,
		{ templateLock: false }
	);

	const set = ( key ) => ( value ) => setAttributes( { [ key ]: value } );

	const isRestrict = mode === 'restrict';
	const isVisibility = mode === 'visibility';
	const showFeatureAmount =
		isRestrict &&
		feature &&
		[ 'min_total', 'min_single', 'custom' ].includes( featureMatch );
	const showFeatureCustom = isRestrict && feature && featureMatch === 'custom';

	return (
		<>
			<InspectorControls>
				<PanelBody
					title={ __( 'ArraySubs Content Restrictions', 'arraysubs' ) }
					initialOpen={ true }
				>
					<SelectControl
						__next40pxDefaultSize
						__nextHasNoMarginBottom
						label={ __( 'Restriction Type', 'arraysubs' ) }
						value={ mode }
						options={ [
							{
								label: __(
									'Subscription / Role / Purchase (restrict)',
									'arraysubs'
								),
								value: 'restrict',
							},
							{
								label: __(
									'Login state (visibility)',
									'arraysubs'
								),
								value: 'visibility',
							},
						] }
						onChange={ set( 'mode' ) }
					/>
				</PanelBody>

				{ isRestrict && (
					<PanelBody
						title={ __( 'When Access Is Denied', 'arraysubs' ) }
						initialOpen={ true }
					>
						<TextareaControl
							__nextHasNoMarginBottom
							label={ __( 'Restricted Message', 'arraysubs' ) }
							help={ __(
								'Shown in place of the content. Leave empty to use the global default.',
								'arraysubs'
							) }
							value={ message }
							onChange={ set( 'message' ) }
						/>
						<ToggleControl
							__nextHasNoMarginBottom
							label={ __( 'Require Login', 'arraysubs' ) }
							checked={ !! loginRequired }
							onChange={ set( 'loginRequired' ) }
						/>
						<ToggleControl
							__nextHasNoMarginBottom
							label={ __( 'Always Show To Admins', 'arraysubs' ) }
							checked={ !! showToAdmins }
							onChange={ set( 'showToAdmins' ) }
						/>
					</PanelBody>
				) }

				{ isVisibility && (
					<PanelBody
						title={ __( 'Visibility', 'arraysubs' ) }
						initialOpen={ true }
					>
						<SelectControl
							__next40pxDefaultSize
							__nextHasNoMarginBottom
							label={ __( 'Show To', 'arraysubs' ) }
							value={ visShow }
							options={ [
								{
									label: __( 'Logged-in users', 'arraysubs' ),
									value: 'logged_in',
								},
								{
									label: __( 'Logged-out users', 'arraysubs' ),
									value: 'logged_out',
								},
							] }
							onChange={ set( 'visShow' ) }
						/>
						<TextareaControl
							__nextHasNoMarginBottom
							label={ __( 'Fallback Content', 'arraysubs' ) }
							help={ __(
								'Shown to everyone else. Plain text or a shortcode.',
								'arraysubs'
							) }
							value={ visFallback }
							onChange={ set( 'visFallback' ) }
						/>
					</PanelBody>
				) }

				{ isRestrict && (
					<PanelBody
						title={ __( 'Access Rules', 'arraysubs' ) }
						initialOpen={ true }
					>
						<StaticTokenSelect
							label={ __( 'Subscription Status', 'arraysubs' ) }
							options={ STATUS_OPTIONS }
							values={ status }
							onChange={ set( 'status' ) }
						/>

						<AsyncTokenSelect
							label={ __(
								'Active Subscription To Products',
								'arraysubs'
							) }
							type="products"
							query={ { product_type: 'subscription' } }
							ids={ products }
							onChangeIds={ set( 'products' ) }
						/>

						<AsyncTokenSelect
							label={ __(
								'Active Subscription To Variations',
								'arraysubs'
							) }
							type="variations"
							query={ { product_type: 'subscription' } }
							ids={ variations }
							onChangeIds={ set( 'variations' ) }
						/>

						<AsyncTokenSelect
							label={ __(
								'Purchased Products (any purchase)',
								'arraysubs'
							) }
							type="products"
							ids={ purchased }
							onChangeIds={ set( 'purchased' ) }
						/>

						<StaticTokenSelect
							label={ __( 'User Roles', 'arraysubs' ) }
							options={ ROLE_OPTIONS }
							values={ roles }
							onChange={ set( 'roles' ) }
						/>

						<NumberControl
							__next40pxDefaultSize
							label={ __( 'Minimum Lifetime Spend', 'arraysubs' ) }
							min={ 0 }
							step={ 0.01 }
							value={ lifetimeSpent }
							onChange={ ( v ) =>
								setAttributes( { lifetimeSpent: v == null ? '' : String( v ) } )
							}
						/>

						<SelectControl
							__next40pxDefaultSize
							__nextHasNoMarginBottom
							label={ __( 'Match Logic', 'arraysubs' ) }
							value={ condition }
							options={ [
								{
									label: __(
										'Match ALL of the above (AND)',
										'arraysubs'
									),
									value: 'and',
								},
								{
									label: __(
										'Match ANY of the above (OR)',
										'arraysubs'
									),
									value: 'or',
								},
							] }
							onChange={ set( 'condition' ) }
						/>
					</PanelBody>
				) }

				{ isRestrict && (
					<PanelBody
						title={ __( 'Plan Feature (Pro)', 'arraysubs' ) }
						initialOpen={ false }
					>
						<p className="arraysubs-control-note">
							{ __(
								'Gate by a feature defined on your subscription products (Product → Features, requires ArraySubs Pro). Pick a feature, then choose how to check it. Leave empty to not use a feature rule.',
								'arraysubs'
							) }
						</p>

						<FeatureCombobox
							label={ __( 'Feature', 'arraysubs' ) }
							help={ __(
								'The feature name, exactly as defined on the product.',
								'arraysubs'
							) }
							value={ feature }
							onChange={ set( 'feature' ) }
						/>

						{ feature && (
							<SelectControl
								__next40pxDefaultSize
								__nextHasNoMarginBottom
								label={ __( 'How To Check It', 'arraysubs' ) }
								value={ featureMatch }
								help={ __(
									'On/off (toggle) features: use "Has the feature". Numeric features (e.g. seats, API calls): use one of the "at least" options.',
									'arraysubs'
								) }
								options={ [
									{
										label: __(
											'Has the feature (on/off features)',
											'arraysubs'
										),
										value: 'has',
									},
									{
										label: __(
											'Combined amount across their plans is at least…',
											'arraysubs'
										),
										value: 'min_total',
									},
									{
										label: __(
											'At least one plan provides at least…',
											'arraysubs'
										),
										value: 'min_single',
									},
									{
										label: __(
											'Custom comparison (advanced)',
											'arraysubs'
										),
										value: 'custom',
									},
								] }
								onChange={ set( 'featureMatch' ) }
							/>
						) }

						{ showFeatureAmount && (
							<NumberControl
								__next40pxDefaultSize
								label={ __( 'Required Amount', 'arraysubs' ) }
								min={ 0 }
								value={ featureValue }
								help={ __(
									'The number the feature must reach.',
									'arraysubs'
								) }
								onChange={ ( v ) =>
									setAttributes( {
										featureValue: v == null ? '' : String( v ),
									} )
								}
							/>
						) }

						{ showFeatureCustom && (
							<SelectControl
								__next40pxDefaultSize
								__nextHasNoMarginBottom
								label={ __( 'Comparison', 'arraysubs' ) }
								value={ featureOp }
								options={ [
									{ label: __( 'At least (>=)', 'arraysubs' ), value: '>=' },
									{ label: __( 'More than (>)', 'arraysubs' ), value: '>' },
									{ label: __( 'Exactly (=)', 'arraysubs' ), value: '=' },
									{ label: __( 'Not equal (!=)', 'arraysubs' ), value: '!=' },
									{ label: __( 'Less than (<)', 'arraysubs' ), value: '<' },
									{ label: __( 'At most (<=)', 'arraysubs' ), value: '<=' },
								] }
								onChange={ set( 'featureOp' ) }
							/>
						) }

						{ showFeatureCustom && (
							<SelectControl
								__next40pxDefaultSize
								__nextHasNoMarginBottom
								label={ __( 'Combine Multiple Plans By', 'arraysubs' ) }
								value={ aggregation }
								help={ __(
									'For presence (on/off) checks use the "Has the feature" mode instead.',
									'arraysubs'
								) }
								options={ [
									{
										label: __(
											'Sum — add values across plans',
											'arraysubs'
										),
										value: 'sum',
									},
									{
										label: __(
											'Max — highest single plan',
											'arraysubs'
										),
										value: 'max',
									},
								] }
								onChange={ set( 'aggregation' ) }
							/>
						) }
					</PanelBody>
				) }

			</InspectorControls>

			<div { ...innerWrapperProps }>
				<Notice status="info" isDismissible={ false } className="arraysubs-editor-badge">
					{ mode === 'visibility'
						? __(
								'Restricted on the frontend by login state. The editor always shows these blocks.',
								'arraysubs'
						  )
						: __(
								'Restricted on the frontend by your access rules. The editor always shows these blocks.',
								'arraysubs'
						  ) }
				</Notice>
				{ innerChildren }
			</div>
		</>
	);
}
