<?php
/**
 * SocialPromoter Installer
 *
 * Creates / upgrades database tables on activation and version change.
 *
 * @package PublisherKits_SocialPromoter
 */

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

/**
 * Class PKITS_SP_Installer
 */
class PKITS_SP_Installer {

	/**
	 * DB version option key.
	 *
	 * @var string
	 */
	const DB_VERSION_KEY = 'pkits_sp_db_version';

	/**
	 * Current DB schema version. Bump when tables change.
	 *
	 * @var string
	 */
	const DB_VERSION = '1.12.0';

	/**
	 * Run the installer on activation or upgrade.
	 *
	 * @return void
	 */
	public static function run() {
		self::create_tables();
		self::migrate_nullable_columns();
		// The Pro schema (campaigns, engagement stats, campaign links and their
		// migrations) ships only in the premium build, as its own class.
		if ( class_exists( 'PKITS_SP_Pro_Schema' ) ) {
			PKITS_SP_Pro_Schema::run();
		}
		update_option( self::DB_VERSION_KEY, self::DB_VERSION );
	}

	/**
	 * Relax the queue's post_id / scheduled_at columns to nullable on older
	 * installs. dbDelta never converts NOT NULL to nullable, so a site created
	 * from a pre-baseline schema where these were NOT NULL would reject the NULLs
	 * that house campaigns (no post) and drafts (no schedule) insert. Guarded by
	 * a one-time flag so the ALTER (which can rewrite the table) runs once, not on
	 * every activation; idempotent where the columns are already nullable.
	 *
	 * @return void
	 */
	private static function migrate_nullable_columns() {
		if ( get_option( 'pkits_sp_queue_nullable_fixed' ) ) {
			return;
		}
		global $wpdb;
		$queue = $wpdb->prefix . 'pkits_sp_queue';
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is trusted prefix + literal; MODIFY cannot use a placeholder.
		$wpdb->query( "ALTER TABLE `{$queue}` MODIFY post_id bigint(20) unsigned DEFAULT NULL, MODIFY scheduled_at datetime DEFAULT NULL" );
		update_option( 'pkits_sp_queue_nullable_fixed', 1, false );
	}

		/**
	 * Create or upgrade all plugin tables using dbDelta.
	 *
	 * @return void
	 */
	private static function create_tables() {
		global $wpdb;
		$charset = $wpdb->get_charset_collate();
		require_once ABSPATH . 'wp-admin/includes/upgrade.php';

		// ----------------------------------------------------------------
		// Queue table (updated: post_id nullable, campaign_id added)
		// ----------------------------------------------------------------
		$queue = $wpdb->prefix . 'pkits_sp_queue';
		dbDelta( "CREATE TABLE {$queue} (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			post_id bigint(20) unsigned DEFAULT NULL,
			campaign_id bigint(20) unsigned DEFAULT NULL,
			platform varchar(20) NOT NULL,
			account_id varchar(200) NOT NULL,
			copy_text text NOT NULL,
			image_url varchar(500) DEFAULT NULL,
			image_layout varchar(20) NOT NULL DEFAULT '',
			scheduled_at datetime DEFAULT NULL,
			status varchar(20) NOT NULL DEFAULT 'pending',
			platform_post_id varchar(300) DEFAULT NULL,
			error_message text DEFAULT NULL,
			created_at datetime NOT NULL,
			sent_at datetime DEFAULT NULL,
			PRIMARY KEY  (id),
			KEY post_id (post_id),
			KEY campaign_id (campaign_id),
			KEY status (status),
			KEY scheduled_at (scheduled_at)
		) {$charset};" );
		}

	/**
	 * Check whether a DB upgrade is needed and run it.
	 *
	 * @return void
	 */
	public static function maybe_upgrade() {
		$installed = get_option( self::DB_VERSION_KEY, '0' );
		if ( version_compare( $installed, self::DB_VERSION, '<' ) ) {
			self::run();
		}
	}
}
