<?php if ( !defined( 'ABSPATH' ) ) exit;//PHPの宣言と直接アクセスの拒否

/*** HAUP: 中国からの不審なIP帯域を基礎リストとして .htaccess に書き込む ***/
/*** メインの同期処理 ***/
function haup_update_security_ip_block_htaccess() {

	$htaccess_file = ABSPATH . '.htaccess';

	//20260315 サーバーソフトではなく.htaccessの有無と書き込み権限での判別に変更
	// .htaccessが存在しない、または書き込み権限がない場合は即終了
	if ( ! file_exists( $htaccess_file ) || ! is_writable( $htaccess_file ) ) {
		return;
	}

	// 以降、Apache/LiteSpeed環境であるとみなして処理を継続
	require_once( ABSPATH . 'wp-admin/includes/misc.php' );

	// A. 外部JSON（マスター）から取得
	$base_url = 'https://habone.biz/haup-common-ban-ip-list/';

	// 1. まず「どのファイルを読み込むべきか」のリストを取得
	$index_response = wp_remote_get( $base_url . 'master-list-index.json' );

	$final_labels = [];
	$master_lists = ['ip-list.json'];
    
	if ( ! is_wp_error( $index_response ) && wp_remote_retrieve_response_code( $index_response ) === 200 ) {
		$index_data = json_decode( wp_remote_retrieve_body( $index_response ), true );
		$master_lists = $index_data['files'] ?? ['ip-list.json'];
    
		// ラベル処理
		$locale = ( strpos( get_locale(), 'ja' ) !== false ) ? 'ja' : 'en';
		$remote_labels = $index_data['labels'] ?? [];

		foreach ( $remote_labels as $slug => $langs ) {
			// 多層構造 { "ja": "中国", "en": "China" } から現在の言語を選択
			if ( is_array( $langs ) ) {
				$final_labels[$slug] = $langs[$locale] ?? $langs['en'];
			} else {
				// もしJSONが多層になっていない場合のフォールバック
				$final_labels[$slug] = $langs;
			}
		}
	}

	$base_deny_ips = [];
	$details = []; // 国別の内訳を格納する配列を追加

	foreach ( $master_lists as $list_file ) {
		$response = wp_remote_get( $base_url . $list_file );

		if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) {
			$data = json_decode( wp_remote_retrieve_body( $response ), true );
			if ( isset( $data['blocked_ips'] ) && is_array( $data['blocked_ips'] ) ) {
				$count = count( $data['blocked_ips'] );
				// 取得したIPをマージしていく
				$base_deny_ips = array_merge( $base_deny_ips, $data['blocked_ips'] );
				
				// ファイル名から「ip-list-」と「.json」を除去して表示用の名前に
				$display_name = str_replace( ['ip-list-', '.json'], '', $list_file );

				if ( $display_name === 'ip-list' ) {
					$display_name = 'common'; // ここで完全に common に上書き
				}

					$details[$display_name] = $count;
			}
		}
	}

	// B. 各サイト固有のカスタムリストをマージ
	$custom_ips = get_option( 'haup_custom_blocked_ips', '' );

	if ( ! empty( $custom_ips ) ) {
		$custom_array  = array_filter( array_map( 'trim', explode( "\n", $custom_ips ) ) );
		$base_deny_ips = array_merge( $base_deny_ips, $custom_array );
	}

	$base_deny_ips = array_unique( $base_deny_ips );

	if ( empty( $base_deny_ips ) ) return;

	// C. .htaccess書き換え準備
	require_once( ABSPATH . 'wp-admin/includes/misc.php' );
	$htaccess_file = ABSPATH . '.htaccess';
	$my_ip         = $_SERVER['REMOTE_ADDR'] ?? ''; // 自分のIPを取得

	$rules = [
	"RewriteEngine On",
	"# --- HAUP Base Rules (Traversal Block) ---",
	"RewriteCond %{QUERY_STRING} \.\.\/ [NC,OR]",
	"RewriteCond %{REQUEST_URI} \.\.\/ [NC]",
	"RewriteRule .* - [F,L]",
	"", // 空行
	"# --- HAUP Dynamic IP Block ---",
	"<RequireAll>",
	"    Require all granted"
	];
	
	//$rules = [ "<RequireAll>", "    Require all granted" ];
	foreach ( $base_deny_ips as $ip ) {
		if ( preg_match( '/^[0-9\.\/]+$/', $ip ) ) {
			// ★追加：自分のIPがリストに含まれていたらスキップ（セルフロック防止）
			if ( ! empty( $my_ip ) && haup_ip_in_range( $my_ip, $ip ) ) {
				continue; 
			}
			$rules[] = "    Require not ip " . $ip;
		}
	}
	$rules[] = "</RequireAll>";

	// D. 書き込み実行
	if ( file_exists( $htaccess_file ) && is_writable( $htaccess_file ) ) {
		$existing_content = file_get_contents( $htaccess_file );
    
		// すでにHAUPのブロックがあるか確認
		if ( strpos( $existing_content, '# BEGIN HAUP_IP_BLOCK' ) === false ) {
			// まだブロックがない場合は、ファイルの「一番上」に空の枠を作成する
			$new_content = "# BEGIN HAUP_IP_BLOCK\n# END HAUP_IP_BLOCK\n\n" . $existing_content;
			file_put_contents( $htaccess_file, $new_content );
		}

		// あとは通常通り insert_with_markers を使う（既にある場所を更新してくれる）
		add_filter( 'insert_with_markers_inline_instructions', '__return_empty_array' );
		$success = insert_with_markers( $htaccess_file, 'HAUP_IP_BLOCK', $rules );
		remove_filter( 'insert_with_markers_inline_instructions', '__return_empty_array' );

		if ( $success ) {
			update_option( 'haup_ip_block_stats', [
				'last_sync' => current_time( 'mysql' ),
				'count'     => count( $base_deny_ips ),
				'ips' => $base_deny_ips,
				'details' => $details,
				'labels'    => $final_labels
			] );
		}
	}
}


/*** 指定したIPがCIDR範囲内にあるかチェックする補助関数 ***/
function haup_ip_in_range( $ip, $range ) {
	if ( strpos( $range, '/' ) === false ) {
		return $ip === $range;
	}
	list( $subdir, $bits ) = explode( '/', $range );
	$ip_addr = ip2long( $ip );
	$subnet  = ip2long( $subdir );
	$mask    = -1 << ( 32 - $bits );
	$subnet &= $mask;

	return ( $ip_addr & $mask ) == $subnet;
}

// 1. スケジュールの登録（1日1回）
if ( ! wp_next_scheduled( 'haup_sync_ip_block_event' ) ) {
	wp_schedule_event( time(), 'daily', 'haup_sync_ip_block_event' );
}
add_action( 'haup_sync_ip_block_event', 'haup_update_security_ip_block_htaccess' );


// 2. 設定保存時にも強制的に実行させる
add_action( 'update_option_haup_custom_blocked_ips', 'haup_update_security_ip_block_htaccess' );

/*** ダッシュボードウィジェットの登録 ***/
function haup_ip_block_htaccess_in_dashboard(){
	wp_add_dashboard_widget(
		'haup_ip_block_status_widget',
		__('HAUP IP Block Status Wdget','hima-art-utility'),
		'haup_ip_block_status_widget_callback'
	);
}
add_action('wp_dashboard_setup','haup_ip_block_htaccess_in_dashboard');

/*** ウィジェットの表示内容（手動更新ボタン付き）***/
function haup_ip_block_status_widget_callback() {
	// 国名スラグと表示名のマッピング（翻訳可能な形に）
	//$country_map = haup_ban_ip_widget_country_title();
	$stats = get_option('haup_ip_block_stats');
	// 保存されたラベルがあれば使い、なければフォールバック
	$country_map = $stats['labels'] ?? [];

	//文字列変数
	$widget_description_text = __('This widget displays the status of the "IP Address Blocking" function in the Hima Art Utility plugin.','hima-art-utility');
	$update_success_text = __('Synchronization has been performed.','hima-art-utility');

	echo '<p>'.esc_html( $widget_description_text ).'</p>';

	if ( isset($_POST['haup_manual_sync']) && check_admin_referer('haup_sync_action', 'haup_sync_nonce') ) {
		haup_update_security_ip_block_htaccess();
		echo '<div class="haup-ip-block-widget-updated"><p>'.esc_html( $update_success_text ).'</p></div>';
	}

	$stats = get_option('haup_ip_block_stats');

	//文字列変数
	$no_data_text = __('We have not yet received the data for the IP addresses to be blocked. Please click the button below to receive it.','hima-art-utility');
	$status_title_text = __('status:','hima-art-utility');
	$status_text = __('We are receiving data on IP addresses to be blocked periodically.','hima-art-utility');
	$moddate_title_text = __('Last updated:','hima-art-utility');
	$blocked_ips_text = __('Number of IP address ranges to be blocked:','hima-art-utility');
	$blocked_ips_list_title_text = __('Display the list of IP ranges currently being rejected.','hima-art-utility');
	$manual_update_text = __('Get the latest blocked IP list now','hima-art-utility');
	$update_description_text = __('* Obtain the latest IP blocklist from Hima Art Utility and rewrite the .htaccess file.','hima-art-utility');

	if ( ! $stats ) {
		echo '<p style="color: #d63638;">'.esc_html( $no_data_text ).'</p>';
	} else {
		echo '<div style="margin-bottom: 15px;">';
		echo '<p><strong>'.esc_html( $status_title_text ).'</strong> <span style="color: #46b450;">'.esc_html( $status_text ).'</span></p>';
		echo '<p><strong>'.esc_html( $moddate_title_text ).'</strong> ' . esc_html($stats['last_sync']) . '</p>';
		echo '<p><strong>'.esc_html( $blocked_ips_text ).'</strong> ' . esc_html($stats['count']) . '</p>';
		
		// ★ 国別の内訳表示を追加
		if ( ! empty( $stats['details'] ) ) {
			echo '<div style="margin: 10px15px;display: flex;flex-wrap: wrap;gap: 0.5rem 1rem;border: 1px solid #ddd;padding: 4px;border-radius: 2px;">';
    
			foreach ( $stats['details'] as $slug => $count ) {
				// common は表示しない
				if ( $slug === 'common' ) {
					 continue;
				}
				// マップにあればそれを使用、なければスラグを大文字にして表示
				//$display_label = isset( $country_map[$slug] ) ? $country_map[$slug] : ucfirst( $slug );
				$display_label = isset( $country_map[$slug] ) ? $country_map[$slug] : ucfirst( $slug );
        
				echo '<div style="display: flex; justify-content: space-between">';
				echo '<span style="font-weight: 600;">' . esc_html( $display_label ) . '</span>';
				echo '<span style="color: #666;">&nbsp;' . esc_html( $count ) . esc_html__( 'IP Ranges', 'hima-art-utility' ) . '</span>';
				echo '</div>';
			}
			echo '</div>';
		}

		echo '</div>';

		echo '<details class="accordion"  style="margin: 0.8rem 0;overflow: hidden;">';
			echo '<summary class="accordion__title" style="cursor: pointer;">'.esc_html( $blocked_ips_list_title_text ).'</summary>';
			echo '<div class="accordion__content" style="margin-top: 10px; max-height: 150px; overflow-y: auto; font-family: monospace; font-size: 12px; line-height: 1.5; background: #fff; padding: 5px; border: 1px solid #ddd;">';

			if ( ! empty($stats['ips']) ) {
				echo implode('<br>', array_map('esc_html', $stats['ips']));
			}

			echo '</div>';
		echo '</details>';
	}

	echo '<form method="post" action="">';
	wp_nonce_field('haup_sync_action', 'haup_sync_nonce');
	echo '<input type="submit" name="haup_manual_sync" class="haup-dashboard-widget-button" value="'.esc_html( $manual_update_text ).'">';
	echo '</form>';
    
	echo '<p style="margin-top: 15px; font-size: 11px; color: #666;">'.esc_html( $update_description_text ).'</p>';
}

