<?php
// @codingStandardsIgnoreFile

/** Database
 *
 * @package BwWinnersGlobalSite
 */

namespace BwWinnersGlobalSite;

if ( ! class_exists( __NAMESPACE__ . '\Database' ) ) {
	/**
	 * Manages the database.
	 */
	class Database {

		private const COMPETITION_TABLE_NAME = 'bw_winners_v2_competitions';
		private const BRAND_TABLE_NAME = 'bw_winners_v2_brands';
		private const PRODUCT_TABLE_NAME = 'bw_winners_v2_products';
		private const ENTRY_TABLE_NAME = 'bw_winners_v2_entries';
		private const BRAND_AWARD_TABLE_NAME = 'bw_winners_v2_brand_awards';
		private const PRODUCT_AWARD_TABLE_NAME = 'bw_winners_v2_product_awards';
		private const BRAND_POSTS_NAME = 'bw_winners_v2_brand_posts';
		/**
		 * Add auto update logic to hooks. For BwWinnersGlobalSite.
		 * If the plugin will have auto updates enabled use init hook.
		 */
		public function __construct() {
			add_action( 'admin_init', array( $this, 'update' ) );
			add_action( 'rest_api_init', array( $this, 'update' ) );
		}

		/**
		 * Drops the plugins tables on all sites.
		 */
		public static function drop_tables_all_sites() {
			if ( ! is_network_admin() || ! function_exists( 'get_sites' ) ) {
				self::drop_tables();
				return;
			}

			$sites = get_sites();

			foreach ( $sites as $site ) {
				switch_to_blog( $site->blog_id );
				self::drop_tables();
				restore_current_blog();
			}
		}

		/**
		 * Drops the plugins tables. Make sure to keep this up to date.
		 */
		public static function drop_tables() {
			Options::update_option( 'database_version', '0.0.0' );

			global $wpdb;

			$tables = array(
				$wpdb->prefix . self::BRAND_POSTS_NAME,
				$wpdb->prefix . self::PRODUCT_AWARD_TABLE_NAME,
				$wpdb->prefix . self::BRAND_AWARD_TABLE_NAME,
				$wpdb->prefix . self::ENTRY_TABLE_NAME,
				$wpdb->prefix . self::PRODUCT_TABLE_NAME,
				$wpdb->prefix . self::BRAND_TABLE_NAME,
				$wpdb->prefix . self::COMPETITION_TABLE_NAME
			);

			foreach ( $tables as $table ) {	
				$sql = "DROP TABLE IF EXISTS {$table}";
				$wpdb->query( $sql );

				if ( $wpdb->last_error ) {
					error_log( sprintf( 'BwWinnersGlobalSite Plugin MySql Error: %s', $wpdb->last_error ) );
				}
			}
		}

		/**
		 * Check for and apply any database updates.
		 */
		public function update() {
			$current_version = Options::get_option( 'database_version' );

			if ( ! is_string( $current_version ) ) {
				$current_version = '0.0.0';
			}

			foreach ( $this->get_updates( $current_version ) as $update ) {
				if ( ! $this->apply_update( $update ) ) {
					break;
				}
				Options::update_option( 'database_version', $update['version'] );
			}
		}

		/**
		 * Applies a database update.
		 *
		 * @param array $update    Update version and file.
		 *
		 * @return boolean True iff the update was successful.
		 */
		private function apply_update( $update ) {
			$error = include plugin_dir_path( PLUGIN_PATH ) . 'includes/database/updates/' . $update['file'];

			if ( $error ) {
				new Database_Update_Error_Notice( $error );
				return false;
			}

			return true;
		}

		/**
		 * Gets a list of
		 *
		 * @param string $current_version The current version of the db.
		 *
		 * @return array List of required updates.
		 */
		private function get_updates( $current_version ) {
			return array_filter(
				array(
					array(
						'version' => '1.0.0',
						'file'    => '10000.php',
					),
				),
				function ( $val ) use ( $current_version ) {
					return version_compare( $val['version'], $current_version, 'gt' );
				}
			);
		}
	}
}


if ( ! class_exists( __NAMESPACE__ . '\Database_Update_Error_Notice' ) ) {
	/**
	 * Manages database update error notices.
	 */
	class Database_Update_Error_Notice {
		/**
		 * Sql error message.
		 *
		 * @var string
		 */
		private $error;

		/**
		 * Adds hook.
		 *
		 * @param string $error Sql error message.
		 */
		public function __construct( $error ) {
			$this->error = $error;

			add_action( 'admin_notices', array( $this, 'render' ), 10, 0 );
		}

		/**
		 * WordPress dashboard error notice template
		 */
		public function render() {
			?>
				<div class="notice notice-error is-dismissible">
					<p><?php esc_html__( 'Database Update Error', 'bw-winners-global-site' ); ?></p>
					<pre><?php echo esc_html( $this->error ); ?></pre>
				</div>
			<?php
		}
	}
}
