/**
 * WordPress dependencies
 */
import { useState, useEffect } from '@wordpress/element';
import { Button, SelectControl, Spinner, Notice, CheckboxControl, __experimentalVStack as VStack } from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';
import { __ } from '@wordpress/i18n';

/**
 * Main admin page component.
 */
function AdminPage() {
	const [isScanning, setIsScanning] = useState(false);
	const [isLoadingRedirects, setIsLoadingRedirects] = useState(false);
	const [redirects, setRedirects] = useState([]);
	const [total, setTotal] = useState(0);
	const [currentPage, setCurrentPage] = useState(1);
	const [totalPages, setTotalPages] = useState(0);
	const [error, setError] = useState(null);
	const [success, setSuccess] = useState(null);
	const [availablePostTypes, setAvailablePostTypes] = useState([]);
	const [selectedPostTypes, setSelectedPostTypes] = useState(["post", "page"]);
	const [redirectType, setRedirectType] = useState("chain");
	const [dryRun, setDryRun] = useState(true);
	const perPage = 50;

	// Processing state.
	const [isProcessing, setIsProcessing] = useState(false);
	const [processingProgress, setProcessingProgress] = useState({
		processed: 0,
		total: 0,
		postsUpdated: 0,
		linksRemoved: 0,
	});
	const [processingResults, setProcessingResults] = useState(null);
	const [showProcessButton, setShowProcessButton] = useState(false);
	const [isFreeUser, setIsFreeUser] = useState(false);
	const [upgradeUrl, setUpgradeUrl] = useState('');

	const {
		restEndpointScan,
		restEndpointHomeRedirects,
		restEndpointProcessBatch,
		restEndpointPostTypes,
		restEndpointChainRedirects,
		restEndpointFixChainRedirects,
		restEndpointStats,
		nonce,
		isNotPaying,
		upgradeUrl: upgradeUrlFromLocalize,
	} = window.redicl || {};

	// Set up API fetch with nonce.
	useEffect(() => {
		apiFetch.use(apiFetch.createNonceMiddleware(nonce));
	}, [nonce]);

	/**
	 * Scan for redirects based on selected type.
	 */
	const handleScan = async () => {
		setIsScanning(true);
		setError(null);
		setSuccess(null);
		setProcessingResults(null);


		try {
			if (redirectType === 'chain') {
				// Scan for chain redirects - load first page
				await loadChainRedirects(1);
				setSuccess(__('Chain redirects loaded.', 'redirect-cleanup'));
			} else {
				// Scan for homepage redirects (existing behavior)
				const response = await apiFetch({
					path: restEndpointScan,
					method: 'POST',
					data: {
						post_types: selectedPostTypes,
					},
				});

				if (response.success) {
					setTotal(response.total);
					setTotalPages(Math.ceil(response.total / perPage));
					setCurrentPage(1);
					setSuccess(response.message);
					setShowProcessButton(true);

					// Load first page of redirects.
					if (response.total > 0) {
						await loadRedirects(1);
					} else {
						setRedirects([]);
					}
				} else {
					setError('Failed to scan redirects.');
				}
			}
		} catch (err) {
			setError(err.message || 'An error occurred while scanning.');
		} finally {
			setIsScanning(false);
		}
	};

	/**
	 * Load redirects for a specific page.
	 */
	const loadRedirects = async (page, postTypes = selectedPostTypes) => {
		setIsLoadingRedirects(true);
		setError(null);

		try {
			const postTypesParam = postTypes.join(',');
			const response = await apiFetch({
				path: `${restEndpointHomeRedirects}?page=${page}&per_page=${perPage}&post_types=${postTypesParam}`,
			});

			if (response.success) {
				setRedirects(response.data);
				setTotal(response.total);
				setTotalPages(response.pages);
				setCurrentPage(response.page);
			} else {
				setError('Failed to load redirects.');
			}
		} catch (err) {
			setError(err.message || 'An error occurred while loading redirects.');
		} finally {
			setIsLoadingRedirects(false);
		}
	};

	/**
	 * Load chain redirects for a specific page.
	 */
	const loadChainRedirects = async (page) => {
		setIsLoadingRedirects(true);
		setError(null);

		try {
			const response = await apiFetch({
				path: `${restEndpointChainRedirects}?page=${page}&per_page=${perPage}`,
			});

			if (response.success) {
				setRedirects(response.data);
				setTotal(response.total);
				setTotalPages(response.pages);
				setCurrentPage(response.page);
				setShowProcessButton(true);
			} else {
				setError(__('Failed to load chain redirects.', 'redirect-cleanup'));
			}
		} catch (err) {
			setError(err.message || __('An error occurred while loading chain redirects.', 'redirect-cleanup'));
		} finally {
			setIsLoadingRedirects(false);
		}
	};

	/**
	 * Handle page change.
	 */
	const handlePageChange = (newPage) => {
		if (newPage >= 1 && newPage <= totalPages) {
			if (redirectType === 'chain') {
				loadChainRedirects(newPage);
			} else {
				loadRedirects(newPage);
			}
		}
	};

	/**
	 * Handle post type checkbox change.
	 */
	const handlePostTypeChange = (postType, checked) => {
		if (checked) {
			setSelectedPostTypes([...selectedPostTypes, postType]);
		} else {
			setSelectedPostTypes(selectedPostTypes.filter(type => type !== postType));
		}
	};

	/**
	 * Process chain redirects to fix them.
	 */
	const handleProcessChainRedirects = async () => {
		setIsProcessing(true);
		setError(null);
		setSuccess(null);
		setProcessingResults(null);

		try {
			const response = await apiFetch({
				path: restEndpointFixChainRedirects,
				method: 'POST',
				data: {
					min_chain_length: 3,
					dry_run: dryRun,
				},
			});

			if (!response.success) {
				setError(response.message || __('Failed to fix chain redirects.', 'redirect-cleanup'));
				return;
			}

			// Set final results for chain redirects.
			setProcessingResults({
				chainsFixed: response.chains_fixed,
				redirectsUpdated: response.redirects_updated,
				redirectsRemoved: response.redirects_removed,
				details: response.details,
				dryRun: response.dry_run,
				isChainFix: true,
			});

			setSuccess(response.message);
		} catch (err) {
			setError(err.message || __('An error occurred while fixing chain redirects.', 'redirect-cleanup'));
		} finally {
			setIsProcessing(false);
		}
	};

	/**
	 * Process posts to remove redirect URLs (batch processing).
	 */
	const handleProcess = async () => {
		// Route to chain redirect handler if that's the selected type.
		if (redirectType === 'chain') {
			return handleProcessChainRedirects();
		}

		setIsProcessing(true);
		setError(null);
		setSuccess(null);
		setProcessingResults(null);
		setProcessingProgress({
			processed: 0,
			total: 0,
			postsUpdated: 0,
			linksRemoved: 0,
		});

		const batchSize = 300;
		let offset = 0;
		let hasMore = true;
		let totalPosts = 0;
		let totalPostsUpdated = 0;
		let totalLinksRemoved = 0;
		let urlLimit = 500;
		const allDetails = [];

		try {
			while (hasMore) {
				const response = await apiFetch({
					path: `${restEndpointProcessBatch}`,
					method: 'POST',
					data: {
						offset,
						batch_size: batchSize,
						url_limit: urlLimit,
						post_types: selectedPostTypes,
						dry_run: dryRun,
					},
				});

				if (!response.success) {
					setError(__('Failed to process posts.', 'redirect-cleanup'));
					break;
				}

				// Update totals from first response.
				if (offset === 0) {
					totalPosts = response.total;
				}

				totalPostsUpdated += response.posts_updated;
				totalLinksRemoved += response.links_removed;

				// Collect details.
				if (response.details) {
					allDetails.push(...response.details);
				}

				// Update progress.
				setProcessingProgress({
					processed: Math.min(offset + response.processed, totalPosts),
					total: totalPosts,
					postsUpdated: totalPostsUpdated,
					linksRemoved: totalLinksRemoved,
				});

				hasMore = response.has_more;
				offset += batchSize;
			}

			// Set final results.
			setProcessingResults({
				postsUpdated: totalPostsUpdated,
				linksRemoved: totalLinksRemoved,
				details: allDetails,
				dryRun: dryRun,
				isChainFix: false,
			});

			if (totalPostsUpdated > 0) {
				setSuccess(
					dryRun
						? `${__("Dry run complete", "redirect-cleanup")}: ${totalPostsUpdated} ${__("post(s) would be updated", "redirect-cleanup")}, ${totalLinksRemoved} ${__("link(s) would be removed", "redirect-cleanup")}.`
						: `${totalPostsUpdated} ${__("post(s) updated", "redirect-cleanup")}, ${totalLinksRemoved} ${__("link(s) removed", "redirect-cleanup")}.`
				);
			} else {
				setSuccess(__('No posts found with redirect URLs to remove.', "redirect-cleanup"));
			}
		} catch (err) {
			setError(err.message || __('An error occurred while processing.', 'redirect-cleanup'));
		} finally {
			setIsProcessing(false);
		}
	};

	/**
	 * Render pagination controls.
	 */
	const renderPagination = () => {
		if (totalPages <= 1) {
			return null;
		}

		const pageNumbers = [];
		const maxVisible = 5;
		let startPage = Math.max(1, currentPage - Math.floor(maxVisible / 2));
		let endPage = Math.min(totalPages, startPage + maxVisible - 1);

		if (endPage - startPage < maxVisible - 1) {
			startPage = Math.max(1, endPage - maxVisible + 1);
		}

		for (let i = startPage; i <= endPage; i++) {
			pageNumbers.push(i);
		}

		return (
			<div className="redirect-cleanup-pagination">
				<Button
					onClick={() => handlePageChange(currentPage - 1)}
					disabled={currentPage === 1 || isLoadingRedirects}
					isSecondary
				>
					{__('Previous', 'redirect-cleanup')}
				</Button>
				<span className="redirect-cleanup-page-info">
					{__('Page', 'redirect-cleanup')} {currentPage} {__('of', 'redirect-cleanup')} {totalPages} ({__('total', 'redirect-cleanup')} {total})
				</span>
				{pageNumbers.map((pageNum) => (
					<Button
						key={pageNum}
						onClick={() => handlePageChange(pageNum)}
						isPrimary={currentPage === pageNum}
						isSecondary={currentPage !== pageNum}
						disabled={isLoadingRedirects}
					>
						{pageNum}
					</Button>
				))}
				<Button
					onClick={() => handlePageChange(currentPage + 1)}
					disabled={currentPage === totalPages || isLoadingRedirects}
					isSecondary
				>
					{__('Next', 'redirect-cleanup')}
				</Button>
			</div>
		);
	};

	/**
	 * Load available post types on mount
	 */
	useEffect(() => {
		const loadPostTypes = async () => {
			try {
				const response = await apiFetch({
					path: restEndpointPostTypes
				})

				if (response.success && response.data) {
					setAvailablePostTypes(response.data)
				} else {
					setAvailablePostTypes([
						{ label: __("Posts", "redirect-cleanup"), value: "post" },
						{ label: __("Pages", "redirect-cleanup"), value: "page" }
					])
				}
			} catch (error) {
				console.error("Error loading post types:", error)
				setAvailablePostTypes([
					{ label: __("Posts", "redirect-cleanup"), value: "post" },
					{ label: __("Pages", "redirect-cleanup"), value: "page" }
				])
			}
		}

		loadPostTypes()
	}, [])

	/**
	 * Load stats on mount
	 */
	useEffect(() => {
		const loadStats = async () => {
			try {
				// Set initial values from localized data
				if (isNotPaying !== undefined) {
					setIsFreeUser(isNotPaying);
				}
				if (upgradeUrlFromLocalize) {
					setUpgradeUrl(upgradeUrlFromLocalize);
				}

				// Fetch current stats from API
				if (restEndpointStats) {
					const response = await apiFetch({
						path: restEndpointStats
					});

					if (response.success) {
						setIsFreeUser(response.is_not_paying || false);
						setUpgradeUrl(response.upgrade_url || '');
					}
				}
			} catch (error) {
				console.error("Error loading stats:", error);
			}
		};

		loadStats();
	}, [restEndpointStats, isNotPaying, upgradeUrlFromLocalize])

	return (
		<div className="redirect-cleanup-admin-page">
			<div className="redirect-cleanup-redirect-type-selector">
				<SelectControl
					label={__("Redirect Type", "redirect-cleanup")}
					value={redirectType}
					onChange={redirectType => setRedirectType(redirectType)}
					__next40pxDefaultSize={true}
					__nextHasNoMarginBottom={true}
					options={[
						{ label: __("Chain redirects", "redirect-cleanup"), value: "chain" },
						{ label: __("Homepage redirects", "redirect-cleanup"), value: "homepage" },
					]}
					disabled={isScanning}
				/>
			</div>
			<div className="redirect-cleanup-header">				
				<Button
					onClick={handleScan}
					isPrimary
					isBusy={isScanning}
					disabled={isScanning || isProcessing}
				>
					{isScanning ? (
						<>
							<Spinner /> {__("Scanning...", "redirect-cleanup")}
						</>
					) : (
						__("Scan for Redirects", "redirect-cleanup")
					)}
				</Button>

				{showProcessButton && !isFreeUser && (
					<Button
						onClick={handleProcess}
						isSecondary
						isBusy={isProcessing}
						disabled={isProcessing || isScanning || total === 0}
					>
						{isProcessing ? (
							<>
								<Spinner /> {__("Processing...", "redirect-cleanup")}
							</>
						) : (
							redirectType === 'chain'
								? __("Fix chain redirects", "redirect-cleanup")
								: __("Remove Redirect URLs from Posts", "redirect-cleanup")
						)}
					</Button>
				)}

			</div>

			{isFreeUser && total > 0 && !isProcessing && !isScanning && (
				<div className="redirect-cleanup-upgrade-notice" style={{ marginTop: '20px', marginBottom: '20px', padding: '20px', backgroundColor: '#fff8e5', border: '1px solid #f0c36d', borderRadius: '4px' }}>
					<h3 style={{ marginTop: 0, marginBottom: '10px' }}>
						{__('Clean These Redirects in One Click', 'redirect-cleanup')}
					</h3>
					<p style={{ marginBottom: '15px' }}>
						{redirectType === 'chain'
							? __('Want to fix all these redirect chains automatically? Upgrade to Pro!', 'redirect-cleanup')
							: __('Want to remove all these redirect URLs from your posts? Upgrade to Pro!', 'redirect-cleanup')
						}
					</p>
					{upgradeUrl && (
						<a href={upgradeUrl} className="button button-primary">
							{__('Upgrade to Pro', 'redirect-cleanup')}
						</a>
					)}
				</div>
			)}
			
			{!isFreeUser && !isProcessing && !isScanning && total !== 0 && (
				<CheckboxControl
					label={__("Run as dry run", "redirect-cleanup")}
					help={__("If checked, no changes will be made to the database, allowing you to check the results beforehand.", "redirect-cleanup")}
					checked={dryRun}
					onChange={setDryRun}
					disabled={isProcessing || isScanning}
					__nextHasNoMarginBottom={true}
				/>
			)}			

			{error && (
				<Notice status="error" isDismissible onRemove={() => setError(null)}>
					{error}
				</Notice>
			)}

			{isProcessing && processingProgress.total > 0 && (
				<div className="redirect-cleanup-progress">
					<div className="redirect-cleanup-progress-bar">
						<div
							className="redirect-cleanup-progress-fill"
							style={{
								width: `${Math.round(
									(processingProgress.processed / processingProgress.total) * 100
								)}%`,
							}}
						/>
					</div>
					<div className="redirect-cleanup-progress-text">
						{__("Processing", "redirect-cleanup")}: {processingProgress.processed} / {processingProgress.total} {__("posts", "redirect-cleanup")}
						{processingProgress.postsUpdated > 0 && (
							<span className="redirect-cleanup-progress-stats">
								{' '}
								| {processingProgress.postsUpdated} {dryRun ? __("would be updated", "redirect-cleanup") : __("updated", "redirect-cleanup")} |{' '}
								{processingProgress.linksRemoved} {__("links", "redirect-cleanup")} {dryRun ? __("would be removed", "redirect-cleanup") : __("removed", "redirect-cleanup")}
							</span>
						)}
					</div>
				</div>
			)}

			{processingResults && !isProcessing && (
				<div className="redirect-cleanup-results">
					<h3>
						{processingResults.dryRun
							? __("Processing Results (Dry Run)", "redirect-cleanup")
							: __("Processing Results", "redirect-cleanup")}
					</h3>
					{processingResults.isChainFix ? (
						<>
							<p>
								<strong>{processingResults.chainsFixed}</strong> {processingResults.dryRun ? __("chain(s) would be fixed", "redirect-cleanup") : __("chain(s) fixed", "redirect-cleanup")},{' '}
								<strong>{processingResults.redirectsUpdated}</strong> {processingResults.dryRun ? __("redirect(s) would be updated", "redirect-cleanup") : __("redirect(s) updated", "redirect-cleanup")},{' '}
								<strong>{processingResults.redirectsRemoved}</strong> {processingResults.dryRun ? __("redirect(s) would be removed", "redirect-cleanup") : __("redirect(s) removed", "redirect-cleanup")}.
							</p>
							{processingResults.details && processingResults.details.length > 0 && (
								<div className="redirect-cleanup-chain-fix-details">
									<h4>{__("Details", "redirect-cleanup")}</h4>
									<ul>
										{processingResults.details.map((detail, index) => (
											<li key={index}>
												{detail.action === 'updated' ? (
													<>
														<code>{detail.source_url}</code> → <code>{detail.new_target}</code>
														<span className="redirect-cleanup-detail-info">
															{' '}({__("was", "redirect-cleanup")} <code>{detail.old_target}</code>)
														</span>
													</>
												) : detail.action === 'skipped' ? (
													<>
														<code>{detail.source_url}</code>
														<span className="redirect-cleanup-detail-warning">
															{' '}({detail.reason})
														</span>
													</>
												) : null}
											</li>
										))}
									</ul>
								</div>
							)}
						</>
					) : (
						<p>
							<strong>{processingResults.postsUpdated}</strong> {processingResults.dryRun ? __("post(s) would be updated", "redirect-cleanup") : __("post(s) updated", "redirect-cleanup")},{' '}
							<strong>{processingResults.linksRemoved}</strong> {processingResults.dryRun ? __("link(s) would be removed", "redirect-cleanup") : __("link(s) removed", "redirect-cleanup")}.
						</p>
					)}
				</div>
			)}

			{total > 0 && (
				<div className="redirect-cleanup-stats">
					<p>
						{__("Found", "redirect-cleanup")} <strong>{total}</strong>{' '}
						{redirectType === 'chain' 
							? (total !== 1 ? __("redirect chains", "redirect-cleanup") : __("redirect chain", "redirect-cleanup"))
							: (total !== 1 ? __("homepage redirects", "redirect-cleanup") : __("homepage redirect", "redirect-cleanup"))
						}.
					</p>
				</div>
			)}
	
			
			{redirectType === 'homepage' && (
				<div className="redirect-cleanup-post-types-filters">
					{availablePostTypes.length > 0 ? (
						<VStack>	
							{availablePostTypes.map(type => (
								<CheckboxControl
									key={type.value}
									label={type.label}
									__nextHasNoMarginBottom={true}
									checked={selectedPostTypes.includes(type.value)}
									onChange={checked => handlePostTypeChange(type.value, checked)}
									disabled={isScanning}
								/>
							))}
						</VStack>
					) : (
						<VStack>
							<CheckboxControl
								label={__("Posts", "redirect-cleanup")}
								__nextHasNoMarginBottom={true}
								checked={selectedPostTypes.includes("post")}
								onChange={checked => handlePostTypeChange("post", checked)}
								disabled={isScanning}
							/>
							<CheckboxControl
								label={__("Pages", "redirect-cleanup")}
								__nextHasNoMarginBottom={true}
								checked={selectedPostTypes.includes("page")}
								onChange={checked => handlePostTypeChange("page", checked)}
								disabled={isScanning}
							/>						
						</VStack>
					)}
				</div>
			)}

			{renderPagination()}

			{redirects.length > 0 && (
				<div className="redirect-cleanup-table-wrapper">
					{isLoadingRedirects && (
						<div className="redirect-cleanup-loading-overlay">
							<Spinner />
						</div>
					)}
					{redirectType === 'chain' ? (
						<table className="wp-list-table widefat fixed striped redirect-cleanup-chain-table">
							<thead>
								<tr>
									<th>{__("Source URL", "redirect-cleanup")}</th>
									<th>{__("Chain Path", "redirect-cleanup")}</th>
									<th>{__("Length", "redirect-cleanup")}</th>
									<th>{__("Loop", "redirect-cleanup")}</th>
								</tr>
							</thead>
							<tbody>
								{redirects.map((redirect, index) => (
									<tr key={index}>
										<td>
											<code>{redirect.source_url}</code>
										</td>
										<td>
											<ul className="redirect-cleanup-chain-list">
												{redirect.chain && redirect.chain.map((url, chainIndex) => (
													<li key={chainIndex}>
														<code>{url}</code>
														{chainIndex < redirect.chain.length - 1 && (
															<span className="redirect-cleanup-chain-arrow"> → </span>
														)}
													</li>
												))}
											</ul>
										</td>
										<td>
											<span className="redirect-cleanup-chain-length">{redirect.length}</span>
										</td>
										<td>
											{redirect.loop ? (
												<span className="redirect-cleanup-loop redirect-cleanup-loop-yes">
													{__("Yes", "redirect-cleanup")}
												</span>
											) : (
												<span className="redirect-cleanup-loop redirect-cleanup-loop-no">
													{__("No", "redirect-cleanup")}
												</span>
											)}
										</td>
									</tr>
								))}
							</tbody>
						</table>
					) : (
						<table className="wp-list-table widefat fixed striped">
							<thead>
								<tr>
									<th>{__("Source URL", "redirect-cleanup")}</th>
									<th>{__("Found In", "redirect-cleanup")}</th>
									<th>{__("Redirect Type", "redirect-cleanup")}</th>
								</tr>
							</thead>
							<tbody>
								{redirects.map((redirect, index) => (
									<tr key={index}>
										<td>
											<code>{redirect.source_url}</code>
										</td>
										<td>
											{redirect.found_in && redirect.found_in.length > 0 ? (
												<ul className="redirect-cleanup-found-in-list">
													{redirect.found_in.map((post) => (
														<li key={post.id}>
															<a
																href={post.edit_url}
																target="_blank"
																rel="noopener noreferrer"
															>
																{post.title}
															</a>
														</li>
													))}
												</ul>
											) : (
												<span className="redirect-cleanup-not-found">
													{__("Not found in any post", "redirect-cleanup")}
												</span>
											)}
										</td>
										<td>
											<span className={`redirect-type redirect-type-${redirect.type || __('301', 'redirect-cleanup')}`}>
												{redirect.type || __('301', 'redirect-cleanup')}
											</span>
										</td>
									</tr>
								))}
							</tbody>
						</table>
					)}
				</div>
			)}

			{redirects.length === 0 && total === 0 && !isScanning && (
				<div className="redirect-cleanup-empty">
					<p>
						{__('No redirects found. Click "Scan for Redirects" to search.', "redirect-cleanup")}
					</p>
				</div>
			)}

			{renderPagination()}
		</div>
	);
}

export default AdminPage;
