<?php
/**
 * Frontend Class for Coming Soon Pro (mdxcsp).
 *
 * Handles rendering the coming soon / maintenance page on the frontend.
 *
 * @package MDXCSP_Coming_Soon_Pro
 */

// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Frontend class for handling coming soon page display.
 */
class MDXCSP_Frontend {

	/**
	 * Option keys and defaults.
	 */
	const OPTION_ENABLE    = 'mdxcsp_enable_coming_soon';
	const OPTION_TEMPLATE  = 'mdxcsp_selected_template';
	const DEFAULT_TEMPLATE = 'template-1';

	/**
	 * Template configurations.
	 *
	 * @var array
	 */
	private $template_configs = array(
		'template-1' => array(
			'supports'          => array(
				'logo'             => true,
				'background'       => true,
				'title'            => true,
				'subtitle'         => true,
				'countdown'        => true,
				'menu_items'       => true,
				'menu_toggle'      => true,
				'social_icons'     => true,
				'copyright'        => true,
				'background_modes' => array( 'image', 'color' ),
			),
			'max_menu_items'    => 5,
			'required'          => array( 'title' ),
			'template_file'     => 'index.php',
		),
		'template-2' => array(
			'supports'          => array(
				'logo'             => true,
				'background'       => true,
				'title'            => true,
				'subtitle'         => false,
				'countdown'        => false,
				'menu_items'       => true,
				'menu_toggle'      => false,
				'social_icons'     => true,
				'copyright'        => true,
				'background_modes' => array( 'image' ),
			),
			'max_menu_items'    => 3,
			'required'          => array( 'title', 'logo' ),
			'template_file'     => 'index.php',
		),
	);

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'template_redirect', array( $this, 'maybe_render_coming_soon' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) );
	}

	/**
	 * Determine if Coming Soon/Maintenance mode is enabled.
	 *
	 * @return bool
	 */
	private function is_mode_enabled(): bool {
		$value = get_option( self::OPTION_ENABLE, '0' );
		return ! empty( $value ) && '1' === (string) $value;
	}

	/**
	 * Get current selected template (sanitized).
	 *
	 * @return string
	 */
	private function current_template(): string {
		$template = get_option( self::OPTION_TEMPLATE, self::DEFAULT_TEMPLATE );
		$template = sanitize_key( (string) $template );
		return '' === $template ? self::DEFAULT_TEMPLATE : $template;
	}

	/**
	 * Get template configuration.
	 *
	 * @param string $template_key Template key.
	 * @return array
	 */
	private function get_template_config( string $template_key ): array {
		return $this->template_configs[ $template_key ] ?? array();
	}

	/**
	 * Enqueue frontend CSS & JS for selected template.
	 *
	 * Note: The template view should call wp_head()/wp_footer() for enqueued assets to output.
	 *
	 * @return void
	 */
	public function enqueue_assets(): void {
		// Only enqueue if coming soon mode is enabled.
		if ( ! $this->is_mode_enabled() ) {
			return;
		}

		// Allow administrators to bypass assets (they won't see coming soon).
		if ( current_user_can( 'manage_options' ) ) {
			return;
		}

		$template  = $this->current_template();
		$style_dir = MDXCSP_PLUGIN_DIR . 'src/frontend/' . $template . '/style.css';
		$style_url = MDXCSP_PLUGIN_URL . 'src/frontend/' . $template . '/style.css';

		if ( file_exists( $style_dir ) ) {
			wp_enqueue_style(
				'mdxcsp-template-style',
				$style_url,
				array(),
				MDXCSP_PLUGIN_VERSION
			);
		}

		$frontend_js_path = MDXCSP_PLUGIN_DIR . 'assets/js/frontend.js';
		$frontend_js_url  = MDXCSP_PLUGIN_URL . 'assets/js/frontend.js';

		if ( file_exists( $frontend_js_path ) ) {
			wp_enqueue_script(
				'mdxcsp-frontend-js',
				$frontend_js_url,
				array(),
				MDXCSP_PLUGIN_VERSION,
				true
			);
		}
	}

	/**
	 * Build a fully-populated context array for the selected template,
	 * providing safe defaults (including plugin asset fallbacks) so the
	 * frontend always renders nicely even before any admin save.
	 *
	 * @param string $template Template key.
	 * @return array
	 */
	private function build_template_context( string $template ): array {
		$all_settings = get_option( 'mdxcsp_template_settings', array() );
		$opts         = ( isset( $all_settings[ $template ] ) && is_array( $all_settings[ $template ] ) ) ? $all_settings[ $template ] : array();

		// Plugin asset defaults (URLs).
		$asset_logo   = MDXCSP_PLUGIN_URL . 'assets/images/logo.png';
		$asset_bg     = MDXCSP_PLUGIN_URL . 'assets/images/bg-1.jpeg';
		$asset_toggle = MDXCSP_PLUGIN_URL . 'assets/images/toggle.png';
		$asset_s1     = MDXCSP_PLUGIN_URL . 'assets/images/social-1.png';
		$asset_s2     = MDXCSP_PLUGIN_URL . 'assets/images/social-2.png';

		// Template-specific background images.
		$default_bg_images = array(
			'template-1' => MDXCSP_PLUGIN_URL . 'assets/images/bg-1.jpeg',
			'template-2' => MDXCSP_PLUGIN_URL . 'assets/images/bg-2.jpg',
		);
		$asset_bg = $default_bg_images[ $template ] ?? $asset_bg;

		// IDs from options.
		$logo_id   = isset( $opts['logo_id'] ) ? absint( $opts['logo_id'] ) : 0;
		$bg_id     = isset( $opts['bg_id'] ) ? absint( $opts['bg_id'] ) : 0;
		$bg_mode   = ( isset( $opts['bg_mode'] ) && in_array( $opts['bg_mode'], array( 'image', 'color' ), true ) ) ? $opts['bg_mode'] : 'image';
		$bg_color  = isset( $opts['bg_color'] ) ? $this->sanitize_hex_color( $opts['bg_color'] ) : '';

		$title           = isset( $opts['title'] ) ? (string) $opts['title'] : '';
		$title_color     = isset( $opts['title_color'] ) ? $this->sanitize_hex_color( $opts['title_color'] ) : '';
		$subtitle        = isset( $opts['subtitle'] ) ? (string) $opts['subtitle'] : '';
		$subtitle_color  = isset( $opts['subtitle_color'] ) ? $this->sanitize_hex_color( $opts['subtitle_color'] ) : '';
		$target_ts       = isset( $opts['target_timestamp'] ) ? (int) $opts['target_timestamp'] : 0;
		$countdown_color = isset( $opts['countdown_color'] ) ? $this->sanitize_hex_color( $opts['countdown_color'] ) : '';

		$menu_1_label = isset( $opts['menu_1_label'] ) ? (string) $opts['menu_1_label'] : '';
		$menu_1_url   = isset( $opts['menu_1_url'] ) ? (string) $opts['menu_1_url'] : '';
		$menu_1_color = isset( $opts['menu_1_color'] ) ? $this->sanitize_hex_color( $opts['menu_1_color'] ) : '';

		$menu_2_label = isset( $opts['menu_2_label'] ) ? (string) $opts['menu_2_label'] : '';
		$menu_2_url   = isset( $opts['menu_2_url'] ) ? (string) $opts['menu_2_url'] : '';
		$menu_2_color = isset( $opts['menu_2_color'] ) ? $this->sanitize_hex_color( $opts['menu_2_color'] ) : '';

		$menu_3_label = isset( $opts['menu_3_label'] ) ? (string) $opts['menu_3_label'] : '';
		$menu_3_url   = isset( $opts['menu_3_url'] ) ? (string) $opts['menu_3_url'] : '';
		$menu_3_color = isset( $opts['menu_3_color'] ) ? $this->sanitize_hex_color( $opts['menu_3_color'] ) : '';

		$nav_color = isset( $opts['nav_color'] ) ? $this->sanitize_hex_color( $opts['nav_color'] ) : '';

		$menu_toggle_icon_id     = isset( $opts['menu_toggle_icon_id'] ) ? absint( $opts['menu_toggle_icon_id'] ) : 0;
		$menu_toggle_label       = isset( $opts['menu_toggle_label'] ) ? (string) $opts['menu_toggle_label'] : '';
		$menu_toggle_label_color = isset( $opts['menu_toggle_label_color'] ) ? $this->sanitize_hex_color( $opts['menu_toggle_label_color'] ) : '';

		$social_1_id  = isset( $opts['social_1_id'] ) ? absint( $opts['social_1_id'] ) : 0;
		$social_1_url = isset( $opts['social_1_url'] ) ? (string) $opts['social_1_url'] : '';
		$social_2_id  = isset( $opts['social_2_id'] ) ? absint( $opts['social_2_id'] ) : 0;
		$social_2_url = isset( $opts['social_2_url'] ) ? (string) $opts['social_2_url'] : '';

		$copyright_text  = isset( $opts['copyright_text'] ) ? (string) $opts['copyright_text'] : '';
		$copyright_color = isset( $opts['copyright_color'] ) ? $this->sanitize_hex_color( $opts['copyright_color'] ) : '';

		// Resolve URLs for images with fallbacks to plugin assets.
		$logo_url = $logo_id ? wp_get_attachment_image_url( $logo_id, 'full' ) : '';
		if ( empty( $logo_url ) ) {
			$logo_url = $asset_logo;
		}

		$bg_url = $bg_id ? wp_get_attachment_image_url( $bg_id, 'full' ) : '';
		if ( 'image' === $bg_mode && empty( $bg_url ) ) {
			$bg_url = $asset_bg;
		}

		$toggle_icon_url = '';
		if ( $menu_toggle_icon_id ) {
			$toggle_icon_url = wp_get_attachment_image_url( $menu_toggle_icon_id, 'full' );
		}
		if ( empty( $toggle_icon_url ) ) {
			$toggle_icon_url = $asset_toggle;
		}

		$social_1_img = $social_1_id ? wp_get_attachment_image_url( $social_1_id, 'full' ) : '';
		if ( empty( $social_1_img ) ) {
			$social_1_img = $asset_s1;
		}
		$social_2_img = $social_2_id ? wp_get_attachment_image_url( $social_2_id, 'full' ) : '';
		if ( empty( $social_2_img ) ) {
			$social_2_img = $asset_s2;
		}

		// Prefill text defaults.
		if ( '' === $title ) {
			$title = __( 'We are launching soon', 'xpertcodes-coming-soon-maintenance' );
		}
		if ( '' === $title_color ) {
			$title_color = '#ffffff';
		}
		if ( '' === $subtitle ) {
			$subtitle = __( 'Our site is getting ready. Stay tuned for something amazing!', 'xpertcodes-coming-soon-maintenance' );
		}
		if ( '' === $subtitle_color ) {
			$subtitle_color = '#E5E7EB';
		}

		// Target timestamp: default to midnight +30 days in site timezone.
		if ( 0 === $target_ts ) {
			$tz  = function_exists( 'wp_timezone' ) ? wp_timezone() : new DateTimeZone( get_option( 'timezone_string' ) ?: 'UTC' );
			$now = new DateTime( 'now', $tz );
			$now->setTime( 0, 0 );
			$now->add( new DateInterval( 'P30D' ) );
			$target_ts = $now->getTimestamp();
		}
		if ( '' === $countdown_color ) {
			$countdown_color = '#ffffff';
		}

		// Menu items and colors (defaults).
		if ( '' === $nav_color ) {
			$nav_color = '#ffffff';
		}
		if ( '' === $menu_1_label ) {
			$menu_1_label = __( 'Home', 'xpertcodes-coming-soon-maintenance' );
			$menu_1_url   = '#home';
		}
		if ( '' === $menu_2_label ) {
			$menu_2_label = __( 'About', 'xpertcodes-coming-soon-maintenance' );
			$menu_2_url   = '#about';
		}
		if ( '' === $menu_3_label ) {
			$menu_3_label = __( 'Contact', 'xpertcodes-coming-soon-maintenance' );
			$menu_3_url   = '#contact';
		}
		if ( '' === $menu_1_color ) {
			$menu_1_color = $nav_color;
		}
		if ( '' === $menu_2_color ) {
			$menu_2_color = $nav_color;
		}
		if ( '' === $menu_3_color ) {
			$menu_3_color = $nav_color;
		}

		// Toggle label + color defaults.
		if ( '' === $menu_toggle_label ) {
			$menu_toggle_label = '☰ ' . __( 'Menu', 'xpertcodes-coming-soon-maintenance' );
		}
		if ( '' === $menu_toggle_label_color ) {
			$menu_toggle_label_color = $nav_color;
		}

		// Social URLs defaults.
		if ( '' === $social_1_url ) {
			$social_1_url = '#social';
		}
		if ( '' === $social_2_url ) {
			$social_2_url = '#social-2';
		}

		// Copyright.
		if ( '' === $copyright_text ) {
			$copyright_text = __( 'Your Company. All rights reserved.', 'xpertcodes-coming-soon-maintenance' );
		}
		if ( '' === $copyright_color ) {
			$copyright_color = '#9CA3AF';
		}

		// Build final context for the view.
		$context = array(
			'template' => $template,

			// Branding.
			'logo_id'  => $logo_id,
			'logo_url' => $logo_url,

			// Background.
			'bg_mode'  => $bg_mode,
			'bg_id'    => $bg_id,
			'bg_url'   => ( 'image' === $bg_mode ) ? $bg_url : '',
			'bg_color' => ( 'color' === $bg_mode ) ? $bg_color : '',

			// Text.
			'title'           => $title,
			'title_color'     => $title_color,
			'subtitle'        => $subtitle,
			'subtitle_color'  => $subtitle_color,

			// Countdown.
			'target_timestamp' => $target_ts,
			'countdown_color'  => $countdown_color,

			// Menu items.
			'nav_color'    => $nav_color,

			'menu_1_label' => $menu_1_label,
			'menu_1_url'   => $menu_1_url,
			'menu_1_color' => $menu_1_color,

			'menu_2_label' => $menu_2_label,
			'menu_2_url'   => $menu_2_url,
			'menu_2_color' => $menu_2_color,

			'menu_3_label' => $menu_3_label,
			'menu_3_url'   => $menu_3_url,
			'menu_3_color' => $menu_3_color,

			// Toggle.
			'menu_toggle_icon_id'     => $menu_toggle_icon_id,
			'menu_toggle_icon_url'    => $toggle_icon_url,
			'menu_toggle_label'       => $menu_toggle_label,
			'menu_toggle_label_color' => $menu_toggle_label_color,

			// Social.
			'social_1_id'  => $social_1_id,
			'social_1_img' => $social_1_img,
			'social_1_url' => $social_1_url,

			'social_2_id'  => $social_2_id,
			'social_2_img' => $social_2_img,
			'social_2_url' => $social_2_url,

			// Footer.
			'copyright_text'  => $copyright_text,
			'copyright_color' => $copyright_color,
		);

		/**
		 * Filter the final template context array before rendering.
		 *
		 * @param array  $context  Data sent to the view.
		 * @param string $template Template key.
		 */
		return apply_filters( 'mdxcsp_template_context', $context, $template );
	}

	/**
	 * Check if Coming Soon mode is enabled and display template.
	 *
	 * - Skips REST, AJAX, cron, CLI, feeds, embeds, and customizer previews.
	 * - Loads `templates/{template}/index.php`.
	 *
	 * @return void
	 */
	public function maybe_render_coming_soon(): void {
		// Don't interfere with REST API, AJAX, CRON or CLI.
		if ( ( defined( 'REST_REQUEST' ) && REST_REQUEST )
			|| ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() )
			|| ( function_exists( 'wp_doing_cron' ) && wp_doing_cron() )
			|| ( defined( 'WP_CLI' ) && WP_CLI ) ) {
			return;
		}

		// Avoid breaking feeds, embeds, or customizer previews.
		if ( function_exists( 'is_feed' ) && is_feed() ) {
			return;
		}
		if ( function_exists( 'is_embed' ) && is_embed() ) {
			return;
		}
		if ( function_exists( 'is_customize_preview' ) && is_customize_preview() ) {
			return;
		}
		if ( function_exists( 'is_preview' ) && is_preview() ) {
			return;
		}

		// Get plugin state.
		if ( ! $this->is_mode_enabled() ) {
			return;
		}

		// Allow administrators to bypass the coming soon page.
		if ( current_user_can( 'manage_options' ) ) {
			return;
		}

		// Get selected template and resolve view path.
		$template  = $this->current_template();
		$config    = $this->get_template_config( $template );
		$file_name = $config['template_file'] ?? 'index.php';
		$view_file = MDXCSP_PLUGIN_DIR . 'src/frontend/' . $template . '/' . $file_name;

		if ( file_exists( $view_file ) ) {
			// Send 503 header (maintenance) and discourage indexing.
			status_header( 503 );

			if ( ! headers_sent() ) {
				nocache_headers();
				header( 'Retry-After: 3600' );
				header( 'X-Robots-Tag: noindex, nofollow, noarchive' );
				header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );
			}

			/**
			 * Fires before rendering the Coming Soon template.
			 *
			 * @param string $template Template key.
			 */
			do_action( 'mdxcsp_before_render_coming_soon', $template );

			// Build and expose a context array for the template to use.
			$mdxcsp_context = $this->build_template_context( $template );

			include $view_file; // phpcs:ignore WordPress.WP.IncludeFile

			/**
			 * Fires after rendering the Coming Soon template.
			 *
			 * @param string $template Template key.
			 */
			do_action( 'mdxcsp_after_render_coming_soon', $template );

			exit;
		}

		// If view file is missing, fallback with 503 response.
		wp_die(
			esc_html__( 'Coming Soon Mode is active, but the selected template view could not be found.', 'xpertcodes-coming-soon-maintenance' ),
			esc_html__( 'Coming Soon', 'xpertcodes-coming-soon-maintenance' ),
			array( 'response' => 503 )
		);
	}

	/**
	 * Sanitize hex color with graceful fallback.
	 *
	 * @param mixed $color Raw color.
	 * @return string
	 */
	private function sanitize_hex_color( $color ): string {
		$color = trim( (string) $color );
		if ( '' === $color ) {
			return '';
		}

		if ( function_exists( 'sanitize_hex_color' ) ) {
			$hex = sanitize_hex_color( $color );
			return $hex ? $hex : '';
		}

		// Basic fallback: #RGB or #RRGGBB.
		return preg_match( '/^#([A-Fa-f0-9]{3}){1,2}$/', $color ) ? $color : '';
	}
}