import { Fragment, isValidElement } from '@wordpress/element';
import {
	__experimentalDivider as Divider,
	__experimentalHeading as Heading,
	__experimentalSpacer as Spacer,
	__experimentalText as Text,
	Button,
	Flex,
	FlexBlock,
	Modal,
	Notice,
	ProgressBar,
	Tooltip,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { hasLabelExpired } from 'utils';
import { useLabelPurchaseContext } from 'context/label-purchase';
import { SchedulePickup } from './schedule-pickup';
import { TrackShipment } from './track-shipment';
import { RefundShipment } from './refund-shipment';
import { withBoundary } from 'components/HOC';
import { CommercialInvoice } from './commercial-invoice';
import { LegacyWarning } from './legacy-warning';
import { PrintPackingSlipButton } from '../print-packing-slip-button';
import { PrintLabelButton } from './print-label-button';
import { ReturnLabelButton } from './return-label-button';
import { Label } from 'types';

export const PurchaseNotice = withBoundary( () => {
	const {
		labels: {
			isPurchasing,
			isUpdatingStatus,
			isRefunding,
			hasPurchasedLabel,
			updatePurchaseStatus,
			getCurrentShipmentLabel,
			labelStatusUpdateErrors,
			isAnyRequestInProgress,
		},
		shipment: { isShipmentAutogeneratedFromLabel },
		rates: { getSelectedRate },
		shipment: {
			shipments,
			setShipments,
			currentShipmentId,
			setCurrentShipmentId,
			getShipmentOrigin,
			getShipmentDestination,
			setReturnShipments,
			returnShipments,
			selections,
			setSelection,
			getCurrentShipmentIsReturn,
		},
		packages,
		nextDesign,
	} = useLabelPurchaseContext();

	const selectedLabel = getCurrentShipmentLabel();
	const isReturn = getCurrentShipmentIsReturn();
	const hasLabel = hasPurchasedLabel();

	const refreshStatus = async () => {
		if ( ! selectedLabel ) {
			return;
		}
		await updatePurchaseStatus( selectedLabel.labelId );
	};

	let purchaseResultTitleText = __(
		'There was an issue processing your purchase',
		'woocommerce-shipping'
	);

	if ( hasLabel && labelStatusUpdateErrors.length === 0 ) {
		purchaseResultTitleText = __(
			'Your shipping label is ready to print',
			'woocommerce-shipping'
		);
	}

	const isDomesticShipment = () => {
		const origin = getShipmentOrigin();
		const destination = getShipmentDestination();
		return origin?.country === 'US' && destination?.country === 'US';
	};

	const selectedRate = getSelectedRate();

	return nextDesign && isAnyRequestInProgress ? (
		<>
			{
				// TODO: We need to use inline classes because we don't load css files on next-admin.
				// One way to solve this is including the classes in next admin,
				// and use those classes in the shipping plugin.
			 }
			<style>
				{ `
				.woocommerce-shipping__progressbar {
					width: 307.2px;
				}
			` }
			</style>
			<Modal
				onRequestClose={ () => {
					/* noop */
				} }
				isDismissible={ false }
				size="medium"
				__experimentalHideHeader
				shouldCloseOnClickOutside={ false }
				shouldCloseOnEsc={ false }
			>
				<Flex
					align="center"
					justify="center"
					gap={ 4 }
					direction="column"
					style={ { padding: '100px 0' } }
				>
					<Text size={ 15 } weight={ 500 } lineHeight={ '20px' }>
						{ __(
							'Processing your order',
							'woocommerce-shipping'
						) }
					</Text>
					<ProgressBar className="woocommerce-shipping__progressbar" />
					<Text size={ 13 } weight={ 400 } lineHeight={ '20px' }>
						{ __( 'Just a brief moment', 'woocommerce-shipping' ) }
					</Text>
				</Flex>
			</Modal>
		</>
	) : (
		<>
			<Heading level={ 3 }>
				{ isPurchasing || isUpdatingStatus
					? __(
							'Please wait while we process your shipping label purchase',
							'woocommerce-shipping'
					  )
					: purchaseResultTitleText }
			</Heading>
			<Spacer margin={ 7 } />
			{ isShipmentAutogeneratedFromLabel() && (
				<>
					<p className="description">
						{ __(
							'This shipping label was created via the mobile app and may include item differences. All original order items are still included in this shipment.',
							'woocommerce-shipping'
						) }
					</p>
					<Spacer margin={ 7 } />
				</>
			) }
			<Notice
				status={ hasLabel ? 'success' : 'warning' }
				className="purchase-notice"
				isDismissible={ false }
				spokenMessage={
					/**
					 * We need to override the default spoken message so that the children are not conditionally rendered via a hook.
					 * Conditional hooks are not allowed in React and cause an error.
					 */
					__(
						'You have successfully requested to purchase a shipping label.',
						'woocommerce-shipping'
					)
				}
			>
				<Flex direction="column">
					<p>
						{ hasLabel
							? __(
									'From here you can print the shipping label again or change the paper size of the label.',
									'woocommerce-shipping'
							  )
							: __(
									'You have purchased a label, but the purchase status is still pending. Please wait a few minutes and refresh the purchase status. If the status is still pending, please contact support.',
									'woocommerce-shipping'
							  ) }
					</p>
					<FlexBlock className="purchase-notice-actions">
						<Flex gap={ 2 } justify="flex-start">
							{ hasLabel && (
								<>
									<PrintPackingSlipButton key="print-packing-slip" />
									<Tooltip
										placement="top"
										text={
											hasLabelExpired( selectedLabel )
												? __(
														'Label images older than 180 days are deleted by our technology partners for general security and data privacy concerns.',
														'woocommerce-shipping'
												  )
												: ''
										}
									>
										<PrintLabelButton key="print-label" />
									</Tooltip>
								</>
							) }
							{ ! hasLabel && (
								<Button
									variant="secondary"
									onClick={ refreshStatus }
									isBusy={ isPurchasing || isUpdatingStatus }
									aria-busy={
										isPurchasing || isUpdatingStatus
									}
									disabled={
										isPurchasing || isUpdatingStatus
									}
								>
									{ __(
										'Refresh purchase status',
										'woocommerce-shipping'
									) }
								</Button>
							) }
						</Flex>
						<Spacer marginBottom="4" />
						{ hasLabel && (
							<Flex justify="flex-start">
								{ [
									<TrackShipment
										key="track-shipment"
										// @ts-expect-error // Conditional is written in js
										label={ selectedLabel }
									/>,
									! isReturn && (
										<SchedulePickup
											key="schedule-pickup"
											selectedLabel={ selectedLabel }
										/>
									),
									<CommercialInvoice
										key="commercial-invoice"
										label={ selectedLabel }
									/>,
									<RefundShipment
										key="refund-shipment"
										label={ selectedLabel }
										selectedRate={ selectedRate }
										isBusy={ isRefunding }
										isDisabled={
											isRefunding ||
											isPurchasing ||
											isUpdatingStatus
										}
									/>,
									! isReturn && (
										<ReturnLabelButton
											key="return-label"
											isDomesticShipment={ isDomesticShipment() }
											shipments={ shipments }
											currentShipmentId={
												currentShipmentId
											}
											setShipments={ setShipments }
											setCurrentShipmentId={
												setCurrentShipmentId
											}
											setReturnShipments={
												setReturnShipments
											}
											returnShipments={ returnShipments }
											packages={ packages }
											selections={ selections }
											setSelection={ setSelection }
										/>
									),
								]
									.filter( ( btn ) => {
										if ( ! isValidElement( btn ) ) {
											return false;
										}

										if (
											btn.key === 'commercial-invoice' &&
											( btn.props as { label?: Label } )
												?.label
												?.commercialInvoiceUrl === ''
										) {
											return false;
										}

										// Always render components with hooks, let them handle their own conditional logic
										return true;
									} ) // Filter out null or invalid elements
									.map( ( btn, index ) => (
										<Fragment key={ index }>
											{ index !== 0 && (
												<Divider
													orientation="vertical"
													margin="0"
												/>
											) }
											{ btn }
										</Fragment>
									) ) }
							</Flex>
						) }
						{ ! hasLabel &&
							labelStatusUpdateErrors &&
							labelStatusUpdateErrors.length > 0 && (
								<Notice
									status="error"
									isDismissible={ false }
									className="purchase-error-notice"
								>
									{ labelStatusUpdateErrors.map(
										( message, index ) => (
											<p key={ index }>{ message }</p>
										)
									) }
								</Notice>
							) }
					</FlexBlock>
				</Flex>
				{ selectedLabel?.isLegacy && <LegacyWarning /> }
			</Notice>
			<Flex>
				<p className="label-purchase-note">
					{ __(
						'Note: Reusing a printed label is a violation of our terms of service and may result in criminal charges.',
						'woocommerce-shipping'
					) }
				</p>
			</Flex>
		</>
	);
} )( 'PurchaseNotice' );
