<?php
declare(strict_types=1);
namespace ConfManager\Frontend;

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


use ConfManager\Traits\Singleton;
use ConfManager\Traits\HasHooks;

/**
 * フロント画面のショートコード登録とスクリプトエンキュー
 *
 * @since 1.0.0
 */
class PublicController {

	use Singleton;
	use HasHooks;

	/**
	 * 初期化
	 */
	protected function init(): void {
		$this->register_hooks();
	}

	/**
	 * フック登録
	 */
	protected function register_hooks(): void {
		$this->add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
		$this->add_action( 'init', [ $this, 'register_shortcodes' ] );
	}

	/**
	 * ショートコードを登録
	 */
	public function register_shortcodes(): void {
		add_shortcode( 'conf_manager', [ $this, 'render_shortcode' ] );
	}

	/**
	 * ショートコード出力
	 *
	 * @param array $atts ショートコード属性
	 * @return string HTML出力
	 */
	public function render_shortcode( array $atts ): string {
		$atts = shortcode_atts(
			[ 'view' => 'registration' ],
			$atts,
			'conf_manager'
		);

		// Pro 版でのみ提供する view。ここでフォールバックさせずに打ち切る。
		//
		// フォールバックすると [conf_manager view="reviewer-apply"] のような指定が
		// 警告なしに参加申込フォームを描画し、査読者応募のつもりのページで
		// 申込が実際に登録されてしまう（既定の固定ページは c-registration と
		// c-mypage の 2 枚だけなので、利用者が自分でページを作ったときに起きる）。
		//
		// 案内文は固定ページを直せる権限の利用者にだけ出す。公開ページは
		// WordPress.org ガイドライン 11 の "only on the plugin's setting page" の
		// 範囲外なので、一般の閲覧者に Pro の訴求は出さない（docs/FREEMIUM.md §1.3）。
		// Pro の src/public/App.jsx の case から registration / mypage（Core にもある）を
		// 除いた全件。Pro の有効化はこれらの固定ページ（c-sponsors 等）も作るので、
		// Pro から Free へ切り替えた環境には該当するページが残っている。
		$pro_views = [ 'submission', 'sponsors', 'sponsor-apply', 'sponsor-mypage', 'reviewer', 'reviewer-apply', 'invitation' ];
		if ( in_array( $atts['view'], $pro_views, true ) ) {
			if ( ! current_user_can( 'edit_posts' ) ) {
				return '';
			}

			return '<p class="conf-manager-notice">' . esc_html__(
				'This view is provided by Conference Manager Pro, which is a separate plugin. Remove this shortcode or replace it with a supported view.',
				'conferencemanager'
			) . '</p>';
		}

		// Core でサポートする view のみ許可（不明な view は registration にフォールバック）
		$supported_views = [ 'registration', 'mypage' ];
		if ( ! in_array( $atts['view'], $supported_views, true ) ) {
			$atts['view'] = 'registration';
		}

		wp_enqueue_script( 'conf-manager-public' );
		wp_enqueue_style( 'conf-manager-public' );

		return '<div id="conf-manager-public-app" data-view="' . esc_attr( $atts['view'] ) . '"></div>';
	}

	/**
	 * フロント画面用スクリプト・スタイルを登録
	 */
	public function enqueue_scripts(): void {
		$asset_file = CONF_MANAGER_PLUGIN_DIR . 'build/public-app.asset.php';
		$asset      = file_exists( $asset_file )
			? require $asset_file
			: [ 'dependencies' => [], 'version' => CONF_MANAGER_VERSION ];

		wp_register_script(
			'conf-manager-public',
			CONF_MANAGER_PLUGIN_URL . 'build/public-app.js',
			$asset['dependencies'],
			$asset['version'],
			true
		);

		wp_set_script_translations(
			'conf-manager-public',
			'conferencemanager',
			CONF_MANAGER_PLUGIN_DIR . 'languages'
		);

		// 決済設定をフロントに渡す
		$payment_methods = get_option( 'conf_manager_payment_methods', [ 'bank' ] );
		if ( ! is_array( $payment_methods ) ) {
			$payment_methods = [ 'bank' ];
		}

		// ⚠️ v1.4.0 でカード決済（Stripe）は Pro 版の機能になった。
		// 過去に保存された 'stripe' が option に残っていても**公開画面には出さない**
		// （出すと、選べるのに決済できない状態になる）。
		$payment_methods = array_values(
			array_filter( $payment_methods, static fn( $m ): bool => 'stripe' !== $m )
		);
		if ( empty( $payment_methods ) ) {
			// 'stripe' だけが保存されていたサイトでも申込フォームが成立するようにする。
			$payment_methods = [ 'bank' ];
		}

		// 会員種別の表示に前置する学会の略称（未設定なら空＝何も付かない）。
		// 🔴 管理側（admin/class-admin-menu.php）にも同じものを渡すこと。
		//    片方だけだと管理と公開で表記が割れる。
		wp_localize_script(
			'conf-manager-public',
			'confManagerMemberType',
			\ConfManager\Members\MemberTypeLabel::script_data()
		);

		wp_localize_script( 'conf-manager-public', 'confManagerPayment', [
			'methods' => $payment_methods,
		] );

		// 利用規約ページURL
		$terms_page = get_page_by_path( 'c-terms' );
		$terms_url  = $terms_page ? get_permalink( $terms_page ) : '';
		wp_localize_script( 'conf-manager-public', 'confManagerTerms', [
			'url' => $terms_url,
		] );

		// セキュリティ: CSRF トークン + ボットガードチャレンジ
		$bot_challenge = \ConfManager\Security\BotGuard::instance()->generate_challenge();
		wp_localize_script( 'conf-manager-public', 'confManagerSecurity', [
			'csrfToken' => wp_create_nonce( 'conf_manager_public_csrf' ),
			'botGuard'  => $bot_challenge,
		] );

		wp_register_style(
			'conf-manager-public',
			CONF_MANAGER_PLUGIN_URL . 'public/css/public.css',
			[],
			CONF_MANAGER_VERSION
		);
	}
}
