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

/**
 * External dependencies
 */
import clsx from 'clsx';
import { trim } from 'lodash';
import { SortableList } from '@nab/components';
import { store as NAB_DATA } from '@nab/data';
import { createSegment } from '@nab/utils';
import type { Segment, SegmentId } from '@nab/types';

/**
 * Internal dependencies
 */
import './style.scss';
import { useExperimentAttribute } from '../hooks';
import { store as NAB_EDITOR } from '../../store';

const DEFAULT_SEGMENT_ID = 'default-segment' as SegmentId;

export const SegmentList = (): JSX.Element => {
	const segments = useSegments();
	const isExperimentPaused = useIsExperimentPaused();
	const { addSegments, openReusableDialog, setActiveSegment, sortSegments } =
		useDispatch( NAB_EDITOR );

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

	return (
		<div className="nab-segment-list">
			{ 2 <= segments.length && (
				<div
					className={ clsx( 'nab-segment-list__item', {
						'nab-segment-list__item--is-active':
							isDefaultSegmentActive,
					} ) }
				>
					<Button
						disabled={ isDefaultSegmentActive }
						onClick={ () => setActiveSegment( DEFAULT_SEGMENT_ID ) }
						title={ _x(
							'Combined Segment (Auto)',
							'text',
							'nelio-ab-testing'
						) }
					>
						{ _x( 'Combined Segment', 'text', 'nelio-ab-testing' ) }
					</Button>
				</div>
			) }

			<SortableList
				disabled={ isExperimentPaused }
				items={ segments }
				render={ SegmentView }
				onSort={ sortSegments }
			/>

			{ ! isExperimentPaused && (
				<div className="nab-segment-list__actions">
					<Button
						className="nab-segment-list__add-new-segment-button"
						variant="link"
						onClick={ () => {
							const segment = createSegment();
							void addSegments( segment );
							void setActiveSegment( segment.id );
						} }
						icon="plus"
					>
						{ _x( 'New', 'command (segment)', 'nelio-ab-testing' ) }
					</Button>
					{ isImportEnabled && (
						<Button
							className="nab-segment-list__import-segments-button"
							variant="link"
							onClick={ () =>
								openReusableDialog( 'manage-segments' )
							}
							icon="external"
						>
							{ _x( 'Import', 'command', 'nelio-ab-testing' ) }
						</Button>
					) }
				</div>
			) }
		</div>
	);
};

const SegmentView = ( {
	item: segment,
	index,
}: {
	readonly item: Omit< Segment, 'segmentationRules' >;
	readonly index: number;
} ) => {
	const activeSegmentId = useActiveSegmentId();
	const { setActiveSegment } = useDispatch( NAB_EDITOR );
	return (
		<div
			key={ segment.id }
			className={ clsx( 'nab-segment-list__item', {
				'nab-segment-list__item--is-active':
					segment.id === activeSegmentId,
			} ) }
		>
			<Button
				disabled={ segment.id === activeSegmentId }
				title={
					trim( segment.attributes.name ) ||
					getDefaulSegmentNameForIndex( index )
				}
				onClick={ () => setActiveSegment( segment.id ) }
			>
				{ trim( segment.attributes.name ) ||
					getDefaulSegmentNameForIndex( index ) }
			</Button>
		</div>
	);
};

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

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

const useSegments = () =>
	useSelect( ( select ) => select( NAB_EDITOR ).getSegments() || [], [] );

const useIsExperimentPaused = () => {
	const [ status ] = useExperimentAttribute( 'status' );
	return status.includes( 'paused' );
};

const useIsImportEnabled = (): boolean =>
	useSelect(
		( select ) => !! select( NAB_DATA ).getReusableSegments().length,
		[]
	);

// =======
// HELPERS
// =======

const getDefaulSegmentNameForIndex = ( index: number ) =>
	sprintf(
		/* translators: %d: Number. */
		_x( 'Segment %d', 'text', 'nelio-ab-testing' ),
		index + 1
	);
