<?php
/**
 * Abstract database class to handle common table management tasks.
 *
 * @package Awesomemotive\Rewardswp\Abstracts
 * @since 1.0.0
 */

namespace Awesomemotive\Rewardswp\Abstracts;

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

use Awesomemotive\Rewardswp\Database\SchemaManager;

/**
 * Class AbstractMigration
 *
 * Provides a common structure for database tables.
 *
 * @since 1.0.0
 */
abstract class AbstractDatabaseTable extends SchemaManager {
	/**
	 * Must return the table name.
	 *
	 * @since 1.0.0
	 * @return string Table name.
	 */
	abstract public function get_table_name(): string;

	/**
	 * Migrations must return the pairs of keys and values, where
	 * the key is the column name in the database and the value is the label to be
	 * used in the frontend.
	 *
	 * @since 1.0.0
	 * @return array
	 */
	abstract public function get_columns(): array;

	/**
	 * Migrations must have a method to create the tables.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	abstract public function create_or_update_table(): void;

	/**
	 * Migrations that wish to create a metadata table should override this method
	 * returning the table name for it.
	 *
	 * @since 1.0.0
	 *
	 * @return string The name of the table used for metadata.
	 */
	public function get_meta_table_name(): string {
		return '';
	}

	/**
	 * Migrations that wish to create a metadata table should override this method
	 * returning the relationship column name for it.
	 *
	 * @since 1.0.0
	 *
	 * @return string The name of the column used to create the relationship with the main table.
	 */
	public function get_meta_table_relationship_field_name(): string {
		return '';
	}

	/**
	 * Creates a metadata table like postmeta or termmeta for custom tables.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function create_meta_table(): void {
		$table_name = static::get_prefixed_meta_table_name();
		$rel_field  = static::get_meta_table_relationship_field_name();

		if ( empty( $table_name ) || empty( $rel_field ) ) {
			return;
		}

		$sql = sprintf(
			'CREATE TABLE %s (
            meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            %s bigint(20) unsigned NOT NULL,
            meta_key varchar(255) DEFAULT NULL,
            meta_value longtext,
            PRIMARY KEY (meta_id),
            KEY %s (%s),
            KEY meta_key (meta_key(191))
        ) %s;',
			$table_name,
			$rel_field,
			$rel_field,
			$rel_field,
			$this->global_config->get_db()->get_charset_collate()
		);

		$this->db_delta( $sql );
	}

	/**
	 * Returns the table name with WordPress table prefix.
	 *
	 * @since 1.0.0
	 * @return string Prefixed table name.
	 */
	public function get_prefixed_table_name(): string {
		return $this->global_config->get_db()->prefix . static::get_table_name();
	}

	/**
	 * Returns the meta table name with WordPress table prefix.
	 *
	 * @since 1.0.0
	 * @return string Prefixed table name.
	 */
	public function get_prefixed_meta_table_name(): string {
		$table_name = static::get_meta_table_name();

		if ( empty( $table_name ) ) {
			return '';
		}

		return $this->global_config->get_db()->prefix . $table_name;
	}
}
