import React from 'react';
import { connect } from 'react-redux';
import { dateI18n } from '@wordpress/date';
import Confetti from 'react-dom-confetti';
import fetch from 'unfetch';
import { setUserStatus } from './actions/user-actions';

const { Fragment } = wp.element;
const { __ } = wp.i18n;
const { TextControl, Dashicon, Button, ExternalLink } = wp.components;

class LicenseSettings extends React.Component {
	constructor( props ) {
		super( props );

		this.state = {
			licenseCode: '',
			licenseData: false,
			updatingLicense: false,
			licenseStatus: false,
		};

		this.confetti = false;

		// https://daniel-lundin.github.io/react-dom-confetti/?v=3
		this.confetiConfig = {
			angle: '76',
			spread: '47',
			startVelocity: 45,
			elementCount: 50,
			dragFriction: 0.1,
			duration: '4270',
			delay: 0,
			width: '10px',
			height: '10px',
			colors: [ '#a864fd', '#29cdff', '#78ff44', '#ff718d', '#fdff6a' ],
		};
	}

	componentDidMount() {
		if ( Object.keys( window.dsgnjs.license ).length ) {
			this.setState( { licenseCode: window.dsgnjs.license.license_code }, () => {
				this.setState( { licenseData: window.dsgnjs.license } );
			} );
		}
	}

	componentDidUpdate( prevProps, prevState ) {
		if ( this.state.licenseCode !== prevState.licenseCode ) {
			this.updateLicense( this.state.licenseCode );

			if ( this.state.licenseCode === '' ) {
				this.setState( { updatingLicense: false } );
			}
		}
	}

	updateLicense = newLicense => {
		// Then update license details.
		if ( newLicense.length === 32 ) {
			this.getLicenseData( newLicense );
		} else {
			this.updateLicenseStatus( { licenseCode: newLicense } );

			if ( this.state.licenseData ) {
				this.setState( { licenseData: false } );
			}
		}
	};

	updateLicenseStatus = ( {
		licenseCode = false,
		status = null,
		premiumUser = this.props.userStatus,
	} ) => {
		// Update licenseStatus to show the right actions to the user.
		if ( licenseCode && ( licenseCode.length !== 32 || 'invalid' === status ) ) {
			this.setState( { licenseStatus: 'invalid' } );
		} else if ( premiumUser && 'valid' === status ) {
			this.setState( { licenseStatus: 'active' } );
		} else if (
			'inactive' === status ||
			'site_inactive' === status ||
			( 'valid' === status && ! premiumUser )
		) {
			this.setState( { licenseStatus: 'readytoactivate' } );
		} else {
			this.setState( { licenseStatus: false } );
		}
	};

	getLicenseData = license => {
		fetch( this.getEddApiUrl( 'check_license', license ), {
			method: 'GET',
			headers: {
				'Content-Type': 'text/plain',
			},
		} ).then( response => {
			if ( response.ok ) {
				response.json().then( licenseData => {
					this.setState(
						{ licenseData: licenseData },
						this.updateLicenseStatus( { status: licenseData.license } )
					);
				} );
			} else {
				const error = new Error( response.statusText );
				error.response = response;
				// eslint-disable-next-line no-console
				console.warn( error );
			}
		} );
	};

	getEddApiUrl = ( action, licenseCode ) => {
		let actionUrl = 'https://wpdesignhub.com/?edd_action=';
		actionUrl += action;
		actionUrl +=
			'&item_id=447&license=' +
			licenseCode +
			'&url=' +
			window.location.protocol +
			'//' +
			window.location.host;
		// 'https://wpdesignhub.com/?edd_action=activate_license&item_id=447&license=' + license + '&url=' + location.protocol + "//" + location.host
		return actionUrl;
	};

	activateLicense = license => {
		this.setState( { updatingLicense: true } );

		fetch( this.getEddApiUrl( 'activate_license', license ), {
			method: 'GET',
			headers: {
				'Content-Type': 'text/plain',
			},
		} ).then( response => {
			if ( response.ok ) {
				response.json().then( licenseData => {
					if ( licenseData.license === 'valid' ) {
						this.updateLicenseInDatabase( licenseData );
						this.shootConfetti();
					}
				} );
			} else {
				const error = new Error( response.statusText );
				error.response = response;
				// eslint-disable-next-line no-console
				console.warn( error );
			}
		} );
	};

	shootConfetti = () => {
		this.confetti = true;
	};

	deactivateLicense = license => {
		this.setState( { updatingLicense: true } );

		fetch( this.getEddApiUrl( 'deactivate_license', license ), {
			method: 'GET',
			headers: {
				'Content-Type': 'text/plain',
			},
		} ).then( response => {
			if ( response.ok ) {
				response.json().then( licenseData => {
					if ( licenseData.license === 'deactivated' ) {
						this.updateLicenseInDatabase( {} );
						this.setState( { licenseCode: '' } );
					} else {
						// eslint-disable-next-line no-console
						console.warn( 'Can\'t deactivate the license.' );
						// TODO: show error to the user
					}
				} );
			} else {
				const error = new Error( response.statusText );
				error.response = response;
				// eslint-disable-next-line no-console
				console.warn( error );
			}
		} );
	};

	updateLicenseInDatabase = licenseData => {
		if ( Object.keys( licenseData ).length ) {
			// Add license code into the data set to be stored in the database.
			licenseData[ 'license_code' ] = this.state.licenseCode;
		}

		window.dsgnjs.license = licenseData; // update global data we get from php

		this.props.setUserStatusByLicense( licenseData );

		fetch( window.ajaxurl, {
			method: 'POST',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
			},
			body:
				'action=dsgn_update_license&_wpnonce=' +
				window.dsgnjs.nonce +
				'&licenseData=' +
				JSON.stringify( licenseData ),
			credentials: 'same-origin',
		} ).then( response => {
			if ( response.ok ) {
				this.setState( { updatingLicense: false } );
				this.setState(
					{ licenseData: licenseData },
					this.updateLicenseStatus( { status: licenseData.license } )
				);
				return response.json();
			}
			const error = new Error( response.statusText );
			error.response = response;
			// eslint-disable-next-line no-console
			console.warn( error );
		} );
	};

	/**
	 * Generates license upgrade URL based on current license activations limit.
	 * @memberof LicenseSettings
	 * @param {integer} currentLicenseLimit How many max active sites allowed for this license.
	 * @return {string} String with the right upgrade URL.
	 */
	getUpgradePath = currentLicenseLimit => {
		let upgradeUrl = '';
		if ( currentLicenseLimit < 3 ) {
			// Currently on Personal plan.
			// Propose to upgrade to Developer plan.
			// Personal to developer upgrade path:
			// https://wpdesignhub.com/checkout/?edd_action=sl_license_upgrade&license_id=5&upgrade_id=1

			upgradeUrl =
				'https://wpdesignhub.com/checkout/?edd_action=sl_license_upgrade&license_id=5&upgrade_id=1';
		} else if ( currentLicenseLimit < 100 ) {
			// Currently on Developer plan.
			// Propose to upgrade to Studio plan.
			// Developer to Studio upgrade path:
			// https://wpdesignhub.com/checkout/?edd_action=sl_license_upgrade&license_id=3&upgrade_id=1

			upgradeUrl =
				'https://wpdesignhub.com/checkout/?edd_action=sl_license_upgrade&license_id=3&upgrade_id=1';
		}

		return upgradeUrl;
	};

	render() {
		const licenseData = this.state.licenseData;

		return (
			<Fragment>
				<TextControl
					className="license-panel__license-code"
					label={ __( 'License' ) }
					help={ __( 'License code your received by email' ) }
					value={ this.state.licenseCode }
					onChange={ newValue => {
						this.setState( { licenseCode: newValue } );
					} }
				/>
				{ ! this.state.licenseCode && (
					<ExternalLink
						href={ __(
							'https://wpdesignhub.com/contact/?utm_source=plugin-ui&utm_medium=sidebar&utm_campaign=plugins-settigns&utm_campaign=plugin-settings'
						) }
						className="license-panel__lost-license"
					>
						{ __( 'Can\'t find your license?' ) }
					</ExternalLink>
				) }
				{ licenseData.license && licenseData.license !== 'invalid' && (
					<div>
						<ul className="dsgn-settings__data">
							<li>
								<Dashicon icon="admin-plugins" /> { __( 'Product' ) }:
								<strong>{ ' ' + licenseData.item_name }</strong>
							</li>
							<li>
								<Dashicon icon="update" /> { __( 'Expires' ) }:
								<strong>{ ' ' + dateI18n( 'M d, Y', licenseData.expires ) }</strong>
								<ExternalLink
									href={
										'https://wpdesignhub.com/checkout/?edd_license_key=' +
										this.state.licenseCode +
										'&download_id=447&utm_source=plugin-ui&utm_medium=sidebar&utm_campaign=plugins-settigns&utm_campaign=plugin-settings'
									}
									className="dsgn-settings__data-action-link"
								>
									{ __( 'renew' ) }
								</ExternalLink>
							</li>
							<li
								className={
									licenseData.activations_left === 0 ?
										'license-panel__license-limit' :
										''
								}
							>
								<Dashicon icon="admin-network" /> { __( 'Activations left' ) }:
								<strong>{ ' ' + licenseData.activations_left }</strong>
								<ExternalLink
									href={ this.getUpgradePath( licenseData.license_limit ) }
									className="dsgn-settings__data-action-link"
								>
									{ __( 'upgrade' ) }
								</ExternalLink>
							</li>
						</ul>
					</div>
				) }

				{ 'readytoactivate' === this.state.licenseStatus && (
					<div>
						<Button
							ref={ x => ( this._button_activate = x ) }
							onClick={ () => {
								this._button_activate.blur();
								this.activateLicense( this.state.licenseCode );
							} }
							className="settings__activate-license design-upsell__cta"
							isBusy={ this.state.updatingLicense }
							isDefault
							isPrimary
							isLarge
							disabled={ licenseData.activations_left === 0 }
						>
							<Dashicon icon="unlock" /> { __( 'Activate' ) }
						</Button>
					</div>
				) }

				{ 'active' === this.state.licenseStatus && (
					<div>
						<Button
							ref={ x => ( this._button_deactivate = x ) }
							onClick={ () => {
								this._button_deactivate.blur();
								this.deactivateLicense( this.state.licenseCode );
							} }
							className="settings__deactivate-license dsgn__delete-action design-upsell__cta"
							isBusy={ this.state.updatingLicense }
							isDefault
							isLarge
						>
							<Dashicon icon="no" /> { __( 'Deactivate' ) }
						</Button>
					</div>
				) }

				{ 'invalid' === this.state.licenseStatus && (
					<div className="settings__license-status invalid-license">
						<Dashicon icon="warning" /> { __( 'Not valid license.' ) }
					</div>
				) }

				<Confetti active={ this.confetti } config={ this.confetiConfig } />
			</Fragment>
		);
	}
}

export default connect(
	// mapStateToProps:
	state => ( {
		userStatus: state.user.status,
	} ),
	//mapDispatchToProps:
	dispatch => ( {
		updateUserStatus: newStatus => {
			dispatch( setUserStatus( newStatus ) );
		},
	} )
)( LicenseSettings );
