<?php

namespace SugarCalendarBookings\SetupWizard;

use Plugin_Upgrader;
use SugarCalendarBookings\Support\Helpers\Helpers;
use WP_Ajax_Upgrader_Skin;
use WP_Error;

/**
 * Class PluginInstallerService.
 *
 * Handles plugin installation and detection for Setup Wizard.
 *
 * @since 1.2.0
 */
class PluginInstallerService {

	/**
	 * Known SMTP plugins.
	 *
	 * @since 1.2.0
	 *
	 * @var array Plugin slug => plugin file path(s).
	 */
	private const SMTP_PLUGINS = [
		'wp-mail-smtp' => [
			'wp-mail-smtp/wp_mail_smtp.php',
			'wp-mail-smtp-pro/wp_mail_smtp.php',
		],
	];

	/**
	 * Install and activate plugins.
	 *
	 * @since 1.2.0
	 *
	 * @param array $plugins Array of plugin slugs to install.
	 *
	 * @return array Result with 'installed' and 'errors' keys.
	 */
	public function install( $plugins ) {

		$this->include_dependencies();

		$installed = [];
		$errors    = [];

		foreach ( $plugins as $plugin_slug ) {
			$result = $this->install_single( $plugin_slug );

			if ( is_wp_error( $result ) ) {
				$errors[ $plugin_slug ] = $result->get_error_message();
			} else {
				$installed[] = $plugin_slug;
			}
		}

		return [
			'installed' => $installed,
			'errors'    => $errors,
		];
	}

	/**
	 * Detect installed and active SMTP plugins.
	 *
	 * @since 1.2.0
	 *
	 * @return array Array of active SMTP plugin slugs.
	 */
	public function detect_smtp_plugins() {

		$active = [];

		foreach ( self::SMTP_PLUGINS as $plugin_slug => $plugin_files ) {
			// Handle both single plugin file and array of files (Lite/Pro versions).
			$files = is_array( $plugin_files ) ? $plugin_files : [ $plugin_files ];

			foreach ( $files as $plugin_file ) {
				if ( is_plugin_active( $plugin_file ) ) {
					$active[] = $plugin_slug;

					break; // Only add the slug once if either version is active.
				}
			}
		}

		return $active;
	}

	/**
	 * Install a single plugin.
	 *
	 * @since 1.2.0
	 *
	 * @param string $plugin_slug Plugin slug.
	 *
	 * @return true|WP_Error True on success, WP_Error on failure.
	 */
	private function install_single( $plugin_slug ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		$api = plugins_api(
			'plugin_information',
			[
				'slug'   => $plugin_slug,
				'fields' => [
					'short_description' => false,
					'sections'          => false,
					'requires'          => false,
					'rating'            => false,
					'ratings'           => false,
					'downloaded'        => false,
					'last_updated'      => false,
					'added'             => false,
					'tags'              => false,
					'compatibility'     => false,
					'homepage'          => false,
					'donate_link'       => false,
				],
			]
		);

		if ( is_wp_error( $api ) ) {
			return $api;
		}

		$upgrader = new Plugin_Upgrader( new WP_Ajax_Upgrader_Skin() );
		$result   = $upgrader->install( $api->download_link );

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		if ( ! $result ) {
			return $this->get_upgrader_error( $upgrader );
		}

		// Activate the plugin.
		$plugin_file = $upgrader->plugin_info();

		if ( $plugin_file ) {
			// Prevent WP Mail SMTP setup wizard from redirecting after activation.
			if ( $plugin_slug === 'wp-mail-smtp' ) {
				update_option( 'wp_mail_smtp_activation_prevent_redirect', true );
			}

			$activation_result = activate_plugin( $plugin_file );

			if ( is_wp_error( $activation_result ) ) {
				return $activation_result;
			}
		}

		return true;
	}

	/**
	 * Get error from upgrader skin.
	 *
	 * @since 1.2.0
	 *
	 * @param Plugin_Upgrader $upgrader Plugin upgrader instance.
	 *
	 * @return WP_Error
	 */
	private function get_upgrader_error( $upgrader ) {

		$skin_errors = $upgrader->skin->get_errors();

		if ( is_wp_error( $skin_errors ) && $skin_errors->has_errors() ) {
			return $skin_errors;
		}

		return new WP_Error(
			'installation_failed',
			__( 'Plugin installation failed.', 'sugar-calendar-bookings-scheduling-appointments-lite' )
		);
	}

	/**
	 * Include required WordPress dependencies for plugin installation.
	 *
	 * @since 1.2.0
	 */
	private function include_dependencies() {

		require_once ABSPATH . 'wp-admin/includes/file.php';
		require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
		require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
		require_once ABSPATH . 'wp-admin/includes/plugin.php';

		Helpers::include_plugin_upgrader();
	}
}
