<?php

namespace QodeBadgesForWooCommerce\Database;

if ( ! defined( 'ABSPATH' ) ) {
	// Exit if accessed directly.
	exit;
}
class Qode_Product_Badge_Relation_Table_Setup implements Qode_Badges_Database_Table_Setup {

	private static $instance;

	private $table_name;
	private $version;
	private $version_option_name;
	private $stored_version;

	/**
	 * Returns current instance of class
	 *
	 * @return Qode_Product_Badge_Relation_Table_Setup
	 */
	public static function get_instance() {
		if ( null == self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * TaxonomyRelationsTableSetup constructor.
	 */
	public function __construct() {
		global $wpdb;

		$this->table_name          = $wpdb->prefix . 'qode_product_badge_relations';
		$this->version             = '1';
		$this->version_option_name = 'qode_badges_for_woocommerce_product_badge_relations_version';
		$this->stored_version      = get_option( $this->version_option_name );

		add_action( 'save_post_product', array( $this, 'refresh_table_on_product_update' ), 10, 3 );
		add_action( 'trashed_post', array( $this, 'delete_related_data' ) );

		do_action( 'qode_badges_for_woocommerce_action_product_badge_relation_table_setup', $this );
	}

	public function setup() {
		global $wpdb;

		$charset_collate = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE IF NOT EXISTS $this->table_name (
				id bigint(20) NOT NULL AUTO_INCREMENT,
				product_id bigint(20) NOT NULL,
				badge_id bigint(20) NOT NULL,
				rule_id bigint(20) NOT NULL,
				start_date date,
				end_date date,
				user_roles varchar(255) NOT NULL DEFAULT '',
				user_ids varchar(2500) NOT NULL DEFAULT '',
				group_id bigint(20) NOT NULL,
				UNIQUE KEY id (id)
			) $charset_collate;";

		if ( ! function_exists( 'dbDelta' ) ) {
			require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		}

		dbDelta( $sql );

		add_option( $this->version_option_name, $this->version );
	}

	public function get_version() {
		return $this->version;
	}

	public function get_stored_version() {
		return $this->stored_version;
	}

	public function set_stored_version( $version ) {
		if ( empty( $version ) ) {
			return false;
		}

		return update_option( $this->version_option_name, $version );
	}

	public function has_new_version() {
		return ! empty( $this->stored_version ) && ( $this->stored_version !== $this->version );
	}

	public function upgrade() {
		// here comes upgrade SQL code
		// it should be in the same format as sql in setup method
		// if you need to drop column you must use $wp_query as dbDelta function can't remove columns
		// before you write upgrade code upgrade table version in constructor.
	}

	// ACTION FUNCTIONS - START.

	public function refresh_table_on_product_update( $product_id ) {
		$nonce = 'qode_badges_for_woocommerce_framework_meta_box_badges-product_save';

		if ( ! isset( $_POST['_inline_edit'] ) && ! isset( $_POST[ $nonce ] ) ) {
			return;
		} elseif ( isset( $_POST['_inline_edit'] ) ) {
			if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_inline_edit'] ) ), 'inlineeditnonce' ) ) {
				return;
			}
		} elseif ( isset( $_POST[ $nonce ] ) ) {
			if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $nonce ] ) ), $nonce ) ) {
				return;
			}
		}

		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

		if ( ! current_user_can( 'edit_post', $product_id ) ) {
			return;
		}

		if ( isset( $_POST ) && isset( $_POST['action'] ) && ( 'editpost' === $_POST['action'] || 'inline-save' === $_POST['action'] ) ) {
			$post_params = $_POST;

			qode_badges_for_woocommerce_badge_regenerate_product_in_database( $product_id, $post_params );

			do_action( 'qode_badges_for_woocommerce_action_after_save_product' );
		}
	}

	public function delete_related_data( $post_ID ) {
		$post_type = get_post_type( $post_ID );
		if ( 'product' === $post_type ) {
			$this->delete_from_database_by_field( $post_ID, 'product_id' );
		} elseif ( 'qbfw_badge' === $post_type ) {
			$this->delete_from_database_by_field( $post_ID, 'badge_id' );
		}
	}

	// ACTION FUNCTIONS - END.

	// DB TABLE ACTIONS - START.

	public function delete_from_database_by_field( $product_id, $field_name ) {
		global $wpdb;

		$table      = esc_sql( $this->table_name );
		$field_name = esc_sql( $field_name );

		if ( ! empty( $product_id ) ) {
			$wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE %i = %d', $table, $field_name, $product_id ) );// phpcs:ignore WordPress.DB.DirectDatabaseQuery
		}
	}

	public function insert_into_database( $rows ) {
		global $wpdb;
		$table = esc_sql( $this->table_name );

		/* INSERT NEW RELATIONS */
		if ( is_array( $rows ) && count( $rows ) ) {
			foreach ( $rows as $values ) {
				$wpdb->query(// phpcs:ignore WordPress.DB.DirectDatabaseQuery
					$wpdb->prepare(
						'INSERT INTO %i (product_id, badge_id, rule_id, start_date, end_date, user_roles, user_ids, group_id) 
	             VALUES (%d, %d, %d, %s, %s, %s, %s, %d)',
						$table,
						$values['product_id'],
						$values['badge_id'],
						$values['rule_id'],
						$values['start_date'],
						$values['end_date'],
						$values['user_roles'],
						$values['user_ids'],
						$values['group_id']
					)
				);
			}
		}
	}

	public function get_badge_from_product_id( $product_id = '' ) {
		$result = array();

		if ( ! empty( $product_id ) ) {
			global $wpdb;

			$table = esc_sql( $this->table_name );
			$date  = wp_date( 'Y-m-d' );

			$result_new = $wpdb->get_results(// phpcs:ignore WordPress.DB.DirectDatabaseQuery
				$wpdb->prepare(
					"SELECT badge_id, user_roles, user_ids, group_id FROM %i 
				     WHERE product_id = %d AND ((start_date <= %s AND end_date >= %s) OR start_date = '0000-00-00')
				     ORDER BY group_id DESC, id ASC",
					$table,
					$product_id,
					$date,
					$date
				),
				ARRAY_N
			);

			if ( is_array( $result_new ) && count( $result_new ) ) {
				$result = $result_new;
			}
		}

		return $result;
	}
	// DB TABLE ACTIONS - END.
}
