<?php
/**
 * Database management for custom tables.
 *
 * @package Carticy\CheckoutShield\Core
 */

declare(strict_types=1);

namespace Carticy\CheckoutShield\Core;

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

/**
 * Handles database table creation and management.
 */
final class Database {

	/**
	 * Database version option key.
	 */
	private const DB_VERSION_KEY = 'carticy_checkout_shield_db_version';

	/**
	 * Current database version.
	 */
	private const DB_VERSION = '1.0.0';

	/**
	 * Get the blocklist table name.
	 *
	 * @return string
	 */
	public static function get_blocklist_table(): string {
		global $wpdb;
		return $wpdb->prefix . 'carticy_ccs_blocklist';
	}

	/**
	 * Check if database needs upgrade and run it.
	 */
	public static function maybe_upgrade(): void {
		$installed_version = get_option( self::DB_VERSION_KEY, '0' );

		if ( version_compare( $installed_version, self::DB_VERSION, '<' ) ) {
			self::create_tables();
			update_option( self::DB_VERSION_KEY, self::DB_VERSION );
		}
	}

	/**
	 * Create database tables.
	 */
	public static function create_tables(): void {
		global $wpdb;

		$table_name      = self::get_blocklist_table();
		$charset_collate = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE {$table_name} (
			id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
			type VARCHAR(20) NOT NULL,
			value VARCHAR(255) NOT NULL,
			value_secondary VARCHAR(255) DEFAULT NULL,
			reason TEXT DEFAULT NULL,
			source_order_id BIGINT UNSIGNED DEFAULT NULL,
			created_by BIGINT UNSIGNED DEFAULT NULL,
			created_at DATETIME NOT NULL,
			PRIMARY KEY (id),
			INDEX idx_type_value (type, value(100)),
			INDEX idx_type (type),
			INDEX idx_source_order (source_order_id)
		) {$charset_collate};";

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

	/**
	 * Drop database tables (for uninstall).
	 */
	public static function drop_tables(): void {
		global $wpdb;

		$table_name = self::get_blocklist_table();

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is safe internal constant.
		$wpdb->query( "DROP TABLE IF EXISTS {$table_name}" );

		delete_option( self::DB_VERSION_KEY );
	}
}
