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

/**
 * External dependencies
 */
import { SaveButton } from '@nelio-content/components';

/**
 * Internal dependencies
 */
import './style.scss';
import { store as NC_CUSTOM_STATUSES } from '~/nelio-content-pages/settings/custom-statuses/store';
import { GeneralSettings } from './general-settings';
import { DisplaySettings } from './display-settings';
import { PostTypesSettings } from './post-types-settings';
import { RolesSettings } from './roles-settings';
import { useState } from 'react';
import { PostStatus } from '@nelio-content/types';

export const StatusEditor = (): JSX.Element | null => {
	const isExistingStatus = ! useIsNew();
	const attrs = useSelect(
		( select ) => select( NC_CUSTOM_STATUSES ).getEditingStatus(),
		[]
	);

	const error = useSelect(
		( select ) => select( NC_CUSTOM_STATUSES ).getEditingStatusError(),
		[]
	);

	const isVisible = useSelect(
		( select ) => select( NC_CUSTOM_STATUSES ).isStatusEditorOpen(),
		[]
	);

	const isExistingStatusDirty = useSelect(
		( select ) =>
			isExistingStatus &&
			select( NC_CUSTOM_STATUSES ).isEditingStatusDirty(),
		[ isExistingStatus ]
	);

	const [ activeTab, setActiveTab ] = useState<
		'general' | 'display' | 'post-types' | 'roles'
	>( 'general' );

	const { closeStatusEditor: close, setStatus } =
		useDispatch( NC_CUSTOM_STATUSES );

	const saveAndClose = () => {
		void setStatus( attrs );
		setActiveTab( 'general' );
		void close();
	};

	const title = <Title />;

	if ( ! isVisible ) {
		return null;
	}

	return (
		<Modal
			className="nelio-content-status-editor"
			title={ title as unknown as string }
			isDismissible={ false }
			shouldCloseOnEsc={ false }
			shouldCloseOnClickOutside={ false }
			onRequestClose={ () => void null }
		>
			<div className="nelio-content-status-editor__body">
				<TabPanel
					className="nelio-content-status-editor__tab-panel"
					activeClass="nelio-content-status-editor__tab--is-active"
					orientation="horizontal"
					initialTabName={ activeTab }
					tabs={ getTabs( attrs ) }
					onSelect={ ( tab ) => setActiveTab( tab ) }
				>
					{ ( { name: tab } ) => (
						<>
							{ 'general' === tab && <GeneralSettings /> }
							{ 'display' === tab && <DisplaySettings /> }
							{ 'post-types' === tab && <PostTypesSettings /> }
							{ 'roles' === tab && <RolesSettings /> }
						</>
					) }
				</TabPanel>
			</div>
			<div className="nelio-content-status-editor__footer">
				<div className="nelio-content-status-editor__actions">
					<Button
						variant="secondary"
						onClick={ () => {
							setActiveTab( 'general' );
							void close();
						} }
					>
						{ isExistingStatusDirty
							? _x(
									'Discard Changes',
									'command',
									'nelio-content'
							  )
							: _x( 'Close', 'command', 'nelio-content' ) }
					</Button>

					<SaveButton
						variant="primary"
						error={ error }
						disabled={
							isExistingStatus ? ! isExistingStatusDirty : false
						}
						isUpdate={ isExistingStatus }
						onClick={ saveAndClose }
					/>
				</div>
			</div>
		</Modal>
	);
};

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

function getTabs( status: PostStatus ) {
	return TABS.map( ( tab ) => ( {
		...tab,
		disabled: isTabDisabled( tab.name, status ),
	} ) );
}

function isTabDisabled(
	tab: ( typeof TABS )[ number ][ 'name' ],
	status: PostStatus
): boolean {
	if ( status.core ) {
		return 'roles' === tab || 'post-types' === tab;
	}

	if ( status.isCustomizationLimited ) {
		return 'post-types' === tab;
	}

	return false;
}

const TABS = [
	{
		name: 'general' as const,
		title: _x( 'General', 'text', 'nelio-content' ),
		className: 'nelio-content-status-editor__tab',
	},
	{
		name: 'display' as const,
		title: _x( 'Display', 'text', 'nelio-content' ),
		className: 'nelio-content-status-editor__tab',
	},
	{
		name: 'post-types' as const,
		title: _x( 'Post Types', 'text', 'nelio-content' ),
		className: 'nelio-content-status-editor__tab',
	},
	{
		name: 'roles' as const,
		title: _x( 'Roles', 'text', 'nelio-content' ),
		className: 'nelio-content-status-editor__tab',
	},
];

// =============
// HELPERS VIEWS
// =============

const Title = (): JSX.Element => {
	const isNew = useIsNew();
	return (
		<div className="nelio-content-status-editor__title">
			<div className="nelio-content-status-editor__title-text">
				{ isNew
					? _x( 'Create Status', 'command', 'nelio-content' )
					: _x( 'Edit Status', 'command', 'nelio-content' ) }
			</div>
		</div>
	);
};

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

const useIsNew = () =>
	useSelect( ( select ) => {
		const context = select( NC_CUSTOM_STATUSES ).getEditingStatus();
		if ( ! context ) {
			return false;
		}

		return select( NC_CUSTOM_STATUSES ).isEditingStatusNew();
	}, [] );
