<?php // phpcs:ignore Standard.Category.SniffName.ErrorCode

namespace WPDataAccess\CSV_Files {

	use WPDataAccess\Data_Dictionary\WPDA_List_Columns_Cache;
	use WPDataAccess\List_Table\WPDA_List_Table;
	use WPDataAccess\Plugin_Table_Models\WPDA_CSV_Uploads_Model;
	use WPDataAccess\Utilities\WPDA_Message_Box;
	use WPDataAccess\WPDA;

	/**
	 * List table showing upload CSV files
	 */
	class WPDA_CSV_List_Table extends WPDA_List_Table {

		/**
		 * Constructor
		 *
		 * @param array $args Constructor arguments.
		 */
		public function __construct( $args = array() ) {
			$args['column_headers']  = self::column_headers_labels();
			$args['title']           = '';
			$args['subtitle']        = '';
			$args['show_view_link']  = 'off';
			$args['allow_insert']    = 'off';
			$args['allow_update']    = 'off';
			$args['allow_delete']    = 'on';
			$args['allow_import']    = 'off';
			$args['show_page_title'] = false;

			global $wpdb;

			$args['wpdaschema_name'] = $wpdb->dbname;
			$args['table_name']      = WPDA_CSV_Uploads_Model::get_base_table_name();

			parent::__construct( $args );

			// Reset columns (we are in a sub page of the Data Explorer main page).
			$this->wpda_list_columns = WPDA_List_Columns_Cache::get_list_columns(
				$wpdb->dbname,
				WPDA_CSV_Uploads_Model::get_base_table_name()
			);
			foreach ( $this->wpda_list_columns->get_table_columns() as $table_columns ) {
				$this->columns_indexed[ $table_columns['column_name'] ] = $table_columns;
			}
		}

		/**
		 * Show list table
		 *
		 * @return void
		 */
		public function show() {
			parent::show();

			?>
			<script type="text/javascript">
				jQuery(function() {
					jQuery('#wpda_main_form').append('<input type="hidden" name="page_action" value="wpda_import_csv">');
				});
			</script>
			<?php
		}

		/**
		 * Add mapping action link
		 *
		 * @param mixed  $item Table columns.
		 * @param string $column_name Column name.
		 * @param string $actions Action.
		 * @return void
		 */
		protected function column_default_add_action( $item, $column_name, &$actions ) {
			// Add page_action to delete form.
			?>
			<script type='text/javascript'>
				jQuery("#delete_form_" + <?php echo esc_attr( self::$list_number - 1 ); ?>).attr('action', '?page=<?php echo esc_attr( $this->page ); ?>&page_action=wpda_import_csv');
			</script>
			<?php
			// Add mapping form to actions.
			$wp_nonce_action = "wpda-mapping-{$item['csv_id']}";
			$wp_nonce        = esc_attr( wp_create_nonce( $wp_nonce_action ) );
			$form_id         = '_' . ( self::$list_number - 1 );
			$mapping_form    = $this->create_post_form( 'mapping', "mapping_form{$form_id}", $item['csv_id'], $wp_nonce );
			?>
			<script type='text/javascript'>
				jQuery("#wpda_invisible_container").append("<?php echo $mapping_form; // phpcs:ignore WordPress.Security.EscapeOutput ?>");
			</script>
			<?php
			$mapping =
				sprintf(
					'<a href="javascript:void(0)" class="view wpda_tooltip" title="' .
						__( 'Map table and columns for CSV file: ', 'wp-data-access' ) . $item['csv_real_file_name'] .
						'

Needs to be performed only once" onclick="jQuery(\'#mapping_form%s\').submit()">%s</a>',
					$form_id,
					'Mapping'
				);

			// Add import form to actions.
			$wp_nonce_action = "wpda-import-csv-{$item['csv_id']}";
			$wp_nonce        = esc_attr( wp_create_nonce( $wp_nonce_action ) );
			$import_form     = $this->create_post_form( 'import_start', "import_form{$form_id}", $item['csv_id'], $wp_nonce, $item['csv_name'] );
			?>
			<script type='text/javascript'>
				jQuery("#wpda_invisible_container").append("<?php echo $import_form; // phpcs:ignore WordPress.Security.EscapeOutput ?>");
			</script>
			<?php
			$import =
				sprintf(
					'<a href="javascript:void(0)" class="view wpda_tooltip" title="' .
						__( 'Import CSV file: ', 'wp-data-access' ) . $item['csv_real_file_name'] .
						'" onclick="jQuery(\'#import_form%s\').submit()">%s</a>',
					$form_id,
					'Import'
				);

			// Add reload form to actions.
			$wp_nonce_action = "wpda-reload-csv-{$item['csv_id']}";
			$wp_nonce        = esc_attr( wp_create_nonce( $wp_nonce_action ) );
			$reload_form     = $this->create_post_form( 'reload', "reload_form{$form_id}", $item['csv_id'], $wp_nonce, $item['csv_name'], $item['csv_encoding'] );
			?>
			<script type='text/javascript'>
				jQuery("#wpda_invisible_container").append("<?php echo $reload_form; // phpcs:ignore WordPress.Security.EscapeOutput ?>");
			</script>
			<?php
			$reload =
				sprintf(
					'<a href="javascript:void(0)" class="view wpda_tooltip" title="' .
						__( 'Upload a newer version of CSV file: ', 'wp-data-access' ) . $item['csv_real_file_name'] .
						'" onclick="jQuery(\'#reload_form%s\').submit()">%s</a>',
					$form_id,
					'Upload'
				);

			// Remove edit action.
			unset( $actions['edit'] );

			// Add new links to beginning of action list.
			//phpcs:ignore - 8.1 proof
			$actions =
				array_merge(
					array( 'mapping' => $mapping ),
					array( 'import' => $import ),
					array( 'reload' => $reload ),
					$actions
				);
		}

		/**
		 * Create post form
		 *
		 * @param string $action Action.
		 * @param string $form_id Form ID.
		 * @param string $csv_id CSV ID.
		 * @param string $wpnonce Nonce.
		 * @param string $csv_name CSV internal name.
		 * @return array|string|string[]
		 */
		private function create_post_form( $action, $form_id, $csv_id, $wpnonce, $csv_name = '', $csv_encoding = '' ) {
			$esc_attr = 'esc_attr';

            $csv_encoding_field = '';
            if ( ! empty( $csv_encoding ) ) {
                $csv_encoding_field = "<input type='hidden' name='csv_encoding' value='{$esc_attr( $csv_encoding )}' />";
            }

			$form     = <<< EOT
				<form id='{$esc_attr( $form_id )}' method='post'
					  action='?page={$esc_attr( $this->page )}&page_action=wpda_import_csv'
				>
					<input type='hidden' name='action' value='{$esc_attr( $action )}' />
					<input type='hidden' name='csv_id' value='{$esc_attr( $csv_id )}' />
					<input type='hidden' name='csv_name' value='{$esc_attr( $csv_name )}' />
					{$csv_encoding_field}
					<input type='hidden' name='_wpnonce' value='{$esc_attr( $wpnonce )}'>
				</form>
EOT;
			return str_replace( array( "\n", "\r" ), '', $form );
		}

		/**
		 * Get current bulk action
		 *
		 * @return array|mixed|string
		 */
		public function get_bulk_actions() {
			$actions = parent::get_bulk_actions();

			if ( is_array( $actions ) ) {
				unset( $actions['bulk-export'] );
				unset( $actions['bulk-export-xml'] );
				unset( $actions['bulk-export-json'] );
				unset( $actions['bulk-export-excel'] );
				unset( $actions['bulk-export-csv'] );
			}

			return $actions;
		}

		/**
		 * Process bulk action
		 *
		 * @return void
		 */
		public function process_bulk_action() {
			if ( 'delete' === $this->current_action() ) {
				// Check if key is available.
				if ( ! isset( $_REQUEST['csv_id'] ) ) { // input var okay.
					wp_die( __( 'ERROR: Invalid URL [missing primary key values]', 'wp-data-access' ) ); // phpcs:ignore WordPress.Security.EscapeOutput
				}
				$csv_id = sanitize_text_field( wp_unslash( $_REQUEST['csv_id'] ) ); // input var okay.

				// Check if delete is allowed.
				$wp_nonce_action = "wpda-delete-{$this->table_name}-{$csv_id}";
				$wp_nonce        = isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : ''; // input var okay.
				if ( ! wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
					wp_die( __( 'ERROR: Not authorized', 'wp-data-access' ) ); // phpcs:ignore WordPress.Security.EscapeOutput
				}

				// Delete CSV file and data.
				$row = WPDA_CSV_Uploads_Model::query( $csv_id );
				if ( is_array( $row ) && 1 === count( $row ) ) {//phpcs:ignore - 8.1 proof
					// Silently delete file.
					if ( isset( $row[0]->csv_real_file_name ) ) {
						unlink( WPDA::get_plugin_upload_dir() . $row[0]->csv_real_file_name );
					}

					// Delete record.
					$next_row_to_be_deleted['csv_id'] = $csv_id;
					if ( $this->delete_row( $next_row_to_be_deleted ) ) {
						$msg = new WPDA_Message_Box(
							array(
								'message_text' => __( 'Row deleted', 'wp-data-access' ),
							)
						);
						$msg->box();
					} else {
						$msg = new WPDA_Message_Box(
							array(
								'message_text'           => __( 'Could not delete row', 'wp-data-access' ),
								'message_type'           => 'error',
								'message_is_dismissible' => false,
							)
						);
						$msg->box();
					}
				}
			} elseif ( 'bulk-delete' === $this->current_action() ) {
				if ( ! isset( $_REQUEST['bulk-selected'] ) ) { // input var okay.
					$msg = new WPDA_Message_Box(
						array(
							'message_text' => __( 'Nothing to delete', 'wp-data-access' ),
						)
					);
					$msg->box();

					return;
				}

				// Check if delete is allowed.
				$wp_nonce_action = "wpda-delete-{$this->table_name}";
				$wp_nonce        = isset( $_REQUEST['_wpnonce2'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce2'] ) ) : ''; // input var okay.
				if ( ! wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
					die( __( 'ERROR: Not authorized', 'wp-data-access' ) ); // phpcs:ignore WordPress.Security.EscapeOutput
				}

				$bulk_rows = $_REQUEST['bulk-selected']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
				//phpcs:ignore - 8.1 proof
				$no_rows   = count(  ( array ) $bulk_rows ); // # rows to be deleted.

				$rows_to_be_deleted = array(); // Gonna hold rows to be deleted.
				for ( $i = 0; $i < $no_rows; $i ++ ) {
					// Write "json" to named array. Need to strip slashes twice. Once for the normal conversion
					// and once extra for the pre-conversion of double quotes in method column_cb().
					$row_object = json_decode( stripslashes( stripslashes( $bulk_rows[ $i ] ) ), true );

					// Check if key is available.
					if ( ! isset( $row_object['csv_id'] ) ) {
						wp_die( __( 'ERROR: Invalid URL [missing primary key values]', 'wp-data-access' ) ); // phpcs:ignore WordPress.Security.EscapeOutput
					}

					// Save key.
					$rows_to_be_deleted[ $i ] = $row_object['csv_id'];
				}

				// Looks like everything is there. Delete records from table...
				$rows_successfully_deleted = 0; // Number of rows successfully deleted.
				$rows_with_errors         = 0; // Number of rows that could not be deleted.
				for ( $i = 0; $i < $no_rows; $i ++ ) {
					// Delete CSV file and data.
					$row = WPDA_CSV_Uploads_Model::query( $rows_to_be_deleted[ $i ] );
					if ( is_array( $row ) && 1 === count( $row ) ) {//phpcs:ignore - 8.1 proof
						// Silently delete file.
						if ( isset( $row[0]->csv_real_file_name ) ) {
							unlink( WPDA::get_plugin_upload_dir() . $row[0]->csv_real_file_name );
						}

						// Delete record.
						$next_row_to_be_deleted['csv_id'] = $rows_to_be_deleted[ $i ];
						if ( $this->delete_row( $next_row_to_be_deleted ) ) {
							$rows_successfully_deleted++;
						} else {
							$rows_with_errors++;
						}
					}
				}

				// Inform user about the results of the operation.
				$message = '';

				if ( 1 === $rows_successfully_deleted ) {
					$message = __( 'CSV files deleted', 'wp-data-access' );
				} elseif ( $rows_successfully_deleted > 1 ) {
					$message = "$rows_successfully_deleted " . __( 'CSV files deleted', 'wp-data-access' );
				}

				if ( '' !== $message ) {
					$msg = new WPDA_Message_Box(
						array(
							'message_text' => $message,
						)
					);
					$msg->box();
				}

				$message = '';

				if ( $rows_with_errors > 0 ) {
					$message = __( 'Not all CSV files have been deleted', 'wp-data-access' );
				}

				if ( '' !== $message ) {
					$msg = new WPDA_Message_Box(
						array(
							'message_text'           => $message,
							'message_type'           => 'error',
							'message_is_dismissible' => false,
						)
					);
					$msg->box();
				}
			} else {
				parent::process_bulk_action();
			}
		}

		/**
		 * Get column labels
		 *
		 * @return array
		 */
		public static function column_headers_labels() {
			return array(
				'csv_id'             => __( 'ID', 'wp-data-access' ),
				'csv_name'           => __( 'Import Name', 'wp-data-access' ),
				'csv_real_file_name' => __( 'Local file Name', 'wp-data-access' ),
				'csv_orig_file_name' => __( 'File Name', 'wp-data-access' ),
				'csv_timestamp'      => __( 'Timestamp', 'wp-data-access' ),
				'csv_mapping'        => __( 'Mapping', 'wp-data-access' ),
                'csv_encoding'       => __( 'Encoding', 'wp-data-access' ),
			);
		}

	}

}
