<?php

use WP_PowerSuite\Core\OptionStoreModuleSettingsRepository;

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

if ( ! function_exists( 'wp_powersuite_is_license_valid' ) || ! wp_powersuite_is_license_valid() ) {
	$license_page_url = admin_url( 'admin.php?page=powersuite-license' );
	?>
	<div class="wp-powersuite-module-settings wpps-settings-panel" data-module-id="<?php echo esc_attr( $module_id ?? 'broken-link-checker' ); ?>">
		<div class="notice notice-warning inline" style="margin:0;">
			<p>
				<?php esc_html_e( 'Broken Link Checker requires an active license. Activate your license to scan content for dead links.', 'wp-powersuite' ); ?>
				<a href="<?php echo esc_url( $license_page_url ); ?>"><?php esc_html_e( 'Activate license', 'wp-powersuite' ); ?></a>
			</p>
		</div>
	</div>
	<?php
	return;
}

if ( ! isset( $module_id ) || empty( $module_id ) ) {
	$module_id = 'broken-link-checker';
}

$settings             = OptionStoreModuleSettingsRepository::forModule( $module_id )->all( [] );
$post_types_available = get_post_types( [ 'public' => true ], 'objects' );
$post_types_selected  = $settings['post_types'] ?? [ 'post', 'page' ];
if ( ! is_array( $post_types_selected ) ) {
	$post_types_selected = [ 'post', 'page' ];
}

$ajax_nonce = wp_create_nonce( 'wp_powersuite_ajax' );
?>

<div class="wp-powersuite-module-settings wpps-blc-settings">
	<p class="description">
		<?php esc_html_e( 'Scan published content for broken internal and external links. Checks post content, images, Gutenberg block URLs, and Elementor data when present. Large sites are scanned in batches automatically.', 'wp-powersuite' ); ?>
	</p>

	<form class="wp-powersuite-module-settings-form" data-module-id="<?php echo esc_attr( $module_id ); ?>" data-ajax-nonce="<?php echo esc_attr( $ajax_nonce ); ?>">
		<?php wp_nonce_field( 'wp_powersuite_save_module_settings_' . $module_id, 'wp_powersuite_nonce' ); ?>

		<h4 style="margin-top: 0;"><?php esc_html_e( 'Post Types to Scan', 'wp-powersuite' ); ?></h4>
		<p class="description" style="margin-bottom: 12px;">
			<?php esc_html_e( 'Select which content types to include in the scan.', 'wp-powersuite' ); ?>
		</p>
		<div class="wpps-blc-post-types" style="display: flex; flex-wrap: wrap; gap: 12px 24px; margin-bottom: 20px;">
			<?php foreach ( $post_types_available as $pt ) : ?>
				<label style="display: flex; align-items: center; gap: 6px;">
					<input
						type="checkbox"
						name="post_types[]"
						value="<?php echo esc_attr( $pt->name ); ?>"
						class="wp-powersuite-advanced-setting"
						data-setting-key="post_types"
						<?php checked( in_array( $pt->name, $post_types_selected, true ) ); ?>
					/>
					<?php echo esc_html( $pt->label ); ?>
				</label>
			<?php endforeach; ?>
		</div>

		<hr style="margin: 20px 0;" />

		<h4><?php esc_html_e( 'Scan', 'wp-powersuite' ); ?></h4>
		<p class="description" style="margin-bottom: 12px;">
			<?php esc_html_e( 'Internal links are verified via WordPress when possible. External links use HEAD with GET fallback. Results include broken, redirect, and inconclusive links.', 'wp-powersuite' ); ?>
		</p>
		<p style="margin-bottom: 12px;">
			<button type="button" class="button button-primary wpps-blc-scan" id="wpps-blc-scan-btn">
				<span class="dashicons dashicons-search" style="vertical-align: middle; margin-right: 4px;"></span>
				<?php esc_html_e( 'Start Scan', 'wp-powersuite' ); ?>
			</button>
			<button type="button" class="button wpps-blc-cancel" id="wpps-blc-cancel-btn" style="display: none; margin-left: 8px;">
				<?php esc_html_e( 'Cancel Scan', 'wp-powersuite' ); ?>
			</button>
		</p>

		<div class="wpps-blc-progress" style="display: none; margin-top: 16px;" aria-live="polite" aria-atomic="true">
			<div style="background: #f0f0f1; border-radius: 4px; height: 8px; overflow: hidden;">
				<div class="wpps-blc-progress-bar" style="width: 0%; background: #2271b1; height: 100%; transition: width 0.3s;"></div>
			</div>
			<p class="description wpps-blc-progress-text" style="margin: 8px 0 0;"><?php esc_html_e( 'Scanning...', 'wp-powersuite' ); ?></p>
		</div>

		<div class="wpps-blc-results" style="margin-top: 20px; display: none;"></div>
	</form>
</div>

<script>
(function() {
	var $ = jQuery;
	$(document).ready(function() {
		var $form = $('.wpps-blc-settings form');
		var $btn = $('#wpps-blc-scan-btn');
		var $cancelBtn = $('#wpps-blc-cancel-btn');
		var $progress = $('.wpps-blc-progress');
		var $progressBar = $('.wpps-blc-progress-bar');
		var $progressText = $('.wpps-blc-progress-text');
		var $results = $('.wpps-blc-results');

		if (!$btn.length) return;

		var nonce = $form.data('ajax-nonce') || (window.wpPowerSuite && window.wpPowerSuite.nonce) || '';
		var scanActive = false;
		var currentScanId = '';
		var aggregated = {
			broken_links: [],
			redirect_links: [],
			inconclusive_links: [],
			total_urls: 0,
			total_posts: 0,
			posts_scanned: 0,
			scan_time: 0
		};

		var i18n = {
			scanning: <?php echo wp_json_encode( __( 'Scanning...', 'wp-powersuite' ) ); ?>,
			scanningProgress: <?php echo wp_json_encode( __( 'Scanning posts… %1$s%% complete (%2$s of %3$s)', 'wp-powersuite' ) ); ?>,
			checkingLinks: <?php echo wp_json_encode( __( 'Checking links… %1$s%% complete (%2$s URLs remaining)', 'wp-powersuite' ) ); ?>,
			finalizing: <?php echo wp_json_encode( __( 'Finalizing results…', 'wp-powersuite' ) ); ?>,
			startScan: <?php echo wp_json_encode( __( 'Start Scan', 'wp-powersuite' ) ); ?>,
			scanFailed: <?php echo wp_json_encode( __( 'Scan failed. Please try again.', 'wp-powersuite' ) ); ?>,
			scanResults: <?php echo wp_json_encode( __( 'Scan Results', 'wp-powersuite' ) ); ?>,
			postsScanned: <?php echo wp_json_encode( __( 'Posts Scanned', 'wp-powersuite' ) ); ?>,
			uniqueUrlsChecked: <?php echo wp_json_encode( __( 'Unique URLs Checked', 'wp-powersuite' ) ); ?>,
			brokenLinks: <?php echo wp_json_encode( __( 'Broken Links', 'wp-powersuite' ) ); ?>,
			redirectLinks: <?php echo wp_json_encode( __( 'Redirects', 'wp-powersuite' ) ); ?>,
			inconclusiveLinks: <?php echo wp_json_encode( __( 'Inconclusive', 'wp-powersuite' ) ); ?>,
			scanDuration: <?php echo wp_json_encode( __( 'Scan Duration', 'wp-powersuite' ) ); ?>,
			excellent: <?php echo wp_json_encode( __( 'Excellent!', 'wp-powersuite' ) ); ?>,
			noBrokenLinks: <?php echo wp_json_encode( __( 'No broken links found.', 'wp-powersuite' ) ); ?>,
			brokenLinksFound: <?php echo wp_json_encode( __( 'Found %d broken link(s). Click the post title to edit.', 'wp-powersuite' ) ); ?>,
			postPage: <?php echo wp_json_encode( __( 'Post/Page', 'wp-powersuite' ) ); ?>,
			brokenUrl: <?php echo wp_json_encode( __( 'URL', 'wp-powersuite' ) ); ?>,
			type: <?php echo wp_json_encode( __( 'Type', 'wp-powersuite' ) ); ?>,
			error: <?php echo wp_json_encode( __( 'Status', 'wp-powersuite' ) ); ?>,
			copy: <?php echo wp_json_encode( __( 'Copy', 'wp-powersuite' ) ); ?>,
			copied: <?php echo wp_json_encode( __( 'Copied!', 'wp-powersuite' ) ); ?>,
			exportCsv: <?php echo wp_json_encode( __( 'Export CSV', 'wp-powersuite' ) ); ?>,
			cancelScan: <?php echo wp_json_encode( __( 'Cancel Scan', 'wp-powersuite' ) ); ?>
		};

		$btn.on('click', function() {
			startScan();
		});

		$cancelBtn.on('click', function() {
			cancelScan();
		});

		function getPostTypes() {
			var postTypes = [];
			$form.find('input[name="post_types[]"]:checked').each(function() {
				postTypes.push($(this).val());
			});
			return postTypes.length ? postTypes : ['post', 'page'];
		}

		function resetAggregated() {
			aggregated = {
				broken_links: [],
				redirect_links: [],
				inconclusive_links: [],
				total_urls: 0,
				total_posts: 0,
				posts_scanned: 0,
				scan_time: 0
			};
		}

		function startScan() {
			resetAggregated();
			scanActive = true;
			currentScanId = '';
			$btn.prop('disabled', true).html('<span class="dashicons dashicons-update" style="animation: spin 1s linear infinite; vertical-align: middle; margin-right: 4px;"></span>' + i18n.scanning);
			$cancelBtn.show();
			$progress.show();
			$progressBar.css('width', '0%');
			$progressText.text(i18n.scanning);
			$results.hide().empty();
			runBatch('start', '');
		}

		function cancelScan() {
			scanActive = false;
			if (currentScanId) {
				$.post(ajaxurl, {
					action: 'wp_powersuite_scan_broken_links',
					nonce: nonce,
					scan_action: 'cancel',
					scan_id: currentScanId
				});
			}
			finishScanUi();
		}

		function runBatch(action, scanId) {
			if (!scanActive && action !== 'start') {
				return;
			}
			var data = {
				action: 'wp_powersuite_scan_broken_links',
				nonce: nonce,
				scan_action: action,
				scan_id: scanId
			};
			if (action === 'start') {
				data.post_types = getPostTypes();
			}

			$.ajax({
				url: ajaxurl,
				type: 'POST',
				timeout: 120000,
				data: data,
				success: function(r) {
					if (!scanActive && action === 'start') {
						return;
					}
					if (r.success && r.data) {
						mergeBatch(r.data);
						updateProgress(r.data);
						if (r.data.has_more && scanActive) {
							currentScanId = r.data.scan_id || scanId;
							runBatch('continue', currentScanId);
							return;
						}
						renderResults(aggregated, i18n);
						$results.show();
					} else {
						$results.html('<div class="notice notice-error"><p>' + (r.data && r.data.message ? escHtml(r.data.message) : i18n.scanFailed) + '</p></div>').show();
					}
					finishScanUi();
				},
				error: function() {
					$results.html('<div class="notice notice-error"><p>' + i18n.scanFailed + '</p></div>').show();
					finishScanUi();
				}
			});
		}

		function mergeBatch(data) {
			aggregated.broken_links = data.broken_links || [];
			aggregated.redirect_links = data.redirect_links || [];
			aggregated.inconclusive_links = data.inconclusive_links || [];
			aggregated.total_urls = data.total_urls || 0;
			aggregated.total_posts = data.total_posts || aggregated.total_posts;
			aggregated.posts_scanned = data.posts_scanned || 0;
			aggregated.scan_time = data.scan_time || 0;
		}

		function updateProgress(data) {
			var pct = data.progress || 0;
			var total = data.total_posts || 0;
			var scanned = data.posts_scanned || 0;
			var pending = data.pending_urls || 0;
			var phase = data.phase || 'posts';

			if (total > 0) {
				scanned = Math.min(scanned, total);
			}

			$progressBar.css('width', pct + '%');

			var text;
			if (!data.has_more) {
				text = i18n.finalizing;
			} else if (phase === 'links' || (scanned >= total && total > 0 && pending > 0)) {
				text = i18n.checkingLinks
					.replace('%1$s', String(pct))
					.replace('%2$s', String(pending))
					.replace('%%', '%');
			} else {
				text = i18n.scanningProgress
					.replace('%1$s', String(pct))
					.replace('%2$s', String(scanned))
					.replace('%3$s', String(total))
					.replace('%%', '%');
			}
			$progressText.text(text);
		}

		function finishScanUi() {
			scanActive = false;
			currentScanId = '';
			$btn.prop('disabled', false).html('<span class="dashicons dashicons-search" style="vertical-align: middle; margin-right: 4px;"></span>' + i18n.startScan);
			$cancelBtn.hide();
			$progress.hide();
		}

		function renderResults(data, i18n) {
			var html = '<div class="wpps-blc-results-card" style="padding: 16px; background: #f6f7f7; border: 1px solid #c3c4c7; border-radius: 4px;">';
			html += '<h4 style="margin-top: 0;">' + i18n.scanResults + ' <span style="font-weight: normal; color: #646970;">(' + data.scan_time + 's)</span></h4>';
			html += '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; margin-bottom: 20px;">';
			html += statBox(Math.min(data.posts_scanned, data.total_posts || data.posts_scanned), i18n.postsScanned, '#2271b1');
			html += statBox(data.total_urls, i18n.uniqueUrlsChecked, '#dba617');
			html += statBox(data.broken_links.length, i18n.brokenLinks, data.broken_links.length ? '#d63638' : '#00a32a');
			html += statBox(data.redirect_links.length, i18n.redirectLinks, '#996800');
			html += statBox(data.inconclusive_links.length, i18n.inconclusiveLinks, '#646970');
			html += '</div>';

			if (data.broken_links.length === 0) {
				html += '<div class="notice notice-success inline"><p><strong>' + i18n.excellent + '</strong> ' + i18n.noBrokenLinks + '</p></div>';
			} else {
				html += '<p class="description" style="margin-bottom: 12px;">' + i18n.brokenLinksFound.replace('%d', data.broken_links.length) + '</p>';
				html += exportButton();
				html += linkTable(data.broken_links, i18n);
			}

			if (data.redirect_links.length) {
				html += '<h4 style="margin-top: 20px;">' + i18n.redirectLinks + '</h4>';
				html += linkTable(data.redirect_links, i18n);
			}
			if (data.inconclusive_links.length) {
				html += '<h4 style="margin-top: 20px;">' + i18n.inconclusiveLinks + '</h4>';
				html += linkTable(data.inconclusive_links, i18n);
			}

			html += '</div>';
			$results.html(html);

			$results.find('.wpps-blc-copy-url').on('click', function() {
				var $copyBtn = $(this);
				var url = $copyBtn.data('url');
				if (navigator.clipboard && navigator.clipboard.writeText) {
					navigator.clipboard.writeText(url).then(function() {
						var orig = $copyBtn.html();
						$copyBtn.html('<span style="color:#00a32a;">' + i18n.copied + '</span>');
						setTimeout(function() { $copyBtn.html(orig); }, 1500);
					});
				}
			});

			$results.find('.wpps-blc-export-csv').on('click', function() {
				exportCsv(data.broken_links);
			});
		}

		function statBox(value, label, color) {
			return '<div style="padding: 12px; background: #fff; border-radius: 4px; text-align: center;"><div style="font-size: 24px; font-weight: 600; color: ' + color + ';">' + value + '</div><div style="font-size: 12px; color: #646970;">' + label + '</div></div>';
		}

		function exportButton() {
			return '<p><button type="button" class="button button-small wpps-blc-export-csv">' + i18n.exportCsv + '</button></p>';
		}

		function linkTable(links, i18n) {
			var html = '<div style="max-height: 400px; overflow-y: auto; border: 1px solid #c3c4c7; border-radius: 4px; background: #fff; margin-bottom: 12px;">';
			html += '<table class="widefat striped" style="margin: 0;"><thead><tr>';
			html += '<th scope="col">' + i18n.postPage + '</th><th scope="col">' + i18n.brokenUrl + '</th><th scope="col">' + i18n.type + '</th><th scope="col">' + i18n.error + '</th><th scope="col"><span class="screen-reader-text">' + i18n.copy + '</span></th>';
			html += '</tr></thead><tbody>';
			links.forEach(function(link) {
				html += '<tr>';
				html += '<td><a href="' + escAttr(link.edit_url) + '" target="_blank" rel="noopener">' + escHtml(link.post_title) + '</a></td>';
				html += '<td style="word-break: break-all; font-family: monospace; font-size: 12px;">' + escHtml(link.url) + '</td>';
				html += '<td>' + escHtml(link.type) + '</td>';
				html += '<td style="color: #d63638;">' + escHtml(link.status || '—') + '</td>';
				html += '<td><button type="button" class="button-link wpps-blc-copy-url" data-url="' + escAttr(link.url) + '" title="' + escAttr(i18n.copy) + '"><span class="dashicons dashicons-admin-links"></span></button></td>';
				html += '</tr>';
			});
			html += '</tbody></table></div>';
			return html;
		}

		function exportCsv(links) {
			if (!links || !links.length) return;
			var csv = 'Post Title,URL,Type,Status\n';
			links.forEach(function(l) {
				csv += '"' + (l.post_title || '').replace(/"/g, '""') + '","' + (l.url || '').replace(/"/g, '""') + '","' + (l.type || '') + '","' + (l.status || '').replace(/"/g, '""') + '"\n';
			});
			var a = document.createElement('a');
			a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv);
			a.download = 'broken-links-' + new Date().toISOString().slice(0,10) + '.csv';
			a.click();
		}

		function escHtml(s) { return $('<div>').text(s || '').html(); }
		function escAttr(s) { return $('<div>').text(s || '').html().replace(/"/g, '&quot;'); }
	});
})();
</script>
