<?php
/**
 * Blog Posts Synchronization Template.
 *
 * This file handles the synchronization of blog posts with the Postomatic API.
 *
 * @package Postomatic
 * @subpackage Admin
 */

namespace Postomatic\Admin;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// Delay page to receive data from API.

if ( isset( $_GET['key'] ) && 'sync' === $_GET['key'] && wp_verify_nonce( isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '', 'postomatic_sync_action' ) ) {
	$current_url  = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
	$query_string = wp_parse_url( $current_url, PHP_URL_QUERY );
	parse_str( $query_string, $query_params );

	if ( isset( $query_params['key'] ) ) {
		unset( $query_params['key'] );
	}
	if ( isset( $query_params['offset'] ) ) {
		unset( $query_params['offset'] );
	}
	if ( isset( $query_params['_wpnonce'] ) ) {
		unset( $query_params['_wpnonce'] );
	}
	$new_url = strtok( $current_url, '?' ) . ( count( $query_params ) ? '?' . http_build_query( $query_params ) : '' );
	$offset  = isset( $_GET['offset'] ) ? absint( wp_unslash( $_GET['offset'] ) ) : 0;
	?>
	<html>
	<head>
		<style>
			.loading-container {
				max-width: 600px;
				margin: 50px auto;
				text-align: center;
				font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
			}

			.title {
				font-size: 28px;
				color: #2563eb;
				font-weight: 600;
				margin-bottom: 16px;
			}

			.subtitle {
				font-size: 16px;
				color: #64748b;
				line-height: 1.6;
				margin-bottom: 32px;
			}

			.progress-container {
				background-color: #e2e8f0;
				border-radius: 8px;
				padding: 4px;
				margin: 20px 0;
			}

			.progress-bar {
				height: 8px;
				background-color: #2563eb;
				border-radius: 6px;
				transition: width 0.3s ease;
				width: 0%;
			}

			.progress-text {
				font-size: 14px;
				color: #64748b;
				margin-top: 8px;
			}

			.loading-spinner {
				width: 40px;
				height: 40px;
				margin: 20px auto;
				border: 3px solid #e2e8f0;
				border-radius: 50%;
				border-top-color: #2563eb;
				animation: spin 1s linear infinite;
			}

			@keyframes spin {
				to {
					transform: rotate(360deg);
				}
			}
		</style>
	</head>
	<body>

	<div class="loading-container">
		<h2 class="title">Processing Your Blog Data</h2>
		<p class="subtitle">We're analyzing your blog content to ensure the best possible experience.
			This may take a few moments.</p>

		<div class="progress-container">
			<div id="progressBar" class="progress-bar"></div>
		</div>
		<div id="progressText" class="progress-text">Processing posts...</div>

		<div class="loading-spinner"></div>
	</div>

	</body>
	<script>
		document.addEventListener("DOMContentLoaded", () => {
			processPosts("<?php echo esc_js( $offset ); ?>");
		});

		async function sendToApi(posts, offset) {
			try {
				let dataToSend;
				if (posts.length) {
					dataToSend = posts.map(post => ({
						id: post.id,
						title: post.title.rendered,
						url: post.link,
						tags: post.tags,
						excerpt: post.excerpt.rendered
					}));
				} else {
					dataToSend = []
				}

				// Routed through admin-ajax so the API service key stays on the
				// server. This used to call the remote endpoint directly, which
				// required printing the key into this page for the Api-Key header.
				const body = new URLSearchParams();
				body.append('action', 'postomatic_sync_blog_posts');
				body.append('nonce', '<?php echo esc_js( wp_create_nonce( 'postomatic_admin_nonce' ) ); ?>');
				body.append('offset', offset);
				body.append('posts', JSON.stringify(dataToSend));

				const response = await fetch('<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>', {
					method: 'POST',
					credentials: 'same-origin',
					headers: {
						'Content-Type': 'application/x-www-form-urlencoded'
					},
					body: body
				});

				if (!response.ok) {
					throw new Error('Failed to send data to API');
				}

				const result = await response.json();

				if (!result || !result.success) {
					throw new Error('Failed to send data to API');
				}

			} catch (error) {
				setTimeout(() => window.location.href = "<?php echo esc_js( $new_url ); ?>", 3000);
				throw new Error('Unauthorized or server issue');
			}
		}

		async function updateProgress(processed, total) {
			const progressBar = document.getElementById('progressBar');
			const progressText = document.getElementById('progressText');
			const percentage = Math.min((processed / total) * 100, 100);

			progressBar.style.width = `${percentage}%`;
			progressText.textContent = `Processing posts... ${Math.round(percentage)}%`;
		}

		async function processPosts(offset = 0) {
			const batchSize = 10;
			let totalPosts = 0;
			offset = parseInt(offset);

			try {
				// Fetch total posts count (ensure correct ordering parameters)
				const totalResponse = await fetch('/wp-json/wp/v2/posts?per_page=1&orderby=id&order=desc');
				const lastPost = await totalResponse.json();
				const lastPostId = lastPost[0]?.id; // Using optional chaining in case there are no posts

				totalPosts = parseInt(lastPostId);

				while (offset < totalPosts) { // Loop until offset reaches totalPosts
					// Fetch posts ordered by ID to maintain consistent pagination
					const posts = await fetchPosts(offset, batchSize);
					if ((offset + batchSize) > totalPosts) {
						await sendToApi(posts, totalPosts);
						break;
					}

					await sendToApi(posts, offset);
					offset += batchSize; // Increment by the number of posts processed
					await updateProgress(offset, totalPosts);
				}

				setTimeout(() => window.location.href = "<?php echo esc_js( $new_url ); ?>", 3000);
			} catch (error) {
				setTimeout(() => window.location.href = "<?php echo esc_js( $new_url ); ?>", 7000);
			}
		}

		async function fetchPosts(offset, batchSize) {
			// Ensure posts are ordered by ID for reliable pagination
			const response = await fetch(
				`/wp-json/wp/v2/posts?per_page=${batchSize}&offset=${offset}&orderby=id&order=asc&status=publish`
			);
			return await response.json();
		}

	</script>
	</html>

	<?php

	exit();
}
