<?php

declare( strict_types=1 );

namespace StrykeWP\Modules\WipMode;

use StrykeWP\Core\OptionManager;

/**
 * WIP Mode Frontend Controller.
 *
 * Handles the `template_redirect` hook and outputs the WIP holding page
 * for non-admin visitors when the module is active.
 *
 * Migrated from stryke-wip v1.6 (procedural stryke_wip_frontend_display()).
 * Color corrected: #27B9C6 → #00BCD4 (STRYKE brand primary).
 *
 * Options read (with legacy fallback for migration):
 *  - New:    stryke_wp_module_wip_mode_active       (via OptionManager)
 *  - Legacy: stryke_wip_active                      (direct get_option)
 *  - New:    stryke_wp_module_wip_mode_allowed_pages (via OptionManager)
 *  - Legacy: stryke_wip_allowed_pages_ids            (direct get_option)
 *
 * @package StrykeWP\Modules\WipMode
 */
class WipController {

	public function __construct(
		private readonly OptionManager $options,
	) {}

	// -----------------------------------------------------------------------
	// Hook Callback
	// -----------------------------------------------------------------------

	/**
	 * Hooked to `template_redirect`.
	 * Intercepts the request and outputs the WIP page when conditions are met.
	 *
	 * @return void
	 */
	public function maybe_show_wip_page(): void {

		if ( ! $this->is_wip_active() ) {
			return;
		}

		// Administrators always bypass WIP mode.
		if ( current_user_can( 'manage_options' ) ) {
			return;
		}

		// Check if the current page is on the whitelist.
		$allowed_ids = $this->get_allowed_page_ids();

		if ( ! empty( $allowed_ids ) && is_page( $allowed_ids ) ) {
			return;
		}

		// Send 503 headers.
		header( 'HTTP/1.1 503 Service Temporarily Unavailable' );
		header( 'Retry-After: 3600' );

		$this->render_wip_page();
		exit;
	}

	// -----------------------------------------------------------------------
	// Option Accessors (with legacy migration fallback)
	// -----------------------------------------------------------------------

	/**
	 * Returns true if WIP mode is currently active.
	 * Reads new option first, falls back to legacy stryke_wip_active.
	 *
	 * @return bool
	 */
	public function is_wip_active(): bool {
		$new_value = $this->options->module_get( 'wip_mode', 'active', null );

		if ( null !== $new_value ) {
			return (bool) $new_value;
		}

		// Legacy fallback.
		return 'active' === get_option( 'stryke_wip_active', 'inactive' );
	}

	/**
	 * Returns the allowed page IDs whitelist.
	 * Reads new option first, falls back to legacy stryke_wip_allowed_pages_ids.
	 *
	 * @return int[]
	 */
	public function get_allowed_page_ids(): array {
		$new_value = $this->options->module_get( 'wip_mode', 'allowed_pages', null );

		if ( null !== $new_value && is_array( $new_value ) ) {
			return array_map( 'absint', $new_value );
		}

		// Legacy fallback.
		$legacy = get_option( 'stryke_wip_allowed_pages_ids', array() );
		return is_array( $legacy ) ? array_map( 'absint', $legacy ) : array();
	}

	// -----------------------------------------------------------------------
	// WIP Page Template
	// -----------------------------------------------------------------------

	/**
	 * Outputs the full WIP holding page HTML.
	 *
	 * @return void
	 */
	private function render_wip_page(): void {
		?>
		<!DOCTYPE html>
		<html <?php language_attributes(); ?>>
		<head>
			<meta charset="UTF-8">
			<meta name="viewport" content="width=device-width, initial-scale=1.0">
			<title><?php echo esc_html( get_bloginfo( 'name' ) ); ?> — Work In Progress</title>
			<style>
				:root {
					--stryke-dark:   #1a1a1a;
					--stryke-medium: #252525;
					--stryke-accent: #189ba7;
					--stryke-light:  #f0f0f0;
					--stryke-muted:  #9e9e9e;
				}
				* { box-sizing: border-box; margin: 0; padding: 0; }
				body {
					background-color: var(--stryke-dark);
					color: var(--stryke-light);
					font-family: 'Inter', 'Helvetica Neue', Arial, sans-serif;
					display: flex;
					justify-content: center;
					align-items: center;
					min-height: 100vh;
					padding: 20px;
					text-align: center;
				}
				.wip-container {
					background-color: var(--stryke-medium);
					border-radius: 12px;
					padding: 50px 30px;
					max-width: 680px;
					width: 100%;
					box-shadow: 0 15px 40px rgba(0, 0, 0, .6);
					border-top: 4px solid var(--stryke-accent);
					animation: fadeIn .8s ease-out;
				}
				.wip-logo {
					margin-bottom: 28px;
				}
				.wip-logo__img {
					max-height: 64px;
					width: auto;
					display: block;
					margin: 0 auto;
				}
				.wip-logo__mark {
					display: inline-flex;
					align-items: center;
					justify-content: center;
					width: 64px;
					height: 64px;
					border-radius: 50%;
					background: var(--stryke-accent);
					color: var(--stryke-dark);
					font-size: 28px;
					font-weight: 800;
					letter-spacing: -1px;
				}
				h1 {
					color: var(--stryke-light);
					font-size: clamp(1.6rem, 4vw, 2.4rem);
					font-weight: 800;
					text-transform: uppercase;
					letter-spacing: 4px;
					margin-bottom: 6px;
					line-height: 1.2;
				}
				.wip-tagline {
					color: var(--stryke-accent);
					font-size: .9rem;
					letter-spacing: 3px;
					text-transform: uppercase;
					margin-bottom: 28px;
				}
				.wip-message {
					font-size: 1rem;
					line-height: 1.7;
					color: var(--stryke-muted);
					margin-bottom: 36px;
				}
				.wip-loader {
					border: 3px solid rgba(255,255,255,.1);
					border-top: 3px solid var(--stryke-accent);
					border-radius: 50%;
					width: 36px;
					height: 36px;
					animation: spin 1s linear infinite;
					margin: 0 auto 32px;
				}
				.wip-footer__brand {
					display: block;
					color: var(--stryke-accent);
					font-size: 1rem;
					font-weight: 700;
					letter-spacing: 0.05em;
					margin-bottom: 4px;
				}
				.wip-footer a {
					color: var(--stryke-muted);
					text-decoration: none;
					font-size: .8rem;
					font-weight: 500;
					transition: color .2s;
				}
				.wip-footer a:hover { color: var(--stryke-accent); }
				@keyframes spin {
					0%   { transform: rotate(0deg); }
					100% { transform: rotate(360deg); }
				}
				@keyframes fadeIn {
					from { opacity: 0; transform: translateY(16px); }
					to   { opacity: 1; transform: translateY(0); }
				}
			</style>
		</head>
		<body>
			<div class="wip-container">
				<div class="wip-logo">
					<?php
					$logo_path = STRYKE_WP_DIR . 'src/Modules/Branding/assets/img/stryke-logo.png';
					if ( file_exists( $logo_path ) ) :
						$logo_url = plugins_url( 'src/Modules/Branding/assets/img/stryke-logo.png', STRYKE_WP_DIR . '/stryke-wp.php' );
					?>
						<img src="<?php echo esc_url( $logo_url ); ?>" alt="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>" class="wip-logo__img" />
					<?php else : ?>
						<span class="wip-logo__mark">S</span>
					<?php endif; ?>
				</div>
				<h1><?php echo esc_html( get_bloginfo( 'name' ) ); ?></h1>
				<p class="wip-tagline"><?php esc_html_e( 'Work In Progress', 'stryke-wp' ); ?></p>
				<div class="wip-loader" aria-hidden="true"></div>
				<p class="wip-message">
					<?php esc_html_e( 'Wir nehmen uns die letzten Momente, um jedes Detail zu perfektionieren. Qualität und strategische Ausrichtung haben oberste Priorität. Danke für Ihre Geduld — wir starten in Kürze durch.', 'stryke-wp' ); ?>
				</p>
				<div class="wip-footer">
					<span class="wip-footer__brand">STRYKE Hub</span>
					<a href="https://www.strykemarketing.de" target="_blank" rel="noopener noreferrer">by STRYKE Marketing</a>
				</div>
			</div>
		</body>
		</html>
		<?php
	}
}
