<?php
/**
 * PufferGo Plugin Setup
 *
 * Thin WordPress-side integration for scenario-based plugin recommendations:
 * - fetch config from siteForge /api/wp-plugin/config
 * - merge local plugin install status
 * - install and activate selected plugins locally
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class PufferGo_Plugin_Setup {

	public function __construct() {
		add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
	}

	public function register_rest_routes() {
		register_rest_route(
			'puffergo/v1',
			'/plugin-setup/config',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'rest_config' ),
				'permission_callback' => array( $this, 'can_manage_plugins' ),
			)
		);

		register_rest_route(
			'puffergo/v1',
			'/plugin-setup/install',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'rest_install' ),
				'permission_callback' => array( $this, 'can_manage_plugins' ),
			)
		);
	}

	public function can_manage_plugins() {
		return current_user_can( 'install_plugins' );
	}

	public function rest_config() {
		$config = $this->fetch_remote_config();
		if ( is_wp_error( $config ) ) {
			return $config;
		}

		$config['plugins'] = array_map(
			function( $plugin ) {
				$plugin['install_status'] = $this->get_plugin_install_status( $plugin );
				return $plugin;
			},
			$config['plugins']
		);

		return rest_ensure_response(
			array(
				'success' => true,
				'data'    => $config,
			)
		);
	}

	public function rest_install( WP_REST_Request $request ) {
		$selected = $request->get_param( 'selected' );
		if ( ! is_array( $selected ) ) {
			return new WP_Error( 'puffergo_plugin_setup_invalid_request', __( 'Invalid selected plugins payload.', 'puffergo' ), array( 'status' => 400 ) );
		}

		$config = $this->fetch_remote_config();
		if ( is_wp_error( $config ) ) {
			return $config;
		}

		$catalog        = $this->index_plugins_by_slug( $config['plugins'] );
		$allowed_slugs  = array_keys( $catalog );
		$selected_slugs = array_values( array_unique( array_map( 'sanitize_key', $selected ) ) );

		foreach ( $selected_slugs as $slug ) {
			if ( ! in_array( $slug, $allowed_slugs, true ) ) {
				return new WP_Error( 'puffergo_plugin_setup_forbidden_plugin', __( 'One or more selected plugins are not allowed.', 'puffergo' ), array( 'status' => 400 ) );
			}
		}

		$results = array();
		foreach ( $selected_slugs as $slug ) {
			$results[] = $this->install_and_activate_plugin( $catalog[ $slug ] );
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'results' => $results,
			)
		);
	}

	private function fetch_remote_config() {
		$request_url = add_query_arg(
			array(
				'locale' => $this->get_current_locale(),
			),
			$this->get_remote_config_url()
		);

		$response = wp_remote_get(
			esc_url_raw( $request_url ),
			array(
				'timeout' => 15,
				'headers' => array(
					'Accept' => 'application/json',
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return new WP_Error( 'puffergo_plugin_setup_remote_error', $response->get_error_message(), array( 'status' => 502 ) );
		}

		$code = wp_remote_retrieve_response_code( $response );
		if ( $code < 200 || $code >= 300 ) {
			return new WP_Error( 'puffergo_plugin_setup_remote_status', __( 'Failed to fetch plugin setup config.', 'puffergo' ), array( 'status' => 502 ) );
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $body ) || empty( $body['success'] ) || empty( $body['data'] ) ) {
			return new WP_Error( 'puffergo_plugin_setup_remote_payload', __( 'Invalid plugin setup config response.', 'puffergo' ), array( 'status' => 502 ) );
		}

		return $this->normalize_remote_config( $body['data'] );
	}

	private function get_remote_config_url() {
		$default_url = trailingslashit( untrailingslashit( PUFFERGO_AI_PAGE_BUILDER_BASE_URL ) ) . 'api/wp-plugin/config';
		return apply_filters( 'puffergo_plugin_setup_config_url', $default_url );
	}

	private function get_current_locale() {
		if ( function_exists( 'get_user_locale' ) ) {
			return sanitize_text_field( get_user_locale() );
		}

		return sanitize_text_field( get_locale() );
	}

	private function index_plugins_by_slug( $plugins ) {
		$indexed = array();
		foreach ( $plugins as $plugin ) {
			if ( empty( $plugin['slug'] ) ) {
				continue;
			}
			$indexed[ sanitize_key( $plugin['slug'] ) ] = $plugin;
		}
		return $indexed;
	}

	private function normalize_remote_config( $config ) {
		$scenarios = array();
		foreach ( isset( $config['scenarios'] ) && is_array( $config['scenarios'] ) ? $config['scenarios'] : array() as $scenario ) {
			if ( empty( $scenario['key'] ) ) {
				continue;
			}

			$scenarios[] = array(
				'key'   => sanitize_key( $scenario['key'] ),
				'label' => isset( $scenario['label'] ) ? sanitize_text_field( $scenario['label'] ) : '',
			);
		}

		$plugins = array();
		foreach ( isset( $config['plugins'] ) && is_array( $config['plugins'] ) ? $config['plugins'] : array() as $plugin ) {
			$normalized = $this->normalize_remote_plugin( $plugin );
			if ( $normalized ) {
				$plugins[] = $normalized;
			}
		}

		$plugin_catalog = $this->index_plugins_by_slug( $plugins );
		$rules          = array();

		foreach ( isset( $config['rules'] ) && is_array( $config['rules'] ) ? $config['rules'] : array() as $scenario_key => $plugin_slugs ) {
			$normalized_key = sanitize_key( $scenario_key );
			if ( ! is_array( $plugin_slugs ) ) {
				continue;
			}

			$rules[ $normalized_key ] = array_values(
				array_filter(
					array_unique(
						array_map( 'sanitize_key', $plugin_slugs )
					),
					function( $slug ) use ( $plugin_catalog ) {
						return isset( $plugin_catalog[ $slug ] );
					}
				)
			);
		}

		return array(
			'version'   => isset( $config['version'] ) ? sanitize_text_field( $config['version'] ) : '',
			'scenarios' => $scenarios,
			'plugins'   => $plugins,
			'rules'     => $rules,
		);
	}

	private function normalize_remote_plugin( $plugin ) {
		if ( ! is_array( $plugin ) || empty( $plugin['slug'] ) || empty( $plugin['file'] ) || empty( $plugin['name'] ) ) {
			return null;
		}

		$slug      = sanitize_key( $plugin['slug'] );

		return array(
			'slug'            => $slug,
			'file'            => sanitize_text_field( $plugin['file'] ),
			'name'            => sanitize_text_field( $plugin['name'] ),
			'description'     => isset( $plugin['description'] ) ? sanitize_text_field( $plugin['description'] ) : '',
			'author'          => isset( $plugin['author'] ) ? sanitize_text_field( $plugin['author'] ) : '',
			'icon'            => isset( $plugin['icon'] ) ? esc_url_raw( $plugin['icon'] ) : '',
			'active_installs' => isset( $plugin['active_installs'] ) ? sanitize_text_field( $plugin['active_installs'] ) : '',
			'settings_url'    => isset( $plugin['settings_url'] ) ? esc_url_raw( $plugin['settings_url'] ) : '',
			'notes'           => isset( $plugin['notes'] ) ? sanitize_text_field( $plugin['notes'] ) : '',
		);
	}

	private function get_plugin_install_status( $plugin ) {
		$plugin_file = isset( $plugin['file'] ) ? $plugin['file'] : '';
		if ( ! $plugin_file ) {
			return 'not_installed';
		}

		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$installed_plugins = get_plugins();
		if ( ! isset( $installed_plugins[ $plugin_file ] ) ) {
			return 'not_installed';
		}

		return is_plugin_active( $plugin_file ) ? 'activated' : 'installed';
	}

	private function install_and_activate_plugin( $plugin ) {
		$slug        = sanitize_key( $plugin['slug'] );
		$plugin_file = $plugin['file'];
		$name        = $plugin['name'];
		$before      = $this->get_plugin_install_status( $plugin );

		if ( 'activated' === $before ) {
			return array(
				'slug'          => $slug,
				'name'          => $name,
				'status_before' => $before,
				'status_after'  => 'activated',
				'result'        => 'already_activated',
				'message'       => __( 'Already installed and activated.', 'puffergo' ),
			);
		}

		if ( 'installed' === $before ) {
			$activated = activate_plugin( $plugin_file );
			if ( is_wp_error( $activated ) ) {
				return array(
					'slug'          => $slug,
					'name'          => $name,
					'status_before' => $before,
					'status_after'  => 'installed',
					'result'        => 'activate_failed',
					'message'       => $activated->get_error_message(),
				);
			}

			return array(
				'slug'          => $slug,
				'name'          => $name,
				'status_before' => $before,
				'status_after'  => 'activated',
				'result'        => 'activated_existing_install',
				'message'       => __( 'Activated successfully.', 'puffergo' ),
			);
		}

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

		$api = plugins_api(
			'plugin_information',
			array(
				'slug'   => $slug,
				'fields' => array(
					'sections' => false,
				),
			)
		);

		if ( is_wp_error( $api ) ) {
			return array(
				'slug'          => $slug,
				'name'          => $name,
				'status_before' => $before,
				'status_after'  => 'not_installed',
				'result'        => 'install_failed',
				'message'       => $api->get_error_message(),
			);
		}

		$skin     = new Automatic_Upgrader_Skin();
		$upgrader = new Plugin_Upgrader( $skin );
		$installed = $upgrader->install( $api->download_link );

		if ( is_wp_error( $installed ) ) {
			return array(
				'slug'          => $slug,
				'name'          => $name,
				'status_before' => $before,
				'status_after'  => 'not_installed',
				'result'        => 'install_failed',
				'message'       => $installed->get_error_message(),
			);
		}

		if ( false === $installed ) {
			return array(
				'slug'          => $slug,
				'name'          => $name,
				'status_before' => $before,
				'status_after'  => 'not_installed',
				'result'        => 'install_failed',
				'message'       => __( 'Plugin installation failed.', 'puffergo' ),
			);
		}

		$activated = activate_plugin( $plugin_file );
		if ( is_wp_error( $activated ) ) {
			return array(
				'slug'          => $slug,
				'name'          => $name,
				'status_before' => $before,
				'status_after'  => 'installed',
				'result'        => 'activate_failed',
				'message'       => $activated->get_error_message(),
			);
		}

		return array(
			'slug'          => $slug,
			'name'          => $name,
			'status_before' => $before,
			'status_after'  => 'activated',
			'result'        => 'installed_and_activated',
			'message'       => __( 'Installed and activated successfully.', 'puffergo' ),
		);
	}
}
