import { getRedirectUrl } from '@automattic/jetpack-components';
import { formatNumber } from '@automattic/number-formatters';
import { createInterpolateElement } from '@wordpress/element';
import { __, _x, _n, sprintf } from '@wordpress/i18n';
import { info } from '@wordpress/icons';
import PropTypes from 'prop-types';
import { Component } from 'react';
import { connect } from 'react-redux';
import Banner from 'components/banner';
import Card from 'components/card';
import QueryRewindStatus from 'components/data/query-rewind-status';
import { withModuleSettingsFormHelpers } from 'components/module-settings/with-module-settings-form-helpers';
import SettingsCard from 'components/settings-card';
import SettingsGroup from 'components/settings-group';
import analytics from 'lib/analytics';
import { FEATURE_SECURITY_SCANNING_JETPACK } from 'lib/plans/constants';
import { getVaultPressData, getVaultPressScanThreatCount } from 'state/at-a-glance';
import { showBackups } from 'state/initial-state';
import { isModuleActivated } from 'state/modules';
import { isFetchingRewindStatus } from 'state/rewind';
import { siteHasFeature } from 'state/site';

class LoadingCard extends Component {
	render() {
		return (
			<SettingsCard
				header={ _x( 'Backups and security scanning', 'Settings header', 'jetpack' ) }
				hideButton
				action="scan"
			>
				<SettingsGroup
					disableInOfflineMode
					module={ { module: 'backups' } }
					support={ {
						text: __(
							'Backs up your site to the global WordPress.com servers, allowing you to restore your content in the event of an emergency or error.',
							'jetpack'
						),
						link: getRedirectUrl( 'vaultpress-help-get-to-know' ),
					} }
				>
					{ __( 'Checking site status…', 'jetpack' ) }
				</SettingsGroup>
			</SettingsCard>
		);
	}
}

class BackupsScanRewind extends Component {
	static propTypes = {
		isOfflineMode: PropTypes.bool,
		siteRawUrl: PropTypes.string,
		rewindState: PropTypes.string,
	};

	static defaultProps = {
		isOfflineMode: false,
		siteRawUrl: '',
		rewindState: '',
	};

	getRewindMessage() {
		const { siteRawUrl, rewindState } = this.props;

		switch ( rewindState ) {
			case 'provisioning':
				return {
					title: __( 'Provisioning', 'jetpack' ),
					icon: 'info',
					description: __( 'Backups and Scan are being configured for your site.', 'jetpack' ),
					url: '',
				};
			case 'awaiting_credentials':
				return {
					title: __( 'Awaiting credentials', 'jetpack' ),
					iconWp: info,
					type: 'warning',
					description: __(
						'Enter your SSH, SFTP, or FTP credentials to enable one-click site restores and fixes',
						'jetpack'
					),
					url: getRedirectUrl( 'jetpack-settings-security-credentials', { site: siteRawUrl } ),
				};
			case 'active':
				return {
					title: __( 'Active', 'jetpack' ),
					icon: 'checkmark-circle',
					description: __( 'Your site is connected to Jetpack Backup and Scan.', 'jetpack' ),
					url: getRedirectUrl( 'calypso-activity-log', { site: siteRawUrl } ),
				};
			default:
				return {
					title: __( 'Oops!', 'jetpack' ),
					icon: 'info',
					description: __(
						'The Jetpack Backup and Scan status could not be retrieved at this time.',
						'jetpack'
					),
					url: '',
				};
		}
	}

	getCardText = () => {
		if ( this.props.isOfflineMode ) {
			return __( 'Unavailable in Offline Mode.', 'jetpack' );
		}

		const { title, icon, iconWp, description, type, url } = this.getRewindMessage();

		return (
			<Banner
				title={ title }
				icon={ icon }
				iconWp={ iconWp }
				feature={ 'rewind' }
				description={ description }
				className={ `jp-banner__no-border is-jetpack-${ type ? type : 'info' }` }
				href={ url }
			/>
		);
	};

	render() {
		return (
			<SettingsCard
				feature={ 'rewind' }
				{ ...this.props }
				header={ _x( 'Backups and security scanning', 'Settings header', 'jetpack' ) }
				action={ 'rewind' }
				hideButton
			>
				{ this.getCardText() }
			</SettingsCard>
		);
	}
}

export const BackupsScan = withModuleSettingsFormHelpers(
	class extends Component {
		toggleModule = ( name, value ) => {
			this.props.updateFormStateOptionValue( name, ! value );
		};

		trackConfigureClick = () => {
			analytics.tracks.recordJetpackClick( 'configure-scan' );
		};

		getCardText() {
			if ( this.props.isOfflineMode ) {
				return __( 'Unavailable in Offline Mode.', 'jetpack' );
			}

			const backupsEnabled = this.props.vaultPressData?.data?.features?.backups ?? false,
				scanEnabled = this.props.vaultPressData?.data?.features?.security ?? false;

			// We check if the features are active first, rather than the plan because it's possible the site is on a
			// VP-only plan, purchased before Jetpack plans existed.
			if ( backupsEnabled && scanEnabled ) {
				const threats = this.props.hasThreats;
				if ( threats ) {
					return (
						<div>
							<strong>
								{ sprintf(
									/* Translators: %s: the number of threats. */
									_n( 'Uh oh, %s threat found.', 'Uh oh, %s threats found.', threats, 'jetpack' ),
									formatNumber( threats )
								) }
							</strong>
							<br />
							<br />
							{ createInterpolateElement( __( '<a>View details</a>', 'jetpack' ), {
								a: <a href={ getRedirectUrl( 'vaultpress-dashboard' ) } />,
							} ) }
							<br />
							{ createInterpolateElement( __( '<a>Contact Support</a>', 'jetpack' ), {
								a: <a href={ getRedirectUrl( 'jetpack-support' ) } />,
							} ) }
						</div>
					);
				}
				return __(
					'Your site is connected to VaultPress for backups and security scanning.',
					'jetpack'
				);
			}

			// Only return here if backups are enabled and site doesn't have scan.
			if ( backupsEnabled && ! this.props.hasScan ) {
				return __( 'Your site is connected to VaultPress for backups.', 'jetpack' );
			}

			if ( this.props.isFetchingRewindStatus ) {
				return __( 'Checking site status…', 'jetpack' );
			}

			return __(
				'The Jetpack Backup and Scan status could not be retrieved at this time.',
				'jetpack'
			);
		}

		render() {
			if ( ! this.props.showBackups ) {
				return null;
			}

			const scanEnabled = this.props.vaultPressData?.data?.features?.security ?? false;
			const rewindState = this.props.rewindStatus?.state ?? false;
			const hasRewindData = false !== rewindState;
			const hasVpData =
				this.props.vaultPressData !== 'N/A' &&
				false !== ( this.props.vaultPressData?.data ?? false );

			if ( ! hasRewindData && this.props.vaultPressActive && ! hasVpData ) {
				return <LoadingCard />;
			}

			// Backup & Scan is working in this site.
			if ( [ 'provisioning', 'awaiting_credentials', 'active' ].includes( rewindState ) ) {
				return <BackupsScanRewind { ...this.props } rewindState={ rewindState } />;
			}

			return (
				<SettingsCard
					feature={ FEATURE_SECURITY_SCANNING_JETPACK }
					{ ...this.props }
					header={ _x( 'Backups and security scanning', 'Settings header', 'jetpack' ) }
					action="scan"
					hideButton
				>
					<QueryRewindStatus />
					<SettingsGroup
						disableInOfflineMode
						module={ { module: 'backups' } }
						support={ {
							text: __(
								'Backs up your site to the global WordPress.com servers, allowing you to restore your content in the event of an emergency or error.',
								'jetpack'
							),
							link: getRedirectUrl( 'vaultpress-help-get-to-know' ),
						} }
					>
						{ this.getCardText() }
					</SettingsGroup>
					{ ! this.props.isUnavailableInOfflineMode( 'backups' ) && scanEnabled && (
						<Card
							compact
							className="jp-settings-card__configure-link"
							onClick={ this.trackConfigureClick }
							target="_blank"
							href={ getRedirectUrl( 'vaultpress-dashboard' ) }
						>
							{ __( 'Configure your Security Scans', 'jetpack' ) }
						</Card>
					) }
				</SettingsCard>
			);
		}
	}
);

export default connect( state => {
	return {
		vaultPressData: getVaultPressData( state ),
		hasScan: siteHasFeature( state, 'scan' ),
		hasThreats: getVaultPressScanThreatCount( state ),
		vaultPressActive: isModuleActivated( state, 'vaultpress' ),
		showBackups: showBackups( state ),
		isFetchingRewindStatus: isFetchingRewindStatus( state ),
	};
} )( BackupsScan );
