<?php

namespace BwWinnersGlobalSite\Brand_Update;

if ( ! class_exists( __NAMESPACE__ . '\Update' ) ) {

	class Update {

		private $form_name = 'Brand Update Form';

		private $brand_id_field_name = 'brand id';

		private $gf_to_acf_map = array(
			array(
				'gf_field' => 'Brand Link',
				'acf_field' => 'brand_link',
				'type' => 'value'
			),
			array(
				'gf_field' => 'Distillery Website URL',
				'acf_field' => 'brand_link',
				'type' => 'value'
			),
			array(
				'gf_field' => 'Brand Description',
				'acf_field' => 'brand_description',
				'type' => 'value',
				'post_content' => true
			),
			array(
				'gf_field' => 'Video Link',
				'acf_field' => 'video_link',
				'type' => 'value'
			),
			array(
				'gf_field' => 'Brand Name',
				'acf_field' => 'brand_name',
				'post_title' => true,
				'type' => 'value'
			),
			array(
				'gf_field' => 'Brand Logo',
				'acf_field' => 'brand_logo',
				'type' => 'attachment'
			),
			array(
				'gf_field' => 'Brand Photo',
				'acf_field' => 'featured_image',
				'type' => 'attachment'
			),
			array(
				'gf_field' => 'Brand Website Link',
				'acf_field' => 'brand_link',
				'type' => 'value'
			),
			array(
				'gf_field' => 'Overview',
				'acf_field' => 'brand_description',
				'type' => 'value',
				'post_content' => true
			),
			array(
				'gf_field' => 'Facebook',
				'acf_field' => 'facebook',
				'type' => 'value',
			),
			array(
				'gf_field' => 'Instagram',
				'acf_field' => 'instagram',
				'type' => 'value',
			),
			array(
				'gf_field' => 'LinkedIn',
				'acf_field' => 'linkedin',
				'type' => 'value',
			),
			array(
				'gf_field' => 'Twitter/X',
				'acf_field' => 'twitter',
				'type' => 'value',
			),
		);

		public function __construct () {
			add_action('admin_menu', array( $this, 'register_admin_page' ) );
			add_action( 'admin_init', array( $this, 'update_brand_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 Brand',              // Page title
				'Update Brand',              // Menu title
				'manage_options',            // Capability required
				'bw_update_brand',           // 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__( 'Brand 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_brand_page () {

			if ( ! isset( $_GET['page'] ) || $_GET['page'] !== 'bw_update_brand' ) {
				return;
			};

			if ( ! current_user_can('edit_others_posts ') ) {
				new Brand_Update_Error_Notice( 'You do not have sufficient permissions to access page.' );
				return;
			};

			if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'bw_update_brand' ) ) {
				new Brand_Update_Error_Notice( 'The link has expired. Please try again.' );
				return;
			};

			if ( ! isset( $_GET['entry'] ) ) {
				new Brand_Update_Error_Notice( 'Missing entry.' );
				return;
			};

			$entry_id = intval( $_GET['entry'] );

			if ( ! \GFAPI::entry_exists( $entry_id ) ) {
				new Brand_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 Brand_Update_Error_Notice( 'Form not found.' );
				return;
			};

			$form = \GFAPI::get_form( $form_id );

			if ( $form['title'] !== $this->form_name ) {
				new Brand_Update_Error_Notice( 'Entry is not for the form "{$this->form_name}".' );
				return;
			};

			$field_id = self::get_field_by_label( $form, $this->brand_id_field_name );

			if ( $field_id == false ) return;

			$brand_id = intval( $entry[ $field_id ] );
			if ( get_post_type( $brand_id ) !== 'brand' ) {
				new Brand_Update_Error_Notice( 'Brand not found.' );
				return;
			};

			$this->update_brand( $entry, $form );

			wp_redirect( get_edit_post_link( $brand_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_brands'] = 'Update Brands';
			}

			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->brand_id_field_name );

				if ( $field_id == false ) return;

				$brand_id = intval( $entry[ $field_id ] );

				if ( ! $brand_id ) return;

				printf( '| <a href="%s">View Brand</a> ', get_permalink( $brand_id ) );
				printf( '| <a href="%s">Update Brand</a> ', wp_nonce_url( get_admin_url( null, "admin.php?page=bw_update_brand&entry={$entry['id']}" ), 'bw_update_brand' ) );
			}

		}

		public function do_entry_list_bulk_actions ( $action, $entries, $form_id ) {

			$form = \GFAPI::get_form( $form_id );

			$this->update_brands( $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'] === 'brand id' ) {
						$brand_id = $entry[$field['id']];

						global $bw_winners_global_site;


						switch ( $label ) {
							case 'Brand':
								$brand = $bw_winners_global_site->entities->get_brand( $brand_id );
								$value = $brand['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_brand'] = array(
				'title' => esc_html__( 'Brand Update', 'gravityforms' ),
				'callback' => array( $this, 'meta_box_brand_update' ),
	            'context' => 'side',
	            'callback_args' => array( $entry, $form )
			);
			return $meta_boxes;
		}

		public function meta_box_brand_update ( $args ) {

		    $form  = $args['form'];
		    $entry = $args['entry'];

			$url = wp_nonce_url( get_admin_url( null, "admin.php?page=bw_update_brand&entry={$entry['id']}" ), 'bw_update_brand' );
			?>
				<div>
					<a class="button" href="<?php echo $url; ?>">Update Brand</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_brands( $entries, $form ) {
			foreach( $entries as $entry_id ) {
				$entry = \GFAPI::get_entry( $entry_id );
				$this->update_brand( $entry, $form );
			}
		}

		private function update_brand( $entry, $form ) {

			if ( is_wp_error( $entry ) || is_wp_error( $form ) ) return;

			$field_id = self::get_field_by_label( $form, $this->brand_id_field_name );

			if ( $field_id == false ) {
				new Brand_Update_Error_Notice( 'Missing brand id field.' );
				return;
			};

			\GFAPI::add_note(
				$entry['id'],
				get_current_user_id(),
				wp_get_current_user(),
				date("F j, Y - g:i a") . ': Brand Updated.',
				'bw-winners'
			); 

			$brand_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 ],
								$brand_id
							);
							if ( ! empty( $mapping['post_content'] ) ) {
								wp_update_post( array(
									'ID' => $brand_id,
									'post_content' => $entry[ $field_id ]
								) );
							}
							if ( ! empty( $mapping['post_title'] ) ) {
								wp_update_post( array(
									'ID' => $brand_id,
									'post_title' => $entry[ $field_id ]
								) );
							}
						};
						break;
					case 'attachment':
						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 Brand_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( $brand_id, 'post_name' ) . '_' . $mapping['acf_field']
							);

							// Copy the image file to the uploads directory
							if (!copy($image_path, $destination_path)) {
								new Brand_Update_Error_Notice( 'Failed to copy the image.' );
								break;
							}

							global $wpdb;

							$brand = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}bw_winners_brands WHERE id = %d", $brand_id ) );

							$brand_name = $brand ? $brand->name : get_the_title( $brand_id );

							$attachment_data = array(
								'guid'           => $upload_url . '/' . basename($destination_path),
								'post_mime_type' => $filetype['type'],
								'post_title'     => sanitize_text_field( $brand_name . ' ' . $mapping['gf_field'] ),
								'post_content'   => '',
								'post_status'    => 'inherit'
							);

							$attach_id = wp_insert_attachment( $attachment_data, $destination_path, $brand_id );

							if ( is_wp_error( $attach_id ) ) {
								new Brand_Update_Error_Notice( 'Error adding attachment to brand.' );
							}
							
							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( $brand_id, $attach_id );
							}

							if ( 'featured_image' === $mapping['acf_field'] ) {
								set_post_thumbnail( $brand_id, $attach_id );
							} else {
								update_field( $mapping['acf_field'], $attach_id, $brand_id );
							}

						}
						break;
					default:
						break;
				}
			}

		}


	}
}

if ( ! class_exists( __NAMESPACE__ . '\Brand_Update_Error_Notice' ) ) {

	/**
	 * Manages brand update error notices.
	 */
	class Brand_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__( 'Brand Update Error', 'bw-winners-global-site' ); ?></p>
					<pre><?php echo esc_html__( $this->error ); ?></pre>
				</div>
			<?php
		}
	}
}
