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

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


/**
 * プラグイン有効化時の処理
 *
 * 全テーブルの作成とDBバージョン管理を行う。
 * テーブル定義は docs/DATABASE.md に準拠。
 *
 * @since 1.0.0
 */
class Activator {

	/**
	 * 有効化処理
	 */
	public static function activate(): void {
		self::create_tables();
		self::ensure_encryption_key();
		self::create_pages();
		update_option( 'conf_manager_db_version', CONF_MANAGER_DB_VERSION );
		Capabilities::register_roles();
		flush_rewrite_rules();
	}

	/**
	 * 暗号化キーが存在しない場合、自動生成して wp_options に保存
	 */
	private static function ensure_encryption_key(): void {
		// wp-config.php に定義済みなら何もしない
		if ( defined( 'CONF_MANAGER_ENCRYPTION_KEY' ) && strlen( CONF_MANAGER_ENCRYPTION_KEY ) >= 16 ) {
			return;
		}

		// wp_options に既にあれば何もしない
		$existing = get_option( 'conf_manager_encryption_key', '' );
		if ( ! empty( $existing ) && strlen( $existing ) >= 16 ) {
			return;
		}

		// 自動生成（64文字の16進数 = 256bit）
		$key = bin2hex( random_bytes( 32 ) );
		update_option( 'conf_manager_encryption_key', $key, false );
	}

	/**
	 * 固定ページを自動作成（既存チェック付き）
	 *
	 * プラグイン有効化時に必要な固定ページを作成する。
	 * 同じスラッグの公開済みページが既に存在する場合はスキップ。
	 */
	private static function create_pages(): void {
		$pages = [
			[
				'slug'    => 'c-registration',
				'title'   => __( 'Registration', 'conferencemanager' ),
				'content' => '[conf_manager]',
			],
			[
				'slug'    => 'c-mypage',
				'title'   => __( 'My Page', 'conferencemanager' ),
				'content' => '[conf_manager view="mypage"]',
			],
			[
				'slug'    => 'c-terms',
				'title'   => __( 'Terms of Service', 'conferencemanager' ),
				'content' => self::get_terms_content(),
			],
		];

		foreach ( $pages as $page ) {
			// 同じスラッグの公開済みページが存在するかチェック
			$existing = get_posts( [
				'name'        => $page['slug'],
				'post_type'   => 'page',
				'post_status' => [ 'publish', 'draft', 'private' ],
				'numberposts' => 1,
			] );

			if ( ! empty( $existing ) ) {
				continue;
			}

			wp_insert_post( [
				'post_type'    => 'page',
				'post_title'   => $page['title'],
				'post_name'    => $page['slug'],
				'post_content' => $page['content'],
				'post_status'  => 'publish',
			] );
		}
	}

	/**
	 * 利用規約ページのデフォルトコンテンツを返す
	 */
	private static function get_terms_content(): string {
		// $site_name はテンプレート内で esc_html() を適用するため、ここでは生値を渡す。
		$site_name = get_bloginfo( 'name' );

		ob_start();
		include CONF_MANAGER_PLUGIN_DIR . 'templates/default-terms-content.php';
		return (string) ob_get_clean();
	}

	/**
	 * DBバージョンチェックとアップグレード
	 */
	public static function maybe_upgrade(): void {
		$current = get_option( 'conf_manager_db_version', '0' );
		if ( version_compare( $current, CONF_MANAGER_DB_VERSION, '<' ) ) {
			self::create_tables();

			// v3.0.0 でスケジュール通知機能を廃止したため、旧 Cron スケジュールをクリア。
			if ( version_compare( $current, '3.0.0', '<' ) ) {
				wp_clear_scheduled_hook( 'conf_manager_payment_reminder' );
				wp_clear_scheduled_hook( 'conf_manager_notification_send' );
			}

			update_option( 'conf_manager_db_version', CONF_MANAGER_DB_VERSION );
		}

		// ロール・ケイパビリティの更新（cap追加時に再登録）
		$roles_ver = get_option( 'conf_manager_roles_version', '0' );
		if ( version_compare( $roles_ver, '2', '<' ) ) {
			Capabilities::register_roles();
			update_option( 'conf_manager_roles_version', '2' );
		}
	}

	/**
	 * 全テーブルを作成（dbDelta で差分適用）
	 */
	private static function create_tables(): void {
		global $wpdb;
		$charset_collate = $wpdb->get_charset_collate();
		$prefix          = $wpdb->prefix . 'conf_';

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';

		// 1. members（会員マスタ）
		dbDelta( "CREATE TABLE {$prefix}members (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			wp_user_id bigint(20) unsigned DEFAULT NULL,
			member_no varchar(30) DEFAULT NULL,
			member_type varchar(20) NOT NULL DEFAULT 'regular',
			is_member tinyint(1) NOT NULL DEFAULT 1,
			name_sei varchar(100) NOT NULL,
			name_mei varchar(100) NOT NULL,
			name_sei_kana varchar(100) DEFAULT NULL,
			name_mei_kana varchar(100) DEFAULT NULL,
			email varchar(500) NOT NULL,
			email_hash varchar(64) NOT NULL,
			phone varchar(500) DEFAULT NULL,
			org_name varchar(200) DEFAULT NULL,
			org_dept varchar(200) DEFAULT NULL,
			org_address varchar(500) DEFAULT NULL,
			passkey_credential_ids text DEFAULT NULL,
			email_verified tinyint(1) NOT NULL DEFAULT 0,
			registered_via varchar(20) NOT NULL DEFAULT 'admin',
			approval_status varchar(20) NOT NULL DEFAULT 'auto_approved',
			email_opt_out tinyint(1) NOT NULL DEFAULT 0,
			email_opt_out_at datetime DEFAULT NULL,
			status varchar(20) NOT NULL DEFAULT 'active',
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			UNIQUE KEY email_hash (email_hash),
			UNIQUE KEY member_no (member_no),
			KEY wp_user_id (wp_user_id),
			KEY member_type (member_type),
			KEY is_member (is_member),
			KEY status (status)
		) $charset_collate;" );

		// 2. events（イベントマスタ）
		dbDelta( "CREATE TABLE {$prefix}events (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			title varchar(300) NOT NULL,
			description longtext DEFAULT NULL,
			date_start datetime NOT NULL,
			date_end datetime NOT NULL,
			venue varchar(300) DEFAULT NULL,
			venue_address varchar(500) DEFAULT NULL,
			capacity int unsigned DEFAULT NULL,
			reg_start datetime DEFAULT NULL,
			reg_end datetime DEFAULT NULL,
			fee_rules_json longtext DEFAULT NULL,
			advance_fee_deadline datetime DEFAULT NULL,
			fee_rules_day_json longtext DEFAULT NULL,
			advance_fee_notice text DEFAULT NULL,
			tax_rate decimal(4,1) NOT NULL DEFAULT 10.0,
			submission_start datetime DEFAULT NULL,
			submission_end datetime DEFAULT NULL,
			submission_settings_json longtext DEFAULT NULL,
			payment_account_name varchar(200) DEFAULT NULL,
			payment_account_info text DEFAULT NULL,
			organizer_info text DEFAULT NULL,
			status varchar(20) NOT NULL DEFAULT 'draft',
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			KEY status (status),
			KEY date_start (date_start),
			KEY reg_start (reg_start),
			KEY reg_end (reg_end)
		) $charset_collate;" );

		// 3. sessions（セッション）
		dbDelta( "CREATE TABLE {$prefix}sessions (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			event_id bigint(20) unsigned NOT NULL,
			title varchar(300) NOT NULL,
			session_type varchar(30) NOT NULL DEFAULT 'main',
			date_start datetime NOT NULL,
			date_end datetime NOT NULL,
			capacity int unsigned DEFAULT NULL,
			fee decimal(10,0) NOT NULL DEFAULT 0,
			sort_order int NOT NULL DEFAULT 0,
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			KEY event_id (event_id),
			KEY session_type (session_type),
			KEY event_id_sort (event_id, sort_order)
		) $charset_collate;" );

		// 4. registrations（参加申込）
		dbDelta( "CREATE TABLE {$prefix}registrations (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			registration_no varchar(30) NOT NULL,
			event_id bigint(20) unsigned NOT NULL,
			member_id bigint(20) unsigned NOT NULL,
			group_id varchar(30) DEFAULT NULL,
			is_representative tinyint(1) NOT NULL DEFAULT 0,
			participation_type varchar(20) NOT NULL DEFAULT 'onsite',
			payment_method varchar(20) NOT NULL DEFAULT 'bank',
			transfer_note varchar(255) DEFAULT NULL,
			session_options_json longtext DEFAULT NULL,
			amount decimal(10,0) NOT NULL DEFAULT 0,
			tax decimal(10,0) NOT NULL DEFAULT 0,
			fee_type varchar(50) DEFAULT NULL,
			fee_type_label varchar(100) DEFAULT NULL,
			discount_code varchar(50) DEFAULT NULL,
			status varchar(20) NOT NULL DEFAULT 'pending',
			registered_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			paid_at datetime DEFAULT NULL,
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			UNIQUE KEY registration_no (registration_no),
			KEY event_id (event_id),
			KEY member_id (member_id),
			KEY group_id (group_id),
			KEY status (status),
			KEY payment_method (payment_method),
			KEY event_id_status (event_id, status),
			KEY member_id_status (member_id, status)
		) $charset_collate;" );

		// 5. group_members（団体スタッフ）
		dbDelta( "CREATE TABLE {$prefix}group_members (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			registration_id bigint(20) unsigned NOT NULL,
			member_id bigint(20) unsigned DEFAULT NULL,
			name varchar(200) NOT NULL,
			email varchar(500) NOT NULL,
			email_hash varchar(64) DEFAULT NULL,
			fee_type varchar(30) DEFAULT NULL,
			participation_type varchar(20) NOT NULL DEFAULT 'onsite',
			session_options_json longtext DEFAULT NULL,
			status varchar(20) NOT NULL DEFAULT 'active',
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			KEY registration_id (registration_id),
			KEY member_id (member_id),
			KEY email_hash (email_hash)
		) $charset_collate;" );

		// 6. payments（決済記録）
		dbDelta( "CREATE TABLE {$prefix}payments (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			registration_id bigint(20) unsigned NOT NULL,
			method varchar(20) NOT NULL,
			amount decimal(10,0) NOT NULL,
			tax decimal(10,0) NOT NULL DEFAULT 0,
			fee decimal(10,0) NOT NULL DEFAULT 0,
			gateway_txn_id varchar(200) DEFAULT NULL,
			bank_transfer_name varchar(200) DEFAULT NULL,
			bank_transfer_date date DEFAULT NULL,
			is_group_payment tinyint(1) NOT NULL DEFAULT 0,
			status varchar(20) NOT NULL DEFAULT 'pending',
			refund_amount decimal(10,0) DEFAULT NULL,
			refund_reason text DEFAULT NULL,
			paid_at datetime DEFAULT NULL,
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			KEY registration_id (registration_id),
			KEY method (method),
			KEY status (status),
			KEY gateway_txn_id (gateway_txn_id),
			KEY paid_at (paid_at),
			KEY registration_id_status (registration_id, status)
		) $charset_collate;" );

		// 7. invoices（請求書）
		dbDelta( "CREATE TABLE {$prefix}invoices (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			payment_id bigint(20) unsigned NOT NULL,
			invoice_no varchar(30) NOT NULL,
			addressee_name varchar(200) NOT NULL,
			addressee_dept varchar(200) DEFAULT NULL,
			honorific varchar(10) NOT NULL DEFAULT '御中',
			tax_registration_no varchar(30) DEFAULT NULL,
			pdf_path varchar(500) NOT NULL,
			issued_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			UNIQUE KEY invoice_no (invoice_no),
			KEY payment_id (payment_id)
		) $charset_collate;" );

		// 8. receipts（領収書）
		dbDelta( "CREATE TABLE {$prefix}receipts (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			payment_id bigint(20) unsigned NOT NULL,
			receipt_no varchar(30) NOT NULL,
			addressee_name varchar(200) NOT NULL,
			addressee_dept varchar(200) DEFAULT NULL,
			proviso varchar(200) NOT NULL DEFAULT '参加費として',
			tax_registration_no varchar(50) DEFAULT NULL,
			pdf_path varchar(500) NOT NULL,
			issued_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			UNIQUE KEY receipt_no (receipt_no),
			KEY payment_id (payment_id)
		) $charset_collate;" );


		// 16. security_keys（暗号化キー）
		dbDelta( "CREATE TABLE {$prefix}security_keys (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			key_hash varchar(64) NOT NULL,
			purpose varchar(30) NOT NULL,
			encrypted_key text NOT NULL,
			active_from datetime NOT NULL,
			active_to datetime DEFAULT NULL,
			rotated_at datetime DEFAULT NULL,
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			KEY key_hash (key_hash),
			KEY purpose (purpose),
			KEY active_from (active_from)
		) $charset_collate;" );

		// 17. audit_log（監査ログ）
		dbDelta( "CREATE TABLE {$prefix}audit_log (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			user_id bigint(20) unsigned DEFAULT NULL,
			action varchar(50) NOT NULL,
			target_type varchar(50) DEFAULT NULL,
			target_id bigint(20) unsigned DEFAULT NULL,
			detail_json longtext DEFAULT NULL,
			ip_address varchar(45) DEFAULT NULL,
			user_agent varchar(500) DEFAULT NULL,
			created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			KEY user_id (user_id),
			KEY action (action),
			KEY target_type (target_type),
			KEY created_at (created_at)
		) $charset_collate;" );

	}
}
