<?php

namespace DownloadThemeZip;

use WP_PowerSuite\Core\AbstractModule;
use WP_PowerSuite\Core\Contracts\DataLocationsInterface;
use WP_PowerSuite\Core\Export\PluginThemeZipExporter;

class Module extends AbstractModule implements DataLocationsInterface {

	private const MODULE_ID      = 'download-theme-zip';
	private const MODULE_VERSION = '1.0.0';

	public function getId(): string {
		return self::MODULE_ID;
	}

	public function getName(): string {
		return __( 'Download Theme as ZIP', 'wp-powersuite' );
	}

	public function getVersion(): string {
		return self::MODULE_VERSION;
	}

	public function getDescription(): string {
		return __( 'ZIP download button on each theme for backup or migration without FTP.', 'wp-powersuite' ); // phpcs:ignore Generic.Files.LineLength.TooLong
	}

	public function getContext(): string|array {
		return [ 'admin' ];
	}

	public function getDependencies(): array {
		return [];
	}

	protected function registerHooks(): void {
		add_action( 'admin_post_wpps_download_theme_zip', [ $this, 'handleDownload' ] );

		if ( ! is_admin() ) {
			return;
		}

		add_action( 'admin_footer-themes.php', [ $this, 'injectDownloadButtonToModal' ] );
	}

	public function injectDownloadButtonToModal(): void {
		if ( ! current_user_can( 'install_themes' ) ) {
			return;
		}

		$themes     = wp_get_themes();
		$theme_data = [];

		foreach ( $themes as $stylesheet => $theme ) {
			$theme_slug = $theme->get_stylesheet();
			// Raw admin-post URL for JS (wp_nonce_url HTML-encodes & as &amp;, breaking query args in href).
			$theme_data[ $theme_slug ] = add_query_arg(
				[
					'action' => 'wpps_download_theme_zip',
					'theme'  => $theme_slug,
					'nonce'  => wp_create_nonce( 'wpps_download_theme_' . $theme_slug ),
				],
				admin_url( 'admin-post.php' )
			);
		}
		?>
		<script type="text/javascript">
		(function($) {
			var themeData = <?php echo wp_json_encode( $theme_data ); ?>;
			var downloadLabel = <?php echo wp_json_encode( __( 'Download ZIP', 'wp-powersuite' ) ); ?>;
			var downloadTitle = <?php echo wp_json_encode( __( 'Download this theme as a ZIP file', 'wp-powersuite' ) ); ?>;

			function addDownloadButtonToModal() {
				var $modal = $('.theme-overlay');
				if ($modal.length === 0 || $modal.find('.wpps-download-theme-zip').length > 0) {
					return;
				}

				var themeSlug = null;
				var urlParams = new URLSearchParams(window.location.search);
				themeSlug = urlParams.get('theme');

				if (!themeSlug) {
					themeSlug = $modal.data('slug') || $modal.attr('data-slug');
				}

				if (!themeSlug) {
					var activateLink = $modal.find('a[href*="stylesheet="], a[href*="action=activate"]').first();
					if (activateLink.length > 0) {
						var href = activateLink.attr('href') || '';
						var match = href.match(/[?&]stylesheet=([^&]+)/);
						if (match) {
							themeSlug = decodeURIComponent(match[1]);
						}
					}
				}

				if (!themeSlug) {
					var themeId = $modal.attr('id');
					if (themeId) {
						themeSlug = themeId.replace('theme-', '').replace('-details', '');
					}
				}

				if (!themeSlug || !themeData[themeSlug]) {
					return;
				}

				var $actions = $modal.find('.theme-actions, .theme-actions-wrapper').first();
				if ($actions.length === 0) {
					$actions = $modal.find('.theme-header').first();
				}

				if ($actions.length === 0) {
					return;
				}

				var $downloadBtn = $('<a>', {
					href: themeData[themeSlug],
					class: 'button button-primary wpps-download-theme-zip',
					title: downloadTitle,
					text: downloadLabel,
					'aria-label': downloadTitle
				});

				$actions.append($downloadBtn);
			}

			$(document).ready(function() {
				$(document).on('click', '.theme, .theme-screenshot', function() {
					setTimeout(addDownloadButtonToModal, 300);
				});

				var $overlayRoot = $('.theme-overlay');
				if ($overlayRoot.length && window.MutationObserver) {
					var observer = new MutationObserver(function() {
						setTimeout(addDownloadButtonToModal, 200);
					});
					observer.observe($overlayRoot.get(0), {
						childList: true,
						subtree: true
					});
				}

				setTimeout(addDownloadButtonToModal, 500);
			});
		})(jQuery);
		</script>
		<?php
	}

	public function handleDownload(): void {
		if ( ! $this->isEnabled() ) {
			wp_die(
				esc_html__( 'Module is not enabled.', 'wp-powersuite' ),
				esc_html__( 'Error', 'wp-powersuite' ),
				[ 'response' => 403 ]
			);
		}

		$theme_slug = '';
		if ( isset( $_GET['theme'] ) ) {
			$theme_slug = sanitize_text_field( wp_unslash( $_GET['theme'] ) );
		} elseif ( isset( $_REQUEST['theme'] ) ) {
			$theme_slug = sanitize_text_field( wp_unslash( $_REQUEST['theme'] ) );
		}

		if ( $theme_slug === '' ) {
			wp_die(
				esc_html__( 'Invalid theme specified.', 'wp-powersuite' ),
				esc_html__( 'Error', 'wp-powersuite' ),
				[ 'response' => 400 ]
			);
		}

		$nonce = '';
		if ( isset( $_GET['nonce'] ) ) {
			$nonce = sanitize_text_field( wp_unslash( $_GET['nonce'] ) );
		} elseif ( isset( $_REQUEST['nonce'] ) ) {
			$nonce = sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) );
		}

		if ( $nonce === '' || ! wp_verify_nonce( $nonce, 'wpps_download_theme_' . $theme_slug ) ) {
			wp_die(
				esc_html__( 'Security check failed.', 'wp-powersuite' ),
				esc_html__( 'Error', 'wp-powersuite' ),
				[ 'response' => 403 ]
			);
		}

		if ( ! current_user_can( 'install_themes' ) ) {
			wp_die(
				esc_html__( 'You do not have permission to download themes.', 'wp-powersuite' ),
				esc_html__( 'Permission Denied', 'wp-powersuite' ),
				[ 'response' => 403 ]
			);
		}

		$rate_error = PluginThemeZipExporter::checkRateLimit( 'theme' );
		if ( $rate_error instanceof \WP_Error ) {
			wp_die(
				esc_html( $rate_error->get_error_message() ),
				esc_html__( 'Error', 'wp-powersuite' ),
				[ 'response' => 429 ]
			);
		}

		$resolved = PluginThemeZipExporter::resolveThemeSource( $theme_slug );
		if ( is_wp_error( $resolved ) ) {
			$status = $resolved->get_error_code() === 'not_found' ? 404 : 403;
			wp_die(
				esc_html( $resolved->get_error_message() ),
				esc_html__( 'Error', 'wp-powersuite' ),
				[ 'response' => $status ]
			);
		}

		$result = PluginThemeZipExporter::createZip(
			$resolved['source'],
			$resolved['slug_for_zip']
		);

		if ( is_wp_error( $result ) ) {
			wp_die(
				'<strong>' . esc_html__( 'Failed to create ZIP file', 'wp-powersuite' ) . '</strong><br><br>' . esc_html( $result->get_error_message() ),
				esc_html__( 'Error', 'wp-powersuite' ),
				[ 'response' => 500 ]
			);
		}

		PluginThemeZipExporter::streamZip( $result, $resolved['filename_base'] );
	}

	/**
	 * {@inheritdoc}
	 */
	public function getDataLocations(): array {
		return [
			'option_store_keys' => [],
		];
	}
}
