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

/**
 * External dependencies
 */
import { isArray } from 'lodash';
import { store as NC_DATA } from '@nelio-content/data';
import type { MediaUploadItem } from '@nelio-content/types';
import {
	getNetworkLabel,
	getSupportedVideoTypes,
} from '@nelio-content/networks';

/**
 * Internal dependencies
 */
import { store as NC_SOCIAL_EDITOR } from '../../store';
import {
	useActiveNetworkType,
	useActiveSocialNetwork,
	useDoesActiveNetworkSupport,
	useHasExplicitVideo,
} from '../../hooks';

export type VideoToggleProps = {
	readonly disabled?: boolean;
};

export const VideoToggle = ( {
	disabled,
}: VideoToggleProps ): JSX.Element | null => {
	const supportsVideo = useDoesActiveNetworkSupport( 'video' );
	const supportsMultiMedia = useDoesActiveNetworkSupport( 'multi-media' );
	const type = useActiveNetworkType();
	const activeNetwork = useActiveSocialNetwork();
	const hasExplicitVideo = useHasExplicitVideo();
	const { setVideos } = useDispatch( NC_SOCIAL_EDITOR );
	const { receiveMediaUploadItem } = useDispatch( NC_DATA );

	if ( ! supportsVideo ) {
		return null;
	}

	if ( [ 'video', 'multi-media' ].includes( type ) ) {
		return <RemoveVideo disabled={ disabled } />;
	}

	if ( hasExplicitVideo ) {
		return <UseExistingVideo disabled={ disabled } />;
	}

	return (
		<MediaUpload
			title={ sprintf(
				/* translators: %s: Social network name. */
				_x(
					'Select or Upload Video Files for %s',
					'command',
					'nelio-content'
				),
				getNetworkLabel( 'name', activeNetwork )
			) }
			allowedTypes={ [
				...( getSupportedVideoTypes( activeNetwork ) ?? 'video' ),
			] }
			multiple={
				// NOTE: The following cast is required until WordPress types
				// for MediaUpload.onSelect are properly defined.
				supportsMultiMedia ? ( 'add' as unknown as true ) : false
			}
			onSelect={ (
				video: MediaUploadItem | Array< MediaUploadItem >
			) => {
				video = isArray( video ) ? video : [ video ];
				video.forEach( ( v ) => {
					void receiveMediaUploadItem( v );
				} );
				void setVideos(
					activeNetwork,
					video.map( ( v ) => v.id ),
					video.map( ( v ) => v.url ),
					video.map( ( v ) => v.alt )
				);
			} }
			render={ ( { open }: { open: () => void } ) => (
				<AddVideo disabled={ disabled } onClick={ open } />
			) }
		/>
	);
};

// ============
// HELPER VIEWS
// ============

const RemoveVideo = ( { disabled }: { disabled?: boolean } ): JSX.Element => {
	const { removeVideo } = useDispatch( NC_SOCIAL_EDITOR );
	return (
		<Button
			className="nelio-content-social-message-editor__quick-action nelio-content-social-message-editor__quick-action--is-toggled"
			icon="video-alt2"
			label={ _x( 'Remove Video', 'command', 'nelio-content' ) }
			tooltipPosition="bottom center"
			isPressed
			disabled={ disabled }
			onClick={ removeVideo }
		/>
	);
};

const AddVideo = ( {
	label,
	disabled,
	onClick,
}: {
	label?: string;
	disabled?: boolean;
	onClick: () => void;
} ) => {
	return (
		<Button
			className="nelio-content-social-message-editor__quick-action"
			icon="video-alt2"
			label={ label ?? _x( 'Add Video…', 'command', 'nelio-content' ) }
			tooltipPosition="bottom center"
			disabled={ disabled }
			onClick={ onClick }
		/>
	);
};

const UseExistingVideo = ( { disabled }: { disabled?: boolean } ) => {
	const network = useActiveSocialNetwork();
	const { switchMessageType } = useDispatch( NC_SOCIAL_EDITOR );
	return (
		<Button
			className="nelio-content-social-message-editor__quick-action"
			icon="video-alt2"
			label={ _x( 'Use Video', 'command', 'nelio-content' ) }
			tooltipPosition="bottom center"
			disabled={ disabled }
			onClick={ () => switchMessageType( network, 'video' ) }
		/>
	);
};
