<?php

namespace NeurogenesisTheme\Helpers;

defined( 'ABSPATH' ) || exit;

/**
 * Recommended plugin card data and install/activate from WordPress.org.
 */
final class RecommendedPlugin {

	public const SLUG = 'neurogenesis-styler';

	private const INSTALL_LOCK_KEY = 'neurogenesis_theme_installing_neurogenesis_styler';

	private const FALLBACK_DOWNLOAD_URL = 'https://downloads.wordpress.org/plugin/neurogenesis-styler.latest-stable.zip';

	/**
	 * @return array{slug:string,name:string,status:string,status_label:string,action_label:string}
	 */
	public static function get_card_data(): array {
		$status = self::get_status();

		$labels = array(
			'not_installed' => __( 'Not Installed', 'thinko' ),
			'inactive'      => __( 'Installed', 'thinko' ),
			'active'        => __( 'Active', 'thinko' ),
		);

		$action_labels = array(
			'not_installed' => __( 'Install & Activate', 'thinko' ),
			'inactive'      => __( 'Activate', 'thinko' ),
			'active'        => '',
		);

		return array(
			'slug'         => self::SLUG,
			'name'         => __( 'Neurogenesis Styler', 'thinko' ),
			'status'       => $status,
			'status_label' => $labels[ $status ] ?? $labels['not_installed'],
			'action_label' => $action_labels[ $status ] ?? '',
		);
	}

	public static function get_status(): string {
		// Constants are defined by the plugin bootstrap — reliable even if the
		// folder slug differs from neurogenesis-styler/.
		if ( defined( 'NEUROGENESIS_PATH' ) || defined( 'NEUROGENESIS_VERSION' ) ) {
			return 'active';
		}

		$basename = self::get_plugin_basename();

		if ( ! $basename ) {
			return 'not_installed';
		}

		self::ensure_plugin_functions();

		return is_plugin_active( $basename ) ? 'active' : 'inactive';
	}

	public static function get_plugin_basename(): ?string {
		self::ensure_plugin_functions();

		$folder = self::SLUG . '/';

		foreach ( array_keys( get_plugins() ) as $file ) {
			if ( str_starts_with( $file, $folder ) ) {
				return $file;
			}
		}

		return null;
	}

	/**
	 * @return array{status:string,message:string,installed?:bool}|\WP_Error
	 */
	public static function install_and_activate() {
		$basename = self::get_plugin_basename();

		if ( $basename && self::get_status() === 'active' ) {
			return array(
				'status'  => 'active',
				'message' => __( 'Plugin is already active.', 'thinko' ),
			);
		}

		// Already on disk: activate only (no install_plugins cap required).
		if ( $basename ) {
			return self::activate( $basename );
		}

		if ( ! current_user_can( 'install_plugins' ) ) {
			return new \WP_Error(
				'forbidden',
				__( 'You do not have permission to install plugins.', 'thinko' )
			);
		}

		if ( ! self::acquire_install_lock() ) {
			return new \WP_Error(
				'install_in_progress',
				__( 'Installation is already in progress. Please wait a moment and try again.', 'thinko' )
			);
		}

		try {
			$install_result = self::install();
			if ( is_wp_error( $install_result ) ) {
				return $install_result;
			}

			$basename = self::get_plugin_basename();
			if ( ! $basename ) {
				return new \WP_Error(
					'not_found',
					__( 'Plugin was installed but could not be located.', 'thinko' )
				);
			}

			return self::activate( $basename, true );
		} finally {
			self::release_install_lock();
		}
	}

	/**
	 * @return true|\WP_Error
	 */
	private static function install() {
		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';
		self::ensure_plugin_functions();

		$download_url = self::get_download_url();
		if ( is_wp_error( $download_url ) ) {
			return $download_url;
		}

		$skin     = new \Automatic_Upgrader_Skin();
		$upgrader = new \Plugin_Upgrader( $skin );
		$result   = $upgrader->install( $download_url );

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

		if ( false === $result ) {
			$error_message = __( 'Plugin installation failed.', 'thinko' );
			$skin_errors   = $skin->get_errors();

			if ( is_wp_error( $skin_errors ) && $skin_errors->get_error_message() ) {
				$error_message = $skin_errors->get_error_message();
			}

			return new \WP_Error( 'install_failed', $error_message );
		}

		return true;
	}

	/**
	 * @return string|\WP_Error
	 */
	private static function get_download_url() {
		$api = plugins_api(
			'plugin_information',
			array(
				'slug'   => self::SLUG,
				'fields' => array(
					'sections' => false,
				),
			)
		);

		if ( ! is_wp_error( $api ) && ! empty( $api->download_link ) ) {
			return $api->download_link;
		}

		return self::FALLBACK_DOWNLOAD_URL;
	}

	/**
	 * @return array{status:string,message:string,installed?:bool}|\WP_Error
	 */
	private static function activate( string $basename, bool $just_installed = false ) {
		if ( ! current_user_can( 'activate_plugins' ) ) {
			return new \WP_Error(
				'forbidden',
				__( 'You do not have permission to activate plugins.', 'thinko' )
			);
		}

		self::ensure_plugin_functions();

		$result = activate_plugin( $basename );
		if ( is_wp_error( $result ) ) {
			if ( self::get_plugin_basename() ) {
				return array(
					'status'    => 'inactive',
					'installed' => true,
					'message'   => sprintf(
						/* translators: %s: activation error message */
						__( 'Plugin installed, but activation failed: %s', 'thinko' ),
						$result->get_error_message()
					),
				);
			}

			return $result;
		}

		if ( $just_installed ) {
			return array(
				'status'  => 'active',
				'message' => __( 'Neurogenesis Styler is installed and active.', 'thinko' ),
			);
		}

		return array(
			'status'  => 'active',
			'message' => __( 'Neurogenesis Styler is now active.', 'thinko' ),
		);
	}

	private static function ensure_plugin_functions(): void {
		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}
	}

	private static function acquire_install_lock(): bool {
		if ( get_transient( self::INSTALL_LOCK_KEY ) ) {
			return false;
		}

		set_transient( self::INSTALL_LOCK_KEY, '1', 60 );

		return true;
	}

	private static function release_install_lock(): void {
		delete_transient( self::INSTALL_LOCK_KEY );
	}
}
