<?php
/**
 * Frontend scripts and styles loader.
 *
 * @package    EventKoi
 * @subpackage EventKoi\Core
 */

namespace EventKoi\Core;

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

/**
 * Handles frontend scripts and inline styles.
 */
class Scripts {

	/**
	 * Constructor: Hooks into front-end actions.
	 */
	public function __construct() {
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 999 );

		// SiteGround Optimizer (and similar) re-minify the already-minified Vite
		// bundle, mangling its template literals into a syntax error that breaks
		// the whole combined file so the calendar never renders. Exclude our
		// bundle from re-minification only — it stays in the combined file so its
		// React dependency order is preserved, but its (already valid) code is
		// left untouched.
		add_filter( 'sgo_js_minify_exclude', array( $this, 'exclude_from_js_optimizers' ) );
	}

	/**
	 * Add EventKoi's frontend script handles to a JS-optimizer exclusion list.
	 *
	 * @param array $handles Script handles the optimizer will skip.
	 * @return array
	 */
	public function exclude_from_js_optimizers( $handles ) {
		$handles   = is_array( $handles ) ? $handles : array();
		$handles[] = 'eventkoi-frontend';

		return apply_filters( 'eventkoi_js_optimizer_excluded_handles', $handles );
	}

	/**
	 * Enqueue frontend assets.
	 */
	public function enqueue_scripts() {
		self::enqueue_frontend_assets();
	}

	/**
	 * Register and enqueue frontend assets, so they can also be reused elsewhere (Elementor).
	 */
	public static function enqueue_frontend_assets() {
		static $registered = false;

		$build_dir  = EVENTKOI_PLUGIN_DIR . 'scripts/frontend/build/';
		$asset_path = $build_dir . 'index.asset.php';

		if ( ! file_exists( $asset_path ) ) {
			return;
		}

		$asset_file = include $asset_path;
		$build_url  = EVENTKOI_PLUGIN_URL . 'scripts/frontend/build/';
		$hot_file   = $build_dir . '.vite-hot';
		$is_dev     = file_exists( $hot_file );

		// Register and enqueue JS (once).
		if ( ! $registered ) {
			$registered = true;

			if ( $is_dev ) {
				$vite_url = trim( file_get_contents( $hot_file ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
				wp_register_script(
					'eventkoi-frontend',
					$vite_url . '/src/index.js',
					$asset_file['dependencies'],
					null,
					true
				);
				add_filter(
					'script_loader_tag',
					function ( $tag, $handle ) use ( $vite_url ) {
						if ( 'eventkoi-frontend' !== $handle ) {
							return $tag;
						}
						$client = '<script type="module" src="' . esc_url( $vite_url . '/@vite/client' ) . '"></script>' . "\n";
						$tag    = str_replace( array( " type='text/javascript'", ' type="text/javascript"' ), '', $tag );
						$tag    = str_replace( '<script ', '<script type="module" ', $tag );
						return $client . $tag;
					},
					10,
					2
				);
			} else {
				wp_register_script(
					'eventkoi-frontend',
					$build_url . 'index.js',
					$asset_file['dependencies'],
					$asset_file['version'],
					true
				);
			}
		}
		wp_enqueue_script( 'eventkoi-frontend' );

		// Prepare localized variables.
		$event_id = get_the_ID();
		$event    = $event_id ? new Event( $event_id ) : null;
		$calendar = Calendar::get_meta();
		$settings = Settings::get();

		$current_user = wp_get_current_user();
		$rsvp_user    = array();

		if ( $current_user && $current_user->ID ) {
			$first_name = isset( $current_user->first_name ) ? sanitize_text_field( $current_user->first_name ) : '';
			$last_name  = isset( $current_user->last_name ) ? sanitize_text_field( $current_user->last_name ) : '';
			$full_name  = trim( $first_name . ' ' . $last_name );

			$rsvp_user = array(
				'id'         => (int) $current_user->ID,
				'name'       => $full_name,
				'first_name' => $first_name,
				'last_name'  => $last_name,
				'email'      => sanitize_email( $current_user->user_email ),
			);
		}

		$params = array(
			'is_admin'             => current_user_can( 'manage_options' ),
			'admin_page'           => admin_url( 'admin.php?page=eventkoi' ),
			'demo_event_id'        => (int) get_option( 'eventkoi_demo_event_id', 0 ),
			'default_cal_id'       => \eventkoi_resolve_calendar_id( (int) get_option( 'eventkoi_default_event_cal', 0 ) ),
			'version'              => EVENTKOI_VERSION,
			'api'                  => EVENTKOI_API,
			'rest_url'             => esc_url_raw( rest_url( EVENTKOI_API ) ),
			'event'                => $event ? $event::get_meta() : array(),
			'ical'                 => $event ? $event::get_ical() : '',
			'no_events'            => __( 'No events were found.', 'eventkoi-lite' ),
			'timezone'             => wp_timezone_string(),
			'timezone_offset'      => ( get_option( 'gmt_offset' ) ?? 0 ) * 3600,
			'date_format'          => \eventkoi_resolved_date_format(),
			'time_format_string'   => \eventkoi_resolved_time_format(),
			'gmap'                 => array(
				'api_key'   => $settings['gmap_api_key'] ?? '',
				'connected' => ! empty( $settings['gmap_connection_status'] ),
			),
			'time_format'          => $settings['time_format'] ?? '12',
			'day_start_time'       => $settings['day_start_time'] ?? '07:00',
			'locale'               => determine_locale(),
			'startday'             => empty( $calendar['startday'] ) ? $settings['week_starts_on'] : $calendar['startday'],
			'working_days'         => isset( $settings['working_days'] ) && is_array( $settings['working_days'] )
				? array_values( array_map( 'intval', $settings['working_days'] ) )
				: array( 0, 1, 2, 3, 4 ),
				'auto_detect_timezone' => rest_sanitize_boolean( $settings['auto_detect_timezone'] ?? false ),
			'nonce'                => wp_create_nonce( 'wp_rest' ),
			'rsvp_user'            => $rsvp_user,
			'rsvp_fields'          => Rsvps::get_custom_fields( (int) $event_id ),
			'checkout_fields'      => Orders::get_checkout_fields( (int) $event_id ),
			'rsvp_show_name'       => (bool) apply_filters( 'eventkoi_rsvp_show_name_field', true, (int) $event_id ),
			// Filter-only behavior, no UI. Defaults off.
			'mobile_list_default'  => (bool) apply_filters( 'eventkoi_calendar_mobile_list_default', false ),
		);

		wp_localize_script(
			'eventkoi-frontend',
			'eventkoi_params',
			apply_filters( 'eventkoi_frontend_params', $params )
		);

		wp_set_script_translations(
			'eventkoi-frontend',
			'eventkoi-lite',
			WP_LANG_DIR . '/plugins'
		);

		// Enqueue styles.
		wp_register_style( 'eventkoi-frontend-tw', $build_url . 'tailwind.css', array(), $asset_file['version'] );
		wp_enqueue_style( 'eventkoi-frontend-tw' );

		if ( ! $is_dev ) {
			wp_register_style( 'eventkoi-frontend', $build_url . 'index.css', array(), $asset_file['version'] );
			wp_enqueue_style( 'eventkoi-frontend' );
		}

		// Inline css.
		if ( is_tax( 'event_cal' ) ) {
			$term = get_queried_object();
			if ( $term && ! is_wp_error( $term ) && isset( $term->term_id ) ) {
				$calendar = new Calendar( $term->term_id );
				$color    = $calendar::get_color();

				$css = sprintf(
					':root { --fc-event-bg-color: %1$s; --fc-event-border-color: %1$s; --ek-calendar-accent: %1$s; }',
					esc_attr( $color )
				);

				// eventkoi-frontend is only registered in production; in dev
				// mode (vite) it doesn't exist and wp_add_inline_style would
				// silently no-op. eventkoi-frontend-tw is always registered.
				wp_add_inline_style( 'eventkoi-frontend-tw', $css );
			}
		}
	}
}
