/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { Modal, Button, TextareaControl } from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { useState, useEffect } from '@wordpress/element';
import { recordEvent } from '@woocommerce/tracks';

/**
 * Internal dependencies
 */
import './feedback-modal.scss';
import LikertScale from '../likert-scale/likert-scale';
import sanitizeHTML from '../../../lib/sanitize-html';

export default function FeedbackModal(): JSX.Element {
	const CUSTOMER_EFFORT_SCORE_ACTION = 'marketplace_redesign_2023';
	const LOCALSTORAGE_KEY_DISMISSAL_COUNT =
		'marketplace_redesign_2023_dismissals'; // ensure we don't ask for feedback if the user's already given feedback or declined to multiple times
	const LOCALSTORAGE_KEY_LAST_REQUESTED_DATE =
		'marketplace_redesign_2023_last_shown_date'; // ensure we don't ask for feedback more than once per day
	const SUPPRESS_IF_DISMISSED_X_TIMES = 1; // if the user dismisses the snackbar this many times, stop asking for feedback
	const SUPPRESS_IF_AFTER_DATE = '2024-01-01'; // if this date is reached, stop asking for feedback

	// Save that we dismissed the dialog or snackbar TODAY so we don't show it again until tomorrow (if ever)
	const dismissToday = () =>
		localStorage.setItem(
			LOCALSTORAGE_KEY_LAST_REQUESTED_DATE,
			new Date().toDateString()
		);

	// Returns the number of times that the request for feedback has been dismissed
	const dismissedTimes = () =>
		parseInt(
			localStorage.getItem( LOCALSTORAGE_KEY_DISMISSAL_COUNT ) || '0',
			10
		);

	// Increment the number of times that the request for feedback has been dismissed
	const incrementDismissedTimes = () => {
		dismissToday();
		localStorage.setItem(
			LOCALSTORAGE_KEY_DISMISSAL_COUNT,
			`${ dismissedTimes() + 1 }`
		);
	};

	// Dismiss forever (by incrementing the number of dismissals to a high number), e.g. when feedback is provided
	const dismissForever = () => {
		dismissToday();
		localStorage.setItem(
			LOCALSTORAGE_KEY_DISMISSAL_COUNT,
			`${ SUPPRESS_IF_DISMISSED_X_TIMES }`
		);
	};

	// Returns true if dismissed forever (either by dismissing at least SUPPRESS_IF_DISMISSED_X_TIMES times, or by submitting feedback)
	const isDismissedForever = () =>
		dismissedTimes() >= SUPPRESS_IF_DISMISSED_X_TIMES;

	const [ isOpen, setOpen ] = useState( false );
	const [ thoughts, setThoughts ] = useState( '' );
	const [ easyToFind, setEasyToFind ] = useState( 0 );
	const [ easyToFindValidiationFailed, setEasyToFindValidiationFailed ] =
		useState( false );
	const [ meetsMyNeeds, setMeetsMyNeeds ] = useState( 0 );
	const [ meetsMyNeedsValidiationFailed, setMeetsMyNeedsValidiationFailed ] =
		useState( false );
	const openModal = () => setOpen( true );
	const closeModal = () => {
		incrementDismissedTimes();
		setOpen( false );
	};
	const { createNotice } = useDispatch( 'core/notices' );

	function maybeShowSnackbar() {
		// don't show if the user has already given feedback or otherwise suppressed:
		if ( isDismissedForever() ) {
			return;
		}

		// don't show if the user has already declined to provide feedback today:
		const today = new Date().toDateString();
		if (
			today ===
			localStorage.getItem( LOCALSTORAGE_KEY_LAST_REQUESTED_DATE )
		) {
			return;
		}

		createNotice(
			'success',
			__( 'How easy is it to find an extension?', 'woocommerce' ),
			{
				type: 'snackbar',
				icon: (
					<>
						<svg
							color="#fff"
							strokeWidth="1.5"
							viewBox="0 0 28.873 8.9823"
							style={ { height: '8px', marginLeft: '-7px' } }
						>
							<path
								className="l"
								d="m4.1223 1.1216 19.12-0.014142 4.3982 3.38-4.3982 3.38-19.12-0.014142a3.34 3.34 0 0 1-2.39-0.97581 3.37 3.37 0 0 1 0.00707-4.773 3.34 3.34 0 0 1 2.383-0.98288z"
								stroke="#fff"
							/>
							<line
								className="l"
								x1="6.7669"
								x2="6.7669"
								y1="7.8533"
								y2="1.1216"
								stroke="#fff"
							/>
							<path
								className="l"
								d="m23.235 1.1146 4.4053 3.3729-4.3982 3.38a6.59 6.59 0 0 1-0.89096-3.3517 6.59 6.59 0 0 1 0.88388-3.4012z"
								stroke="#fff"
							/>
							<line
								className="l"
								x1="6.7669"
								x2="22.323"
								y1="4.4875"
								y2="4.4875"
								stroke="#fff"
							/>
						</svg>
					</>
				),
				explicitDismiss: true,
				onDismiss: incrementDismissedTimes,
				actions: [
					{
						onClick: openModal,
						label: 'Give feedback',
					},
				],
			}
		);
	}

	// eslint-disable-next-line react-hooks/exhaustive-deps -- [] => we only want this effect to run once, on first render
	useEffect( maybeShowSnackbar, [] );

	// We don't want the "How easy was it to find an extension?" dialog to appear forever:
	const FEEDBACK_DIALOG_CAN_APPEAR =
		new Date( SUPPRESS_IF_AFTER_DATE ) > new Date();
	if ( ! FEEDBACK_DIALOG_CAN_APPEAR ) {
		return <></>;
	}

	function easyToFindChanged( value: number ) {
		setEasyToFindValidiationFailed( false );
		setEasyToFind( value );
	}

	function meetsMyNeedsChanged( value: number ) {
		setMeetsMyNeedsValidiationFailed( false );
		setMeetsMyNeeds( value );
	}

	function submit() {
		// Validate:
		if ( easyToFind === 0 || meetsMyNeeds === 0 ) {
			if ( easyToFind === 0 ) setEasyToFindValidiationFailed( true );
			if ( meetsMyNeeds === 0 ) setMeetsMyNeedsValidiationFailed( true );
			return;
		}

		const comments = sanitizeHTML( thoughts ).__html;

		// Send event to CES:
		recordEvent( 'ces_feedback', {
			action: CUSTOMER_EFFORT_SCORE_ACTION,
			score: easyToFind,
			score_second_question: meetsMyNeeds,
			score_combined: easyToFind + meetsMyNeeds,
			comments,
		} );
		// Close the modal:
		setOpen( false );
		// Ensure we don't ask for feedback again:
		dismissForever();
	}

	return (
		<>
			{ isOpen && (
				<Modal
					title={ __(
						'How easy was it to find an extension?',
						'woocommerce'
					) }
					onRequestClose={ closeModal }
					className="woocommerce-marketplace__feedback-modal"
				>
					<p>
						{ __(
							'Your feedback will help us create a better experience for people like you! Please tell us to what extent you agree or disagree with the statements below.',
							'woocommerce'
						) }
					</p>
					<LikertScale
						fieldName="extension_screen_easy_to_find"
						title={ __(
							'It was easy to find an extension',
							'woocommerce'
						) }
						onValueChange={ easyToFindChanged }
						validationFailed={ easyToFindValidiationFailed }
					/>
					<LikertScale
						fieldName="extension_screen_meets_my_needs"
						title={ __(
							'The Extensions screen’s functionality meets my needs',
							'woocommerce'
						) }
						onValueChange={ meetsMyNeedsChanged }
						validationFailed={ meetsMyNeedsValidiationFailed }
					/>
					<TextareaControl
						label={ __( 'Additional thoughts', 'woocommerce' ) }
						value={ thoughts }
						onChange={ ( value: string ) => setThoughts( value ) }
					/>
					<p className="woocommerce-marketplace__feedback-modal-buttons">
						<Button
							variant="tertiary"
							onClick={ closeModal }
							text={ __( 'Cancel', 'woocommerce' ) }
						/>
						<Button
							variant="primary"
							onClick={ submit }
							text={ __( 'Send', 'woocommerce' ) }
						/>
					</p>
				</Modal>
			) }
		</>
	);
}
