<?php
/**
 * Installer
 *
 * Handles plugin activation, deactivation, and DB migrations.
 *
 * @package Relatedly\Core
 * @since   2.0.0
 */

namespace Relatedly\Core;

defined( 'ABSPATH' ) || exit;

/**
 * Handles activation, deactivation, and database schema upgrades.
 *
 * @since 2.0.0
 */
class Installer {

	/** Increment this constant whenever the DB table structure changes. */
	const TABLE_SCHEMA_VERSION = '2.0';

	// -------------------------------------------------------------------------
	// Lifecycle hooks
	// -------------------------------------------------------------------------

	/** Called by register_activation_hook(). */
	public static function activate(): void {
		$stored = get_option( 'relatedly_version', '0.0.0' );

		// Set defaults only on very first activation.
		if ( '0.0.0' === $stored ) {
			$options = new Options();
			add_option( Options::OPTION_KEY, $options->defaults() );
			add_option( 'relatedly_activated_time', time() );
		}

		self::create_tracking_table();
		update_option( 'relatedly_version', RELATEDLY_VERSION );
		flush_rewrite_rules();
	}

	/** Called by register_deactivation_hook(). */
	public static function deactivate(): void {
		( new Cache() )->flush();
		flush_rewrite_rules();
	}

	/**
	 * Run DB migrations on every request when version or schema is outdated.
	 * Called from Plugin::init() before any services are wired.
	 */
	public static function maybe_upgrade(): void {
		$stored_version = get_option( 'relatedly_version', '0.0.0' );
		$schema_version = get_option( 'relatedly_table_schema_version', '0' );

		$version_ok = version_compare( $stored_version, RELATEDLY_VERSION, '>=' );
		$schema_ok  = ( self::TABLE_SCHEMA_VERSION === $schema_version );

		if ( $version_ok && $schema_ok ) {
			return;
		}

		self::create_tracking_table();

		if ( ! $version_ok ) {
			update_option( 'relatedly_version', RELATEDLY_VERSION );
		}
	}

	// -------------------------------------------------------------------------
	// DB table
	// -------------------------------------------------------------------------

	/**
	 * Create or upgrade the click-tracking table via dbDelta.
	 * Safe to call multiple times — uses CREATE TABLE IF NOT EXISTS.
	 */
	public static function create_tracking_table(): void {
		global $wpdb;

		$table          = $wpdb->prefix . 'relatedly_clicks';
		$schema_version = get_option( 'relatedly_table_schema_version', '0' );

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$exists = $wpdb->get_var(
			$wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table ) )
		) === $table;

		if ( $exists && self::TABLE_SCHEMA_VERSION === $schema_version ) {
			return;
		}

		$collate = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE IF NOT EXISTS {$table} (
			id               bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			source_post_id   bigint(20) UNSIGNED NOT NULL,
			clicked_post_id  bigint(20) UNSIGNED NOT NULL,
			display_type     varchar(20) NOT NULL DEFAULT 'inline',
			event_type       varchar(20) NOT NULL DEFAULT 'click',
			event_date       datetime DEFAULT CURRENT_TIMESTAMP,
			ip_address       varchar(45) DEFAULT NULL,
			user_agent       text DEFAULT NULL,
			PRIMARY KEY  (id),
			KEY source_post_id (source_post_id),
			KEY clicked_post_id (clicked_post_id),
			KEY display_type (display_type),
			KEY event_type (event_type),
			KEY event_date (event_date),
			KEY idx_date_type (event_date, event_type),
			KEY idx_date_display_type (event_date, display_type, event_type),
			KEY idx_date_clicked (event_date, clicked_post_id, event_type),
			KEY idx_date_source (event_date, source_post_id, event_type)
		) {$collate};";

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		dbDelta( $sql );

		update_option( 'relatedly_table_schema_version', self::TABLE_SCHEMA_VERSION );
	}
}
