<?php

namespace BwWinner;

class Product_Update {

	private $form_name = 'Product Update Form';

	private $product_id_field_name = 'product id';

	private $gf_to_acf_map = array(
		array(
			'gf_field' => 'Brand Link',
			'acf_field' => 'brand_link',
			'type' => 'value'
		),
		array(
			'gf_field' => 'Product Link',
			'acf_field' => 'product_link',
			'type' => 'value'
		),
		array(
			'gf_field' => 'Purchase Link',
			'acf_field' => 'purchase_link',
			'type' => 'value'
		),
		array(
			'gf_field' => 'Product Image',
			'acf_field' => 'product_image',
			'type' => 'attachment',
			'post_thumbnail' => true
		),
		array(
			'gf_field' => 'Brand Logo',
			'acf_field' => 'brand_logo',
			'type' => 'attachment'
		),
		array(
			'gf_field' => 'Tasting Notes',
			'acf_field' => 'tasting_notes',
			'type' => 'value',
			'post_content' => true
		),
		array(
			'gf_field' => 'Product Description',
			'acf_field' => 'product_description',
			'type' => 'value',
			'post_content' => true
		),
		array(
			'gf_field' => 'Retail Price',
			'acf_field' => 'retail_price',
			'type' => 'value'
		),
		array(
			'gf_field' => 'Video Link',
			'acf_field' => 'video_link',
			'type' => 'value'
		),
		array(
			'gf_field' => 'Alcohol by volume',
			'acf_field' => 'alcohol_by_volume',
			'type' => 'value'
		)
	);

	public function __construct () {
		add_action('admin_menu', array( $this, 'register_admin_page' ) );
		add_action( 'admin_init', array( $this, 'update_product_page' ) );
		add_filter( 'query_vars', array( $this, 'query_vars' ) );

		add_filter( 'gform_entry_list_bulk_actions', array( $this, 'add_entry_list_bulk_actions' ), 10, 2  );
		add_action( 'gform_entries_first_column_actions', array( $this, 'add_entry_actions' ), 10, 5 );
		add_action( 'gform_entry_list_action', array( $this, 'do_entry_list_bulk_actions' ), 10, 3 );

		add_filter( 'gform_entries_column_filter', array( $this, 'entries_column' ), 10, 5 );
		add_filter( 'gform_entry_detail_meta_boxes', array( $this, 'entry_detail_meta_boxes' ), 10, 3 );
	}

	public function register_admin_page () {
		// Add a submenu page without showing it in the menu
		add_submenu_page(
			null,                         // No parent menu (hidden)
			'Update Product',             // Page title
			'Update Product',             // Menu title
			'manage_options',             // Capability required
			'bw_update_product',          // Menu slug
			array( $this, 'dashboard' )   // Callback function
		);
	}

	public function dashboard () {
		require_once(ABSPATH . 'wp-admin/includes/dashboard.php');
		// Load the dashboard header
		echo '<div class="wrap">';
		echo '<h1>' . \esc_html__( 'Product Update Failed!' ) . '</h1>';

		// Display the dashboard content
		\wp_dashboard_setup(); // Set up the dashboard widgets

		// Render dashboard widgets
		\do_meta_boxes('dashboard', 'normal', '');
		\do_meta_boxes('dashboard', 'side', '');

		echo '</div>';
	}

	public function update_product_page () {

		if ( ! isset( $_GET['page'] ) || $_GET['page'] !== 'bw_update_product' ) {
			return;
		};

		if ( ! current_user_can('edit_others_posts ') ) {
			new Product_Update_Error_Notice( 'You do not have sufficient permissions to access page.' );
			return;
		};

		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'bw_update_product' ) ) {
			new Product_Update_Error_Notice( 'The link has expired. Please try again.' );
			return;
		};

		if ( ! isset( $_GET['entry'] ) ) {
			new Product_Update_Error_Notice( 'Missing entry.' );
			return;
		};

		$entry_id = intval( $_GET['entry'] );

		if ( ! \GFAPI::entry_exists( $entry_id ) ) {
			new Product_Update_Error_Notice( 'Entry not found.' );
			return;
		};

		$entry = \GFAPI::get_entry( $entry_id );

		$form_id = intval( $entry['form_id'] );

		if ( ! \GFAPI::form_id_exists( $form_id ) ) {
			new Product_Update_Error_Notice( 'Form not found.' );
			return;
		};

		$form = \GFAPI::get_form( $form_id );

		if ( $form['title'] !== $this->form_name ) {
			new Product_Update_Error_Notice( 'Entry is not for the form "{$this->form_name}".' );
			return;
		};

		$field_id = self::get_field_by_label( $form, $this->product_id_field_name );

		if ( $field_id == false ) return;

		$product_id = intval( $entry[ $field_id ] );

		if ( get_post_type( $product_id ) !== 'bw-product' ) {
			new Product_Update_Error_Notice( 'Product not found.' );
			return;
		};

		$this->update_product( $entry, $form );

		wp_redirect( get_edit_post_link( $product_id, 'edit' ) );

		exit;
	}

	public function query_vars ( $query_vars ) {
		$query_vars[] = 'entry';
		return $query_vars;
	}

	public function add_entry_list_bulk_actions ( $actions, $form_id ) {

		$form = \GFAPI::get_form( $form_id );

		if ( $form['title'] === $this->form_name ) {
			$actions['update_products'] = 'Update Products';
		}

		return $actions;
	}

	public function add_entry_actions ( $form_id, $field_id, $value, $entry, $query_string ) {
		if ( \GFAPI::form_id_exists( $form_id ) ) {
			$form = \GFAPI::get_form( $form_id );

			if ( $form['title'] !== $this->form_name ) return;

			$field_id = self::get_field_by_label( $form, $this->product_id_field_name );

			if ( $field_id == false ) return;

			$product_id = intval( $entry[ $field_id ] );

			if ( ! $product_id ) return;

			printf( '| <a href="%s">View Product</a> ', get_permalink( $product_id ) );
			printf( '| <a href="%s">Update Product</a> ', wp_nonce_url( get_admin_url( null, "admin.php?page=bw_update_product&entry={$entry['id']}" ), 'bw_update_product' ) );
		}

	}

	public function do_entry_list_bulk_actions ( $action, $entries, $form_id ) {

		$form = \GFAPI::get_form( $form_id );

		$this->update_products( $entries, $form );
	}

	public function entries_column ( $value, $form_id, $field_id, $entry, $query_string ) {

		if ( empty( $value ) ) {
			$form = \GFAPI::get_form( $form_id );

			if ( $form['title'] !== $this->form_name ) {
				return $value;
			};

			$field = \GFAPI::get_field( $form, $field_id );
			$label = $field->label;

			foreach ( $form['fields'] as $field ) {
				if ( ! isset( $field['label'] ) || ! isset( $field['id'] ) ) {
					continue;
				}
				if ( $field['label'] === 'product id' ) {
					$product_id = $entry[$field['id']];

					global $bw_winners;


					switch ( $label ) {
						case 'Product':
							$product = $bw_winners->entities->get_product( $product_id );
							$value = $product['name'];
							break;
						case 'Brand':
							$product = $bw_winners->entities->get_product( $product_id );
							$brand = $bw_winners->entities->get_brand( $product['brand_id'] );
							$value = $brand['name'];
							break;
						
						case 'Company':
							$product = $bw_winners->entities->get_product( $product_id );
							$brand = $bw_winners->entities->get_brand( $product['brand_id'] );
							$company = $bw_winners->entities->get_company( $brand['company_id'] );
							$value = $company['name'];
							break;
						
						default:
							// code...
							break;
					}

					break;
				}
			}
		}

		return $value;
	}

	public function entry_detail_meta_boxes ( $meta_boxes, $entry, $form ) {
		if ( $form['title'] !== $this->form_name ) {
			return $meta_boxes;
		};
		$meta_boxes['bw_winners_product'] = array(
			'title' => esc_html__( 'Product Update', 'gravityforms' ),
			'callback' => array( $this, 'meta_box_product_update' ),
            'context' => 'side',
            'callback_args' => array( $entry, $form )
		);
		return $meta_boxes;
	}

	public function meta_box_product_update ( $args ) {

	    $form  = $args['form'];
	    $entry = $args['entry'];

		$url = wp_nonce_url( get_admin_url( null, "admin.php?page=bw_update_product&entry={$entry['id']}" ), 'bw_update_product' );
		?>
			<div>
				<a class="button" href="<?php echo $url; ?>">Update Product</a>
			</div>
		<?php
	}

	private static function get_field_by_label( $form, $label ) {
		foreach ( $form['fields'] as $field ) {
			if ( $field->label == $label ) {
				return $field->id;
			}
		}
		return false;
	}

	private function update_products( $entries, $form ) {
		foreach( $entries as $entry_id ) {
			$entry = \GFAPI::get_entry( $entry_id );
			$this->update_product( $entry, $form );
		}
	}

	private function update_product( $entry, $form ) {

		if ( is_wp_error( $entry ) || is_wp_error( $form ) ) return;

		$field_id = self::get_field_by_label( $form, $this->product_id_field_name );

		if ( $field_id == false ) {
			new Product_Update_Error_Notice( 'Missing product id field.' );
			return;
		};

		\GFAPI::add_note(
			$entry['id'],
			get_current_user_id(),
			wp_get_current_user(),
			date("F j, Y - g:i a") . ': Product Updated.',
			'bw-winners'
		); 

		$product_id = intval( $entry[ $field_id ] );

		foreach( $this->gf_to_acf_map as $mapping ) {
			switch ($mapping['type']) {
				case 'value':
					// Map field from gf to acf by value.
					if ( false !== $field_id = self::get_field_by_label( $form, $mapping['gf_field'] ) ) {
						update_field(
							$mapping['acf_field'],
							$entry[ $field_id ],
							$product_id
						);
						if ( ! empty( $mapping['post_content'] ) ) {
							wp_update_post( array(
								'ID' => $product_id,
								'post_content' => $entry[ $field_id ]
							) );
						}
					};
					break;
				default:
					if ( false !== $field_id = self::get_field_by_label( $form, $mapping['gf_field'] ) ) {

						$image_url = $entry[ $field_id ];

						if ( empty( $image_url ) ) break;

						$upload_dir = wp_upload_dir();
						$upload_path = $upload_dir['path'];
						$upload_url = $upload_dir['url'];

						$relative_path = str_replace($upload_dir['baseurl'], '', $image_url);
						$image_path = $upload_dir['basedir'] . $relative_path;

						if (!file_exists($image_path)) {
							new Product_Update_Error_Notice( 'The specified file does not exist.' );
							break;
						}


						$filetype = wp_check_filetype( basename( $image_path ), null );

						$destination_path = $upload_path . '/' . wp_unique_filename(
							$upload_path,
							get_post_field( $product_id, 'post_name' ) . '_' . $mapping['acf_field']
						);

						// Copy the image file to the uploads directory
						if (!copy($image_path, $destination_path)) {
							new Product_Update_Error_Notice( 'Failed to copy the image.' );
							break;
						}

						global $wpdb;

						$product = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}bw_winners_products WHERE id = %d", $product_id ) );

						$product_name = $product ? $product->name : get_the_title( $product_id );

						$attachment_data = array(
							'guid'           => $upload_url . '/' . basename($destination_path),
							'post_mime_type' => $filetype['type'],
							'post_title'     => sanitize_text_field( $product_name . ' ' . $mapping['gf_field'] ),
							'post_content'   => '',
							'post_status'    => 'inherit'
						);

						$attach_id = wp_insert_attachment( $attachment_data, $destination_path, $product_id );

						if ( is_wp_error( $attach_id ) ) {
							new Product_Update_Error_Notice( 'Error adding attachment to product.' );
						}
						
						require_once(\ABSPATH . 'wp-admin/includes/image.php');
						$attach_data = wp_generate_attachment_metadata( $attach_id, $destination_path );
						wp_update_attachment_metadata( $attach_id, $attach_data );

						if ( ! empty( $mapping['post_thumbnail'] ) ) {
							set_post_thumbnail( $product_id, $attach_id );
						}

						update_field( $mapping['acf_field'], $attach_id, $product_id );

					}
					break;
			}
		}

	}


}

/**
 * Manages product update error notices.
 */
class Product_Update_Error_Notice {
	/**
	 * @var string Sql error message.
	 */
	private $error;

	/**
	 * @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__( 'Product Update Error', 'bw-winner' ); ?></p>
				<pre><?php echo esc_html__( $this->error ); ?></pre>
			</div>
		<?php
	}
}
