<?php
/**
 * Design System enqueuer.
 *
 * @package Polanger_Dashboard_Tools
 */

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

/**
 * Handles runtime asset output.
 */
class PDT_Design_Enqueue {
  /**
   * @var PDT_Design_Settings
   */
  private $settings;

  /**
   * @var PDT_Design_Generator
   */
  private $generator;

  /**
   * Constructor.
   *
   * @param PDT_Design_Settings  $settings  Settings helper.
   * @param PDT_Design_Generator $generator CSS generator.
   */
  public function __construct( $settings, $generator ) {
    $this->settings  = $settings;
    $this->generator = $generator;
  }

  /**
   * Enqueue for admin pages when scope requires it.
   *
   * @param string $hook_suffix Admin hook suffix.
   * @return void
   */
  public function enqueue_for_admin( $hook_suffix ) {
    $settings = $this->get_effective_settings();

    if ( empty( $settings['enabled'] ) ) {
      return;
    }

    if ( ! $this->should_enqueue_for_admin_request( $settings, $hook_suffix ) ) {
      return;
    }

		$this->enqueue_compiled_css( $settings );
		$this->enqueue_theme_assets( $settings );
		$this->enqueue_midnight_runtime_fix( $settings );
	}

  /**
   * Enqueue admin bar styles on the frontend for logged-in users.
   *
   * @return void
   */
  public function enqueue_for_frontend() {
    if ( is_admin() || ! is_user_logged_in() || ! is_admin_bar_showing() ) {
      return;
    }

    $settings = $this->settings->get_settings();
    if ( empty( $settings['enabled'] ) ) {
      return;
    }

    $this->enqueue_compiled_css( $settings );
  }

  /**
   * Get settings that should be reflected on the current request.
   *
   * @return array
   */
  private function get_effective_settings() {
    $settings = $this->settings->get_settings();

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $current_page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
    if ( 'polanger-design-system' !== $current_page ) {
      return $settings;
    }

    if ( empty( $_POST['pdt_design_save'] ) || empty( $_POST['_wpnonce'] ) ) {
      return $settings;
    }

    $nonce = sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) );
    if ( ! wp_verify_nonce( $nonce, 'pdt_design_save' ) ) {
      return $settings;
    }

    $raw = isset( $_POST['pdt_design'] ) ? wp_unslash( $_POST['pdt_design'] ) : array();
    $raw = $this->settings->prepare_raw_settings( $raw, $settings );
    return $this->settings->sanitize_settings( $raw );
  }

  /**
   * Decide whether current admin request should receive the theme CSS.
   *
   * @param array  $settings Design settings.
   * @param string $hook_suffix Admin hook suffix.
   * @return bool
   */
  private function should_enqueue_for_admin_request( $settings, $hook_suffix ) {
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $current_page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
    $scope = isset( $settings['scope'] ) ? $settings['scope'] : 'polanger_only';

    switch ( $scope ) {
      case 'all_admin':
        return true;

      case 'all_admin_exclude_plugins':
        return ! $this->is_third_party_plugin_screen( $hook_suffix, $current_page );

      case 'selected_screens':
        $selected = isset( $settings['selected_screens'] ) && is_array( $settings['selected_screens'] ) ? $settings['selected_screens'] : array();
        $current_keys = $this->get_current_screen_keys( $hook_suffix, $current_page );
        return ! empty( array_intersect( $selected, $current_keys ) );

      case 'polanger_only':
      default:
        return ( '' !== $current_page && 0 === strpos( $current_page, 'polanger-' ) );
    }
  }

  /**
   * Determine whether a screen belongs to a plugin-owned admin page.
   *
   * @param string $hook_suffix Admin hook suffix.
   * @param string $current_page Current page query arg.
   * @return bool
   */
  private function is_third_party_plugin_screen( $hook_suffix, $current_page ) {
    if ( ! empty( $current_page ) && 0 === strpos( $current_page, 'polanger-' ) ) {
      return false;
    }

    if ( 0 === strpos( $hook_suffix, 'toplevel_page_' ) ) {
      return true;
    }

    return false !== strpos( $hook_suffix, '_page_' );
  }

  /**
   * Map the current screen into high-level buckets for scope targeting.
   *
   * @param string $hook_suffix Admin hook suffix.
   * @param string $current_page Current page query arg.
   * @return array
   */
  private function get_current_screen_keys( $hook_suffix, $current_page ) {
    $keys = array();

    if ( '' !== $current_page && 0 === strpos( $current_page, 'polanger-' ) ) {
      $keys[] = 'polanger';
    }

    $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
    $base = ( $screen && ! empty( $screen->base ) ) ? (string) $screen->base : '';
    $post_type = ( $screen && ! empty( $screen->post_type ) ) ? (string) $screen->post_type : '';

    if ( 'index.php' === $hook_suffix || 'dashboard' === $base ) {
      $keys[] = 'dashboard';
    }

    if ( 'upload' === $base || 'upload.php' === $hook_suffix ) {
      $keys[] = 'media';
    }

    if ( false !== strpos( $base, 'comment' ) || 'edit-comments.php' === $hook_suffix ) {
      $keys[] = 'comments';
    }

    if ( in_array( $hook_suffix, array( 'themes.php', 'widgets.php', 'nav-menus.php', 'customize.php' ), true ) || false !== strpos( $base, 'appearance' ) || false !== strpos( $base, 'theme' ) ) {
      $keys[] = 'appearance';
    }

    if ( in_array( $hook_suffix, array( 'plugins.php', 'plugin-install.php' ), true ) || 'plugins' === $base || 'plugin-install' === $base ) {
      $keys[] = 'plugins';
    }

    if ( in_array( $hook_suffix, array( 'users.php', 'user-new.php', 'profile.php', 'user-edit.php' ), true ) || false !== strpos( $base, 'user' ) || 'profile' === $base ) {
      $keys[] = 'users';
    }

    if ( in_array( $hook_suffix, array( 'tools.php', 'import.php', 'export.php', 'site-health.php', 'export-personal-data.php', 'erase-personal-data.php' ), true ) || false !== strpos( $base, 'tools' ) || false !== strpos( $base, 'site-health' ) ) {
      $keys[] = 'tools';
    }

    if ( 0 === strpos( $hook_suffix, 'options-' ) || false !== strpos( $base, 'options-' ) ) {
      $keys[] = 'settings';
    }

    if ( in_array( $base, array( 'post', 'edit' ), true ) ) {
      if ( 'page' === $post_type ) {
        $keys[] = 'pages';
      } elseif ( 'post' === $post_type || '' === $post_type ) {
        $keys[] = 'posts';
      } else {
        $keys[] = 'custom_post_types';
      }
    }

    if ( empty( $keys ) && ! empty( $post_type ) && ! in_array( $post_type, array( 'post', 'page' ), true ) ) {
      $keys[] = 'custom_post_types';
    }

    return array_values( array_unique( $keys ) );
  }

  /**
   * Enqueue generated CSS with inline fallback.
   *
   * @param array $settings Settings.
   * @return void
   */
	private function enqueue_compiled_css( $settings ) {
    $this->generator->compile_if_needed( $settings );

    wp_enqueue_style(
      'pdt-design-base',
      plugin_dir_url( dirname( __FILE__ ) ) . 'assets/base.css',
      array(),
      PDT_VERSION
    );

    $meta = $this->settings->get_css_meta();
    if ( ! empty( $meta['url'] ) && ! empty( $meta['path'] ) && file_exists( $meta['path'] ) ) {
      $url = set_url_scheme( $meta['url'] );

      wp_enqueue_style(
        'pdt-design-generated',
        $url,
        array( 'pdt-design-base' ),
        isset( $meta['hash'] ) ? $meta['hash'] : PDT_VERSION
      );

      /**
       * Keep an inline fallback by default so migrated sites, strict hosts, mixed
       * scheme setups, or upload/CDN rules cannot silently disable the theme.
       */
      if ( apply_filters( 'pdt_design_inline_fallback_enabled', true, $settings, $meta ) ) {
        wp_add_inline_style( 'pdt-design-generated', $this->generator->build_css( $settings ) );
      }

      return;
    }

		wp_add_inline_style( 'pdt-design-base', $this->generator->build_css( $settings ) );
	}

	/**
	 * Enqueue optional theme-pack CSS after generated tokens.
	 *
	 * @param array $settings Settings.
	 * @return void
	 */
	private function enqueue_theme_assets( $settings ) {
		if ( ! class_exists( 'PDT_Design_Themes' ) ) {
			return;
		}

		$preset = isset( $settings['preset'] ) ? (string) $settings['preset'] : '';
		$asset  = PDT_Design_Themes::get_asset( $preset, 'admin.css' );
		if ( ! $asset ) {
			return;
		}

		$dependency = wp_style_is( 'pdt-design-generated', 'enqueued' ) ? 'pdt-design-generated' : 'pdt-design-base';

		wp_enqueue_style(
			'pdt-design-theme-' . sanitize_key( $preset ),
			set_url_scheme( $asset['url'] ),
			array( $dependency ),
			$asset['version']
		);
	}

	/**
	 * Enqueue the Midnight-only third-party text contrast fixer.
   *
   * @param array $settings Active design settings.
   * @return void
   */
  private function enqueue_midnight_runtime_fix( $settings ) {
    $preset = isset( $settings['preset'] ) ? (string) $settings['preset'] : '';
    if ( 'dark' !== $preset ) {
      return;
    }

    $resolved = $this->generator->resolve_tokens( $settings );

    wp_enqueue_script(
      'pdt-design-runtime',
      plugin_dir_url( dirname( __FILE__ ) ) . 'assets/runtime.js',
      array(),
      PDT_VERSION,
      true
    );

    wp_localize_script(
      'pdt-design-runtime',
      'pdtDesignMidnightFix',
      array(
        'enabled'            => true,
        'textColor'          => isset( $resolved['resolved_on_surface'] ) ? $resolved['resolved_on_surface'] : '#f8fafc',
        'darkThreshold'      => 0.22,
        'minContrast'        => 4.4,
        'containerSelectors' => array(
          '.postbox .inside',
          '.stuffbox .inside',
          '.widget-inside',
          '.widgets-holder-wrap',
          '.accordion-section-content',
          '.tabs-panel',
          '.misc-pub-section',
          '.submitbox .inside',
          '.categorydiv div.tabs-panel',
          '.customlinkdiv div.tabs-panel',
        ),
      )
    );
  }
}
