<template>
	<div class="divi-views-wizard__step plugins-step">
		<spinnerLoader :progressText="installProgressText" v-if="installInProgress" />
		<div class="plugins-step__content">

			<div class="divi-views-wizard__plugins">
				<h3>Choose plugins to install</h3>
				<div class="divi-views-wizard__plugins-list">
					<div
						class="divi-views-wizard__plugin installed-plugin"
						v-for="pluginData in installedPlugins"
						:key="pluginData.slug"
					>
						<span class="svg-icon">
							<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
								<path d="M8.72917 13.3125L14.75 7.27083L13.8542 6.375L8.72917 11.5208L6.25 9.04167L5.35417 9.9375L8.72917 13.3125ZM3.75 17.5C3.41667 17.5 3.125 17.375 2.875 17.125C2.625 16.875 2.5 16.5833 2.5 16.25V3.75C2.5 3.41667 2.625 3.125 2.875 2.875C3.125 2.625 3.41667 2.5 3.75 2.5H16.25C16.5833 2.5 16.875 2.625 17.125 2.875C17.375 3.125 17.5 3.41667 17.5 3.75V16.25C17.5 16.5833 17.375 16.875 17.125 17.125C16.875 17.375 16.5833 17.5 16.25 17.5H3.75Z" fill="#0CA64B"/>
							</svg>
						</span>
						<div class="divi-views-wizard__installed-plugin-content">
							<h4>{{ pluginData.name }}</h4>
							<p>{{ pluginData.desc_alt ? pluginData.desc_alt : pluginData.desc }}</p>
						</div>

					</div>
					<div
						class="divi-views-wizard__plugin to-install-plugin"
						:class="{ 'is-selected': toInstallList.includes(pluginData.slug) }"
						v-for="pluginData in readyToInstallPlugins"
						:key="pluginData.slug"
						@click="checkHandler( pluginData.slug )"
					>
						<span class="svg-icon">
							<svg v-if="!toInstallList.includes(pluginData.slug)" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
								<path d="M15.8333 4.16667L15.8333 15.8333L4.16667 15.8333L4.16667 4.16667L15.8333 4.16667ZM15.8333 2.5L4.16667 2.5C3.25 2.5 2.5 3.25 2.5 4.16667L2.5 15.8333C2.5 16.75 3.25 17.5 4.16667 17.5H15.8333C16.75 17.5 17.5 16.75 17.5 15.8333V4.16667C17.5 3.25 16.75 2.5 15.8333 2.5Z" fill="#94A3B8"/>
							</svg>
							<svg v-if="toInstallList.includes(pluginData.slug)" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
								<path d="M8.72917 13.3125L14.75 7.27083L13.8542 6.375L8.72917 11.5208L6.25 9.04167L5.35417 9.9375L8.72917 13.3125ZM3.75 17.5C3.41667 17.5 3.125 17.375 2.875 17.125C2.625 16.875 2.5 16.5833 2.5 16.25V3.75C2.5 3.41667 2.625 3.125 2.875 2.875C3.125 2.625 3.41667 2.5 3.75 2.5H16.25C16.5833 2.5 16.875 2.625 17.125 2.875C17.375 3.125 17.5 3.41667 17.5 3.75V16.25C17.5 16.5833 17.375 16.875 17.125 17.125C16.875 17.375 16.5833 17.5 16.25 17.5H3.75Z" fill="#0D88BF"/>
							</svg>
						</span>
						<div class="divi-views-wizard__installed-plugin-content">
							<h4>{{ pluginData.name }}</h4>
							<p>{{ pluginData.desc }}</p>
						</div>

					</div>
				</div>
			</div>

			<div class="divi-views-wizard__step-controls">
				<cx-vui-button
					button-style="accent-border"
					class="cx-vui-button--style-accent"
					size="default"
					@on-click="prevStepHandler"
				>
					<template v-slot:label>
						<span class="svg-icon">
							<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
								<path d="M15.41 7.41L14 6L8 12L14 18L15.41 16.59L10.83 12L15.41 7.41Z" fill="#0D88BF"/>
							</svg>
						</span>
						<span>Back</span>
					</template>
				</cx-vui-button>
				<cx-vui-button
					button-style="default"
					class="cx-vui-button--style-accent"
					size="default"
					:disabled="!isNextStep"
					@on-click="stepAction"
				>
					<template v-slot:label>
						<span v-if="isInstallAvaliable">Install plugins</span>
						<span v-if="!isInstallAvaliable">Next</span>
						<span class="svg-icon">
							<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
								<path d="M8.3332 5L7.1582 6.175L10.9749 10L7.1582 13.825L8.3332 15L13.3332 10L8.3332 5Z" fill="white"/>
							</svg>
						</span>
					</template>
				</cx-vui-button>
			</div>
		</div>
		<div class="plugins-step__sidebar">

		</div>
	</div>
</template>

<script>
import { mapState } from 'vuex';
import spinnerLoader from './spinnerLoader.vue';

export default {
	name: 'pluginsStep',
	components: {
		spinnerLoader
	},
	data() {
		return {
			toInstallList: [],
			installInProgress: false,
			installProgressText: '',
			installErrors: [],
			pluginActionRequest: null,
		}
	},
	mounted() {
		this.toInstallList = this.readyToInstallPlugins.map( ( pluginData ) => {
			return pluginData.slug;
		} )
	},
	computed: {
		compatibilityPlugins() {
			return this.$store.getters.getCompatibilityPlugins;
		},
		licenseCompatibilityPlugins() {
			return this.$store.getters.getLicenseCompatibilityPlugins;
		},
		compatibilityPluginSlug() {
			return this.$store.getters.getCompatibilityPluginSlug;
		},
		installedPlugins() {
			return this.compatibilityPlugins.filter( ( pluginData ) => {
				return pluginData.isInstalled;
			} );
		},
		readyToInstallPlugins(){
			return this.licenseCompatibilityPlugins.filter( ( pluginData ) => {
				return !pluginData.isInstalled;
			} );
		},
		isNextStep() {
			return 0 < this.installedPlugins.length || 0 < this.toInstallList.length;
		},
		isInstallAvaliable() {
			return 0 < this.toInstallList.length || this.installInProgress;
		},
		isJetEngineActivated() {
			const plugin = this.installedPlugins.find( p => p.slug === 'jet-engine/jet-engine.php' );

			return !! ( plugin && plugin.isInstalled && plugin.isActivated );
		}
	},
	methods: {
		stepAction() {
			if ( this.isInstallAvaliable ) {
				this.installSelectedPlugins();
			} else {
				this.nextStepHandler();
			}
		},

		nextStepHandler() {
			const nextStep = this.isJetEngineActivated ? 'modulesStep' : 'finishStep';

			if ( 'modulesStep' === nextStep ) {
				this.installProgressText = 'Opening Modules step…';
				this.installInProgress = true;

				window.setTimeout( () => {
					window.location.href = 'admin.php?page=divi-views-wizard&current-step=modulesStep';
				}, 100 );
			} else {
				this.$store.commit( 'updateStep', { step: nextStep } );
			}
		},
		prevStepHandler() {
			this.$store.commit( 'updateStep', { step: 'licenseStep' } );
		},

		doPluginAction( slug, action ) {
			const self = this;

			if ( self.pluginActionRequest !== null ) {
				try { self.pluginActionRequest.abort(); } catch ( e ) {}
				self.pluginActionRequest = null;
			}

			return new Promise((resolve, reject) => {
				self.pluginActionRequest = jQuery.ajax({
					type: 'POST',
					url: window.wizardConfig.ajaxUrl,
					dataType: 'json',
					data: {
						action: 'jet_dashboard_plugin_action',
						data: {
							action,
							plugin: slug,
							nonce: window.wizardConfig.nonce,
						}
					},
					beforeSend() {
						self.installInProgress = true;
					},
					success(res) {
						console.log(res)
						if (res && res.status === 'success') {
							self.$store.commit( 'updateCompatibilityPlugins', {
								slug: slug,
								data: res.data
							} );
							resolve(res);
						} else {
							const msg = res?.message || `Unknown error on ${action} ${slug}`;
							reject(new Error(msg));
						}
					},
					error(xhr, status, err) {
						reject(err || new Error(status || 'Network error'));
					},
					complete() {
						self.pluginActionRequest = null;
					}
				});
			});
		},

		async installSelectedPlugins() {
			if ( ! this.toInstallList.length || this.installInProgress ) return;

			this.installErrors = [];
			this.installInProgress = true;
			const total = this.toInstallList.length;

			for (let i = 0; i < total; i++) {
				const slug = this.toInstallList[i];
				const pluginData = this.getPluginDataBySlug( slug );

				// INSTALL
				this.installProgressText = `[${i + 1}/${total}] Installing ${pluginData.name}…`;

				try {
					await this.doPluginAction(slug, 'install');
				} catch (e) {
					this.installErrors.push({ slug, step: 'install', error: String(e) });
				}

				// ACTIVATE
				this.installProgressText = `[${i + 1}/${total}] Activating ${pluginData.name}…`;
				try {
					await this.doPluginAction(slug, 'activate');
				} catch (e) {
					this.installErrors.push({ slug, step: 'activate', error: String(e) });
				}
			}

			this.installProgressText = this.installErrors.length
				? `Done with errors: ${this.installErrors.length} item(s).`
				: `All done: ${total} plugin(s) installed & activated.`;

			this.installInProgress = false;

			this.nextStepHandler();
		},

		getPluginDataBySlug( slug ) {
			let index = this.compatibilityPlugins.findIndex( ( pluginData, index ) => {
				return pluginData.slug === slug;
			} );

			if ( -1 === index ) {
				return false;
			}

			return this.compatibilityPlugins[ index ];
		},


		checkHandler( slug ) {

			if ( ! slug ) return;

			const i = this.toInstallList.indexOf( slug );

			if ( i === -1 ) {
				this.toInstallList.push( slug );
			} else {
				this.toInstallList.splice(i , 1 );
			}
		}
	}
}
</script>

<style lang="scss">

.divi-views-wizard {
	&__plugins-list {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 20px;
	}

	&__plugin {
		display: flex;
		justify-content: start;
		align-items: start;
		gap: 16px;
		padding: 20px;
		border-radius: 16px;
		border: 2px solid #E2E8F0;

		&.to-install-plugin {
			cursor: pointer;

			&:hover {
				border-color: #0D88BF;
			}

			&.is-selected {
				border-color: #0D88BF;
			}
		}
	}
}

.plugins-step {
	position: relative;
	display: flex;
	justify-content: space-between;
	align-items: start;
	gap: 16px;

	&__content {
		flex: 1 1 auto;
		max-width: 660px;
	}

	&__sidebar {
		overflow: hidden;
		border-radius: 20px;
	}
}

</style>
