<?php

defined( 'ABSPATH' ) || exit;

/**
 * Vendors module.
 *
 * Surfaces install/activate status for the third-party plugins Bowden Works
 * typically installs alongside BW Dev. Two tiers:
 *
 *   - Recommended: always part of the BW stack
 *   - Optional:    used on some sites
 *
 * Each row shows current status (Active / Installed-Inactive / Not Installed)
 * with a colored badge and an action button:
 *   - Active            → "Active" badge
 *   - Installed-Inactive→ "Activate" link (nonce-gated /wp-admin/plugins.php URL)
 *   - Not Installed     → "Install" link → opens WP's Plugin Info Thickbox modal
 *                         with one-click install
 *
 * No persisted module-level settings — pure status display.
 *
 * Plugin file paths follow the standard `<slug>/<slug>.php` convention used
 * by the WordPress.org plugin repo for these specific plugins.
 *
 * @package BW_Dev
 */

class BW_Dev_Module_Vendors implements BW_Dev_Module_Interface {

	/**
	 * Plugins surfaced in the Vendors tab. Add to this list as the BW stack evolves.
	 * Each entry needs:
	 *   - slug:        wordpress.org plugin slug (used by the install modal URL).
	 *                  For paid plugins the slug is just an internal identifier.
	 *   - file:        relative plugin file (the bootstrap inside wp-content/plugins/)
	 *   - name:        display name
	 *   - description: one-line summary explaining why BW uses it
	 *   - tier:        'recommended' or 'optional'
	 *   - paid:        (optional, default false) true for premium plugins not on
	 *                  wordpress.org — disables the Thickbox install modal and
	 *                  swaps the action button for a "Get plugin" external link
	 *   - vendor_url:  required when paid=true; where the user buys/downloads
	 */
	private const PLUGINS = array(
		// --- Recommended (always in the BW stack) ---
		array(
			'slug'        => 'kadence-blocks',
			'file'        => 'kadence-blocks/kadence-blocks.php',
			'name'        => 'Kadence Blocks',
			'description' => 'Custom Gutenberg blocks for Kadence — Row Layout, Advanced Heading, Tabs, Accordion, etc. Required for most BW client sites.',
			'tier'        => 'recommended',
		),
		array(
			'slug'        => 'kadence-blocks-pro',
			'file'        => 'kadence-blocks-pro/kadence-blocks-pro.php',
			'name'        => 'Kadence Blocks Pro',
			'description' => 'Pro Kadence blocks — Forms, Image Overlay, Advanced Slider, Lottie, dynamic content, etc. Pairs with the free Kadence Blocks plugin.',
			'tier'        => 'recommended',
			'paid'        => true,
			'vendor_url'  => 'https://www.kadencewp.com/kadence-blocks/',
		),
		array(
			'slug'        => 'advanced-custom-fields-pro',
			'file'        => 'advanced-custom-fields-pro/acf.php',
			'name'        => 'Advanced Custom Fields PRO',
			'description' => 'Custom field framework — repeaters, flexible content, options pages, gallery field. Heavily used in BW templates.',
			'tier'        => 'recommended',
			'paid'        => true,
			'vendor_url'  => 'https://www.advancedcustomfields.com/pro/',
		),
		array(
			'slug'        => 'webp-express',
			'file'        => 'webp-express/webp-express.php',
			'name'        => 'WebP Express',
			'description' => 'Serves WebP versions of JPEG/PNG images to supporting browsers. Big page-weight win.',
			'tier'        => 'recommended',
		),
		array(
			'slug'        => 'wordpress-seo',
			'file'        => 'wordpress-seo/wp-seo.php',
			'name'        => 'Yoast SEO',
			'description' => 'Sitemaps, meta tags, Open Graph, Article schema. BW Dev complements Yoast — does not duplicate it.',
			'tier'        => 'recommended',
		),
		array(
			'slug'        => 'redirection',
			'file'        => 'redirection/redirection.php',
			'name'        => 'Redirection',
			'description' => '301/302 redirect manager and 404 logger.',
			'tier'        => 'recommended',
		),

		// --- Optional (situational) ---
		array(
			'slug'        => 'gravityforms',
			'file'        => 'gravityforms/gravityforms.php',
			'name'        => 'Gravity Forms',
			'description' => 'Heavy-duty form builder — multi-page, conditional logic, payment integrations, file uploads. Use on contact-form-heavy sites.',
			'tier'        => 'optional',
			'paid'        => true,
			'vendor_url'  => 'https://www.gravityforms.com/',
		),
		array(
			'slug'        => 'better-search-replace',
			'file'        => 'better-search-replace/better-search-replace.php',
			'name'        => 'Better Search Replace',
			'description' => 'Safe DB search-and-replace. Useful when migrating sites between domains.',
			'tier'        => 'optional',
		),
		array(
			'slug'        => 'customizer-export-import',
			'file'        => 'customizer-export-import/customizer-export-import.php',
			'name'        => 'Customizer Export/Import',
			'description' => 'Move Customizer settings between sites with the same theme.',
			'tier'        => 'optional',
		),
		array(
			'slug'        => 'post-types-order',
			'file'        => 'post-types-order/post-types-order.php',
			'name'        => 'Post Types Order',
			'description' => 'Drag-and-drop manual ordering for posts and CPTs.',
			'tier'        => 'optional',
		),
	);

	public function slug(): string {
		return 'vendors';
	}

	public function label(): string {
		return __( 'Plugins', 'bw-dev' );
	}

	public function group(): string {
		return 'vendors';
	}

	public function default_settings(): array {
		return array();
	}

	public function sanitize( array $data ): array {
		unset( $data );
		return array();
	}

	public function register(): void {
		add_action( 'admin_enqueue_scripts', array( $this, 'maybe_enqueue_thickbox' ) );
	}

	/**
	 * Thickbox is what powers WP's "Plugin Information" modal. We only need
	 * it on the BW Dev settings page, so gate by the page's hook suffix.
	 *
	 * @param string $hook_suffix Current admin page hook.
	 */
	public function maybe_enqueue_thickbox( $hook_suffix ): void {
		if ( 'settings_page_bw-dev' !== $hook_suffix ) {
			return;
		}
		add_thickbox();
	}

	/* ---------------------------------------------------------------------
	 * Settings tab
	 * ------------------------------------------------------------------- */

	public function render_tab(): void {
		if ( ! function_exists( 'is_plugin_active' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$by_tier = array(
			'recommended' => array(),
			'optional'    => array(),
		);
		foreach ( self::PLUGINS as $p ) {
			$tier                = isset( $by_tier[ $p['tier'] ] ) ? $p['tier'] : 'optional';
			$by_tier[ $tier ][]  = $p;
		}
		?>
		<p class="description">
			<?php esc_html_e( 'Third-party plugins that pair with BW Dev. Click "Install" or "Activate" to bring one into this site without leaving the page.', 'bw-dev' ); ?>
		</p>

		<?php
		$this->render_tier(
			__( 'Recommended', 'bw-dev' ),
			__( 'These are part of the standard Bowden Works stack — install them on every client site unless you have a reason not to.', 'bw-dev' ),
			$by_tier['recommended']
		);

		$this->render_tier(
			__( 'Optional', 'bw-dev' ),
			__( 'Situational plugins that come in handy on specific projects.', 'bw-dev' ),
			$by_tier['optional']
		);
		?>

		<p class="description" style="margin-top:20px;">
			<?php esc_html_e( 'All plugins listed here are sourced from the official WordPress.org plugin directory. The Install button opens WordPress\'s standard plugin-information modal where you can review and install in one click.', 'bw-dev' ); ?>
		</p>
		<?php
	}

	private function render_tier( string $heading, string $intro, array $plugins ): void {
		if ( empty( $plugins ) ) {
			return;
		}
		?>
		<h3 style="margin-top:24px;"><?php echo esc_html( $heading ); ?></h3>
		<p class="description" style="max-width:720px;"><?php echo esc_html( $intro ); ?></p>
		<table class="widefat striped" style="margin-top:10px;">
			<thead>
				<tr>
					<th style="width:200px;"><?php esc_html_e( 'Plugin', 'bw-dev' ); ?></th>
					<th><?php esc_html_e( 'What it does', 'bw-dev' ); ?></th>
					<th style="width:140px;"><?php esc_html_e( 'Status', 'bw-dev' ); ?></th>
					<th style="width:130px;"><?php esc_html_e( 'Action', 'bw-dev' ); ?></th>
				</tr>
			</thead>
			<tbody>
				<?php foreach ( $plugins as $p ) : ?>
					<?php $this->render_plugin_row( $p ); ?>
				<?php endforeach; ?>
			</tbody>
		</table>
		<?php
	}

	private function render_plugin_row( array $p ): void {
		$is_paid      = ! empty( $p['paid'] );
		$vendor_url   = $is_paid ? (string) ( $p['vendor_url'] ?? '' ) : '';
		$is_active    = is_plugin_active( $p['file'] );
		$is_installed = $is_active || file_exists( WP_PLUGIN_DIR . '/' . $p['file'] );

		// Status badge.
		if ( $is_active ) {
			$badge = '<span style="display:inline-block;padding:2px 8px;border-radius:3px;background:#00a32a;color:#fff;font-size:11px;font-weight:600;">' . esc_html__( 'Active', 'bw-dev' ) . '</span>';
		} elseif ( $is_installed ) {
			$badge = '<span style="display:inline-block;padding:2px 8px;border-radius:3px;background:#dba617;color:#fff;font-size:11px;font-weight:600;">' . esc_html__( 'Inactive', 'bw-dev' ) . '</span>';
		} else {
			$badge = '<span style="display:inline-block;padding:2px 8px;border-radius:3px;background:#646970;color:#fff;font-size:11px;font-weight:600;">' . esc_html__( 'Not installed', 'bw-dev' ) . '</span>';
		}

		// PAID/PRO badge alongside name.
		$pro_badge = $is_paid
			? ' <span style="display:inline-block;padding:1px 6px;border-radius:3px;background:#1d2327;color:#fff;font-size:10px;font-weight:600;letter-spacing:.04em;vertical-align:middle;">' . esc_html__( 'PAID', 'bw-dev' ) . '</span>'
			: '';

		// Action.
		if ( $is_active ) {
			$action = '<span style="color:#646970;">&mdash;</span>';
		} elseif ( $is_installed ) {
			// Activate flow works for any plugin (free or paid) once it's on disk.
			$activate_url = wp_nonce_url(
				self_admin_url( 'plugins.php?action=activate&plugin=' . rawurlencode( $p['file'] ) ),
				'activate-plugin_' . $p['file']
			);
			$action = sprintf(
				'<a href="%s" class="button button-primary">%s</a>',
				esc_url( $activate_url ),
				esc_html__( 'Activate', 'bw-dev' )
			);
		} elseif ( $is_paid && '' !== $vendor_url ) {
			// Paid plugin not installed → external vendor link (no Thickbox install).
			$action = sprintf(
				'<a href="%s" target="_blank" rel="noopener noreferrer" class="button button-secondary" aria-label="%s">%s &rarr;</a>',
				esc_url( $vendor_url ),
				/* translators: %s: plugin name */
				esc_attr( sprintf( __( 'Get %s from the vendor', 'bw-dev' ), $p['name'] ) ),
				esc_html__( 'Get plugin', 'bw-dev' )
			);
		} else {
			// Free plugin not installed → WP's Plugin Information Thickbox with one-click install.
			$install_url = self_admin_url(
				sprintf(
					'plugin-install.php?tab=plugin-information&plugin=%s&TB_iframe=true&width=772&height=689',
					rawurlencode( $p['slug'] )
				)
			);
			$action = sprintf(
				'<a href="%s" class="thickbox button button-primary" aria-label="%s">%s</a>',
				esc_url( $install_url ),
				/* translators: %s: plugin name */
				esc_attr( sprintf( __( 'Install %s now', 'bw-dev' ), $p['name'] ) ),
				esc_html__( 'Install', 'bw-dev' )
			);
		}

		// Plugin name link — vendor URL for paid plugins, wordpress.org for free.
		$name_url = $is_paid && '' !== $vendor_url
			? $vendor_url
			: 'https://wordpress.org/plugins/' . rawurlencode( $p['slug'] ) . '/';
		$name_link = sprintf(
			'<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
			esc_url( $name_url ),
			esc_html( $p['name'] )
		);
		?>
		<tr>
			<td><strong><?php echo $name_link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped above. ?></strong><?php echo $pro_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped above. ?></td>
			<td style="color:#3c434a;"><?php echo esc_html( $p['description'] ); ?></td>
			<td><?php echo $badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped above. ?></td>
			<td><?php echo $action; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped above. ?></td>
		</tr>
		<?php
	}

	public function uninstall(): void {
		// No persisted state.
	}
}
