/**
 * External dependencies
 */
import classnames from 'classnames';
import { __ } from '@wordpress/i18n';
import { InspectorControls } from '@wordpress/block-editor';
import {
	PanelBody,
	ToggleControl,
	CheckboxControl,
	Notice,
	Disabled,
} from '@wordpress/components';
import BlockErrorBoundary from '@woocommerce/base-components/block-error-boundary';
import {
	PRIVACY_URL,
	TERMS_URL,
	CHECKOUT_PAGE_ID,
} from '@woocommerce/block-settings';
import { isWcVersion, getAdminLink, getSetting } from '@woocommerce/settings';
import { createInterpolateElement, useRef } from '@wordpress/element';
import {
	EditorProvider,
	useEditorContext,
	StoreNoticesProvider,
	CheckoutProvider,
} from '@woocommerce/base-context';
import { CartCheckoutFeedbackPrompt } from '@woocommerce/editor-components/feedback-prompt';
import PageSelector from '@woocommerce/editor-components/page-selector';
import { CartCheckoutCompatibilityNotice } from '@woocommerce/editor-components/compatibility-notices';
import {
	previewCart,
	previewSavedPaymentMethods,
} from '@woocommerce/resource-previews';

/**
 * Internal dependencies
 */
import Block from './block.js';
import './editor.scss';

const BlockSettings = ( { attributes, setAttributes } ) => {
	const {
		showCompanyField,
		showApartmentField,
		showPhoneField,
		requireCompanyField,
		requirePhoneField,
		allowCreateAccount,
		showOrderNotes,
		showPolicyLinks,
		showReturnToCart,
		cartPageId,
		hasDarkControls,
		showRateAfterTaxName,
	} = attributes;
	const { currentPostId } = useEditorContext();
	const { current: savedCartPageId } = useRef( cartPageId );
	// Checkout signup is feature gated to WooCommerce 4.7 and newer;
	// uses updated my-account/lost-password screen from 4.7+ for
	// setting initial password.
	// Also implicitly gated to feature plugin, because Checkout
	// block is gated to plugin
	const showCreateAccountOption =
		getSetting( 'checkoutAllowsSignup', false ) &&
		isWcVersion( '4.7.0', '>=' );
	return (
		<InspectorControls>
			{ currentPostId !== CHECKOUT_PAGE_ID && (
				<Notice
					className="wc-block-checkout__page-notice"
					isDismissible={ false }
					status="warning"
				>
					{ createInterpolateElement(
						__(
							'If you would like to use this block as your default checkout you must update your <a>page settings in WooCommerce</a>.',
							'woocommerce'
						),
						{
							a: (
								// eslint-disable-next-line jsx-a11y/anchor-has-content
								<a
									href={ getAdminLink(
										'admin.php?page=wc-settings&tab=advanced'
									) }
									target="_blank"
									rel="noopener noreferrer"
								/>
							),
						}
					) }
				</Notice>
			) }
			<PanelBody
				title={ __(
					'Address options',
					'woocommerce'
				) }
			>
				<p className="wc-block-checkout__controls-text">
					{ __(
						'Include additional address fields in the checkout form.',
						'woocommerce'
					) }
				</p>
				<ToggleControl
					label={ __( 'Company', 'woocommerce' ) }
					checked={ showCompanyField }
					onChange={ () =>
						setAttributes( {
							showCompanyField: ! showCompanyField,
						} )
					}
				/>
				{ showCompanyField && (
					<CheckboxControl
						label={ __(
							'Require company name?',
							'woocommerce'
						) }
						checked={ requireCompanyField }
						onChange={ () =>
							setAttributes( {
								requireCompanyField: ! requireCompanyField,
							} )
						}
						className="components-base-control--nested"
					/>
				) }
				<ToggleControl
					label={ __(
						'Apartment, suite, etc.',
						'woocommerce'
					) }
					checked={ showApartmentField }
					onChange={ () =>
						setAttributes( {
							showApartmentField: ! showApartmentField,
						} )
					}
				/>
				<ToggleControl
					label={ __( 'Phone', 'woocommerce' ) }
					checked={ showPhoneField }
					onChange={ () =>
						setAttributes( {
							showPhoneField: ! showPhoneField,
						} )
					}
				/>
				{ showPhoneField && (
					<CheckboxControl
						label={ __(
							'Require phone number?',
							'woocommerce'
						) }
						checked={ requirePhoneField }
						onChange={ () =>
							setAttributes( {
								requirePhoneField: ! requirePhoneField,
							} )
						}
						className="components-base-control--nested"
					/>
				) }
			</PanelBody>
			{ showCreateAccountOption && (
				<PanelBody
					title={ __(
						'Account options',
						'woocommerce'
					) }
				>
					<ToggleControl
						label={ __(
							'Allow shoppers to sign up for a user account during checkout',
							'woocommerce'
						) }
						checked={ allowCreateAccount }
						onChange={ () =>
							setAttributes( {
								allowCreateAccount: ! allowCreateAccount,
							} )
						}
					/>
				</PanelBody>
			) }
			<PanelBody
				title={ __( 'Order notes', 'woocommerce' ) }
			>
				<p className="wc-block-checkout__controls-text">
					{ __(
						'Reduce the number of fields to checkout.',
						'woocommerce'
					) }
				</p>
				<ToggleControl
					label={ __(
						'Allow shoppers to optionally add order notes',
						'woocommerce'
					) }
					checked={ showOrderNotes }
					onChange={ () =>
						setAttributes( {
							showOrderNotes: ! showOrderNotes,
						} )
					}
				/>
			</PanelBody>
			<PanelBody
				title={ __(
					'Navigation options',
					'woocommerce'
				) }
			>
				<ToggleControl
					label={ __(
						'Show links to policies',
						'woocommerce'
					) }
					help={ __(
						'Shows links to your "terms and conditions" and "privacy policy" pages.',
						'woocommerce'
					) }
					checked={ showPolicyLinks }
					onChange={ () =>
						setAttributes( {
							showPolicyLinks: ! showPolicyLinks,
						} )
					}
				/>
				{ showPolicyLinks && ( ! PRIVACY_URL || ! TERMS_URL ) && (
					<Notice
						className="wc-block-base-control-notice"
						isDismissible={ false }
					>
						{ createInterpolateElement(
							__(
								'Pages must be first setup in store settings: <a1>Privacy policy</a1>, <a2>Terms and conditions</a2>.',
								'woocommerce'
							),
							{
								a1: (
									// eslint-disable-next-line jsx-a11y/anchor-has-content
									<a
										href={ getAdminLink(
											'admin.php?page=wc-settings&tab=account'
										) }
										target="_blank"
										rel="noopener noreferrer"
									/>
								),
								a2: (
									// eslint-disable-next-line jsx-a11y/anchor-has-content
									<a
										href={ getAdminLink(
											'admin.php?page=wc-settings&tab=advanced'
										) }
										target="_blank"
										rel="noopener noreferrer"
									/>
								),
							}
						) }
					</Notice>
				) }
				<ToggleControl
					label={ __(
						'Show a "Return to Cart" link',
						'woocommerce'
					) }
					checked={ showReturnToCart }
					onChange={ () =>
						setAttributes( {
							showReturnToCart: ! showReturnToCart,
						} )
					}
				/>
			</PanelBody>
			{ showReturnToCart &&
				! (
					currentPostId === CHECKOUT_PAGE_ID && savedCartPageId === 0
				) && (
					<PageSelector
						pageId={ cartPageId }
						setPageId={ ( id ) =>
							setAttributes( { cartPageId: id } )
						}
						labels={ {
							title: __(
								'Return to Cart button',
								'woocommerce'
							),
							default: __(
								'WooCommerce Cart Page',
								'woocommerce'
							),
						} }
					/>
				) }
			{ getSetting( 'taxesEnabled' ) &&
				getSetting( 'displayItemizedTaxes', false ) &&
				! getSetting( 'displayCartPricesIncludingTax', false ) && (
					<PanelBody
						title={ __( 'Taxes', 'woocommerce' ) }
					>
						<ToggleControl
							label={ __(
								'Show rate after tax name',
								'woocommerce'
							) }
							help={ __(
								'Show the percentage rate alongside each tax line in the summary.',
								'woocommerce'
							) }
							checked={ showRateAfterTaxName }
							onChange={ () =>
								setAttributes( {
									showRateAfterTaxName: ! showRateAfterTaxName,
								} )
							}
						/>
					</PanelBody>
				) }
			<PanelBody title={ __( 'Style', 'woocommerce' ) }>
				<ToggleControl
					label={ __(
						'Dark mode inputs',
						'woocommerce'
					) }
					help={ __(
						'Inputs styled specifically for use on dark background colors.',
						'woocommerce'
					) }
					checked={ hasDarkControls }
					onChange={ () =>
						setAttributes( {
							hasDarkControls: ! hasDarkControls,
						} )
					}
				/>
			</PanelBody>
			<CartCheckoutFeedbackPrompt />
		</InspectorControls>
	);
};

const CheckoutEditor = ( { attributes, setAttributes } ) => {
	const { className, isPreview } = attributes;
	return (
		<>
			<EditorProvider
				previewData={ { previewCart, previewSavedPaymentMethods } }
			>
				<div
					className={ classnames(
						className,
						'wp-block-woocommerce-checkout',
						{
							'is-editor-preview': isPreview,
						}
					) }
				>
					<BlockSettings
						attributes={ attributes }
						setAttributes={ setAttributes }
					/>
					<BlockErrorBoundary
						header={ __(
							'Checkout Block Error',
							'woocommerce'
						) }
						text={ __(
							'There was an error whilst rendering the checkout block. If this problem continues, try re-creating the block.',
							'woocommerce'
						) }
						showErrorMessage={ true }
						errorMessagePrefix={ __(
							'Error message:',
							'woocommerce'
						) }
					>
						<StoreNoticesProvider context="wc/checkout">
							<Disabled>
								<CheckoutProvider>
									<Block attributes={ attributes } />
								</CheckoutProvider>
							</Disabled>
						</StoreNoticesProvider>
					</BlockErrorBoundary>
				</div>
			</EditorProvider>
			<CartCheckoutCompatibilityNotice blockName="checkout" />
		</>
	);
};

export default CheckoutEditor;
