/**
 * WordPress dependencies
 */
import { DropdownMenu, TextControl } from '@safe-wordpress/components';
import { _x } from '@safe-wordpress/i18n';
import { useSelect, useDispatch } from '@safe-wordpress/data';

/**
 * External dependencies
 */
import { createSegmentationRule as createSegmentationRuleWithDefaults } from '@nab/segmentation-rules';
import { isDefined } from '@nab/utils';
import type { SegmentationRuleTypeName } from '@nab/types';

/**
 * Internal dependencies
 */
import './style.scss';
import { SegmentationRuleList } from './segmentation-rule-list';
import { SegmentationRuleTypeCategoryList } from './segmentation-rule-type-category-list';
import { store as NAB_EDITOR } from '../../store';

export type SegmentProps = {
	readonly name: string;
	readonly setName: ( name: string ) => void;
	readonly duplicateSegment?: () => void;
	readonly removeSegment?: () => void;
};

export const Segment = ( {
	name,
	setName,
	duplicateSegment,
	removeSegment,
}: SegmentProps ): JSX.Element => {
	const activeSegmentRules = useActiveSegmentRules();
	const createSegmentationRule = useSegmentationRuleCreator();

	const activeSegmentId = useActiveSegmentId();
	const isDefaultSegmentActive = 'default-segment' === activeSegmentId;

	if ( isDefaultSegmentActive ) {
		return (
			<div className="nab-current-segment-info">
				<div className="nab-current-segment-info__header">
					<strong>{ name }</strong>
				</div>
				<p>
					{ _x(
						'The default segment will include every visitor who matches at least one of the segments you’ve defined. It’ll give you an aggregated view of all segmented participants, so you can analyze the overall results for this test alongside each individual segment.',
						'text',
						'nelio-ab-testing'
					) }
				</p>
			</div>
		);
	}

	return (
		<div className="nab-current-segment-info">
			<div className="nab-current-segment-info__header">
				<TextControl
					placeholder={ _x(
						'Name your segment…',
						'user',
						'nelio-ab-testing'
					) }
					value={ name }
					onChange={ ( value ) => setName( value ) }
				/>
				<Actions
					duplicate={ duplicateSegment }
					remove={ removeSegment }
				/>
			</div>

			<SegmentationRuleList />
			<SegmentationRuleTypeCategoryList
				segmentationRules={ activeSegmentRules }
				createSegmentationRule={ createSegmentationRule }
			/>
		</div>
	);
};

const Actions = ( {
	duplicate,
	remove,
}: {
	readonly duplicate: SegmentProps[ 'duplicateSegment' ];
	readonly remove: SegmentProps[ 'removeSegment' ];
} ) => {
	const { openReusableDialog } = useDispatch( NAB_EDITOR );
	return (
		<DropdownMenu
			icon="admin-generic"
			label={ _x( 'Segment Actions', 'text', 'nelio-ab-testing' ) }
			controls={ [
				{
					title: _x(
						'Save',
						'command (segment)',
						'nelio-ab-testing'
					),
					icon: 'cloud' as const,
					onClick: () => openReusableDialog( 'save-segment' ),
				},
				duplicate
					? {
							title: _x(
								'Duplicate',
								'command (segment)',
								'nelio-ab-testing'
							),
							icon: 'admin-page' as const,
							onClick: duplicate,
					  }
					: undefined,
				remove
					? {
							title: _x(
								'Remove',
								'command (segment)',
								'nelio-ab-testing'
							),
							icon: 'trash' as const,
							onClick: remove,
					  }
					: undefined,
			].filter( isDefined ) }
		/>
	);
};

// =====
// HOOKS
// =====

const useActiveSegment = () =>
	useSelect( ( select ) => select( NAB_EDITOR ).getActiveSegment(), [] );

const useActiveSegmentRules = () => {
	const activeSegment = useActiveSegment();
	return useSelect(
		( select ) => {
			const { getSegmentationRules } = select( NAB_EDITOR );
			return activeSegment?.id
				? getSegmentationRules( activeSegment.id ) || []
				: [];
		},
		[ activeSegment ]
	);
};

const useSegmentationRuleCreator = () => {
	const { addSegmentationRulesIntoSegment } = useDispatch( NAB_EDITOR );
	const activeSegment = useActiveSegment();
	return ( type: SegmentationRuleTypeName ) => {
		if ( ! activeSegment ) {
			return;
		}
		const rule = createSegmentationRuleWithDefaults( type );
		if ( rule ) {
			void addSegmentationRulesIntoSegment( activeSegment.id, rule );
		}
	};
};

const useActiveSegmentId = () =>
	useSelect( ( select ) => select( NAB_EDITOR ).getActiveSegment()?.id, [] );
