<?php
/**
 * One-time migration from the legacy standalone plugins.
 *
 * Runs on plugin activation. If `bw_dev_settings` does not yet exist (or has
 * no module data), reads the legacy options from the five source plugins and
 * writes them into the unified `bw_dev_settings` schema.
 *
 * Legacy options are NOT deleted — the user manually deactivates each source
 * plugin once they've verified the corresponding module is doing the job.
 * The source plugins' own uninstall hooks clean up their options when they
 * are deleted.
 *
 * Idempotent: re-running activation never clobbers existing bw-dev data.
 *
 * @package BW_Dev
 */

defined( 'ABSPATH' ) || exit;

class BW_Dev_Migration {

	const VERSION_OPTION = 'bw_dev_migration_version';
	const CURRENT_VERSION = 1;

	/**
	 * Activation hook entry point. Wired via register_activation_hook in the
	 * main plugin file. Runs once on first activation, and is idempotent so
	 * subsequent reactivations are safe — the table install + cron schedule
	 * checks always execute (cheap; the helpers self-skip when up to date).
	 */
	public static function on_activation(): void {
		$ran = (int) get_option( self::VERSION_OPTION, 0 );
		if ( $ran < self::CURRENT_VERSION ) {
			self::migrate_legacy_options();
			update_option( self::VERSION_OPTION, self::CURRENT_VERSION );
		}

		// Login Activity Log infrastructure — table + daily prune cron. Both
		// helpers are idempotent (option-version check + wp_next_scheduled
		// check), so calling on every activation is safe.
		if ( class_exists( 'BW_Dev_Module_Login_Log' ) ) {
			BW_Dev_Module_Login_Log::install_table();
			BW_Dev_Module_Login_Log::schedule_cron();
		}
	}

	/**
	 * Build a bw_dev_settings payload from any legacy options found on the
	 * site. Modules that have no legacy data are simply absent from the
	 * payload (so is_module_enabled() returns the default-true for them).
	 *
	 * The merge is conservative: only fills in keys that are NOT already
	 * populated in bw_dev_settings, so a partial migration plus a manual
	 * setting tweak survives a re-activation.
	 */
	public static function migrate_legacy_options(): void {
		$existing = (array) get_option( BW_Dev_Settings::OPTION, array() );

		// Favicon: bw_favicon_url (string).
		$legacy_favicon_url = get_option( 'bw_favicon_url', null );
		if ( null !== $legacy_favicon_url && ! isset( $existing['favicon'] ) ) {
			$existing['favicon'] = array( 'url' => (string) $legacy_favicon_url );
		}

		// Sticky: bw_sticky_settings (array with 'elements' key).
		$legacy_sticky = get_option( 'bw_sticky_settings', null );
		if ( is_array( $legacy_sticky ) && ! isset( $existing['sticky'] ) ) {
			$elements = isset( $legacy_sticky['elements'] ) && is_array( $legacy_sticky['elements'] )
				? array_values( $legacy_sticky['elements'] )
				: array();
			$existing['sticky'] = array( 'elements' => $elements );
		}

		// YouTube: bw_youtube_embed_settings (['acf_field' => string]).
		$legacy_youtube = get_option( 'bw_youtube_embed_settings', null );
		if ( is_array( $legacy_youtube ) && ! isset( $existing['youtube'] ) ) {
			$existing['youtube'] = array(
				'acf_field' => isset( $legacy_youtube['acf_field'] ) ? (string) $legacy_youtube['acf_field'] : 'youtube_link',
			);
		}

		// Admin Columns: bw_admin_column_settings (keyed by post type).
		$legacy_ac = get_option( 'bw_admin_column_settings', null );
		if ( is_array( $legacy_ac ) && ! isset( $existing['admin_columns'] ) ) {
			$existing['admin_columns'] = $legacy_ac;
		}

		// Admin Note: bw_admin_note_settings (['post_types' => [...]]).
		// The _bw_admin_note post-meta key is preserved — no data migration
		// needed for the individual notes; only the per-post-type enable map
		// moves to the new schema.
		$legacy_an = get_option( 'bw_admin_note_settings', null );
		if ( is_array( $legacy_an ) && ! isset( $existing['admin_note'] ) ) {
			$existing['admin_note'] = array(
				'post_types' => isset( $legacy_an['post_types'] ) && is_array( $legacy_an['post_types'] )
					? array_values( $legacy_an['post_types'] )
					: array( 'page' ),
			);
		}

		// Established Year: standalone `established-year` plugin's `bw_established_date`
		// (a YYYY-MM-DD string) → bw_dev_settings.established_year.date.
		$legacy_est = get_option( 'bw_established_date', null );
		if ( is_string( $legacy_est ) && '' !== trim( $legacy_est ) && ! isset( $existing['established_year'] ) ) {
			$existing['established_year'] = array( 'date' => trim( $legacy_est ) );
		}

		update_option( BW_Dev_Settings::OPTION, $existing );
	}

	/**
	 * Map of source plugin basename → bw-dev module slug it replaces.
	 * Used by the diagnostics view (and ad-hoc by adi when deactivating
	 * legacy plugins) to confirm the new module is enabled before the
	 * old one is turned off.
	 */
	public static function legacy_map(): array {
		return array(
			'bw-favicon/bw-favicon.php'                   => 'favicon',
			'bw-sticky-settings/bw-sticky-settings.php'   => 'sticky',
			'bw-youtube-embed/bw-youtube-embed.php'       => 'youtube',
			'bw-pretty-post-link/bw-pretty-post-link.php' => 'post_link',
			'bw-admin-column/bw-admin-column.php'         => 'admin_columns',
			'bw-admin-note/bw-admin-note.php'             => 'admin_note',
		);
	}
}
