<?php
/**
 * ProductReports
 *
 * @package CommonFrameworkPlugin
 */

// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

namespace CommonFrameworkPlugin;

use CommonFrameworkPlugin\CPTGenerator;
use WP_Query;

/**
 * Creates the CommonFrameworkPlugin post type and shortcodes to output them.
 */
class ProductReports extends \CommonFrameworkPlugin\Module {
	/**
	 * Only register if on an admin page and if fieldmanager plugin is active.
	 *
	 * @return bool
	 */
	public function can_register() {
		return false;
	}

	/**
	 * Register our hooks.
	 *
	 * @return void
	 */
	public function register() {
		// add_action( 'admin_post_not_vertiv_products_report', array( $this, 'not_vertiv_products_report' ) );
		// add_action( 'admin_post_vertiv_products_report', array( $this, 'vertiv_products_report' ) );
		// add_action( 'admin_post_all_products_report', array( $this, 'all_products_report' ) );
		// add_action( 'admin_post_focus_keyword_products_report', array( $this, 'focus_keyword_products_report' ) );
		// add_action( 'admin_post_child_products_report', array( $this, 'child_products_report' ) );
		// add_action( 'admin_post_updated_products_two_weeks_report', array( $this, 'updated_products_two_weeks_report' ) );
		// add_action( 'admin_post_new_products_last_month_report', array( $this, 'new_products_last_month_report' ) );
		// add_action( 'admin_post_matching_child_products_report', array( $this, 'matching_child_products_report' ) );
		// add_action( 'admin_post_all_unsynced_products_report', array( $this, 'all_unsynced_products_report' ) );
	}

	/**
	 * Outputs an array of data as a CSV file to the browser.
	 *
	 * This function accepts an array of data, where each nested array represents a line in the CSV file.
	 * It writes each line to the output stream, which is typically used to generate downloadable CSV files
	 * directly from a browser request. The function halts script execution after outputting the CSV to ensure
	 * no additional output corrupts the file format.
	 *
	 * @param array $new_csv An array of arrays, each inner array representing a CSV line.
	 */
	public function output_csv( $new_csv ) {
		$file = fopen( 'php://output', 'w' );
		foreach ( $new_csv as $line ) {
			fputcsv( $file, $line );
		}
		fclose( $file );
		exit;
	}

	/**
	 * Sets HTTP headers to facilitate downloading a CSV file.
	 *
	 * This function configures the HTTP headers to set the content type as CSV and to instruct the browser
	 * to prompt the user to download the file with a specified filename. It's typically used just before
	 * streaming a CSV file to ensure the browser treats the response as a downloadable file.
	 *
	 * @param string $filename The base name of the file, without the extension, to be used for the downloaded CSV.
	 */
	public function setup_report_headers( $filename ) {
		header( 'Content-type: application/csv' );
		header( 'Content-Disposition: attachment; filename="' . $filename . '.csv"' );
	}

	/**
	 * Creates csv of all the posts in the products post type that are not synced.
	 */
	public function not_vertiv_products_report() {
		$this->setup_report_headers( 'not-vertiv-products-report' );
		$i = 0;
		$csv = array();
		$args = array(
			'post_type' => 'products',
			'posts_per_page' => -1,
		);
		$report_query = new WP_Query( $args );
		if ( $report_query->have_posts() ) {
			while ( $report_query->have_posts() ) {
				$report_query->the_post();
				$prodnum = get_field( 'prod_id_val' );
				if ( empty( $prodnum ) ) {
					$title = get_the_title();
					$url = get_permalink();
					$csv[ $i ][0] = $title;
					$csv[ $i ][1] = $url;
					$i++;
				}
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * Creates csv of all products that contain a product id number.
	 */
	public function vertiv_products_report() {
		$this->setup_report_headers( 'vertiv-feed-products' );
		$i = 0;
		$csv = array();
		$args = array(
			'post_type' => 'products',
			'posts_per_page' => -1,
		);
		$report_query = new WP_Query( $args );
		if ( $report_query->have_posts() ) {
			while ( $report_query->have_posts() ) {
				$report_query->the_post();
				$prodnum = get_field( 'prod_id_val' );
				if ( ! empty( $prodnum ) ) {
					$csv[ $i ][0] = get_the_title();
					$csv[ $i ][1] = strip_tags( get_the_content() );
					$csv[ $i ][2] = get_permalink();
					$csv[ $i ][3] = get_the_ID();
					$csv[ $i ][4] = $prodnum;
					$i++;
				}
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * Creates csv of all the posts in the products post type.
	 */
	public function all_products_report() {
		$this->setup_report_headers( 'all-products-report' );
		$i = 0;
		$csv = array();
		$args = array(
			'post_type' => 'products',
			'posts_per_page' => -1,
		);
		$report_query = new WP_Query( $args );
		if ( $report_query->have_posts() ) {
			while ( $report_query->have_posts() ) {
				$report_query->the_post();
				$title = get_the_title();
				$post_url = get_permalink();
				if ( ! empty( $title ) ) {
					$csv[ $i ][0] = $title;
					$csv[ $i ][1] = $post_url;
					$i++;
				}
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * Creates a report of all Yoast SEO fields for products.
	 */
	public function focus_keyword_products_report() {
		$this->setup_report_headers( 'products-yoast-report' );
		$csv = array();
		$csv[0][0] = 'Page Title';
		$csv[0][1] = 'Focus Keyword';
		$csv[0][2] = 'Yoast Seo Title';
		$csv[0][3] = 'Yoast Seo Metadescription';
		$csv[0][4] = 'Yoast Seo Link Index';
		$csv[0][5] = 'Yoast SEO Content Score';
		$csv[0][6] = 'Page URL';
		$i = 1;
		$args = array(
			'post_type' => 'page',
			'posts_per_page' => -1,
		);
		$report_query = new WP_Query( $args );
		if ( $report_query->have_posts() ) {
			while ( $report_query->have_posts() ) {
				$report_query->the_post();
				$id = get_the_ID();
				$csv[ $i ][0] = get_the_title();
				$csv[ $i ][1] = get_post_meta( $id, '_yoast_wpseo_focuskw', true );
				$csv[ $i ][2] = get_post_meta( $id, '_yoast_wpseo_title', true );
				$csv[ $i ][3] = get_post_meta( $id, '_yoast_wpseo_metadesc', true );
				$csv[ $i ][4] = get_post_meta( $id, '_yoast_wpseo_linkdex', true );
				$csv[ $i ][5] = get_post_meta( $id, '_yoast_wpseo_content_score', true );
				$csv[ $i ][6] = get_permalink();
				$i++;
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * Generates a report of every child product and which product is their parent.
	 */
	public function child_products_report() {
		$this->setup_report_headers( 'child-products-report' );
		$csv = array();
		$i = 0;
		$args = array(
			'post_type' => 'products',
			'posts_per_page' => -1,
			'publish' => 'publish',
		);
		$report_query = new WP_Query( $args );
		if ( $report_query->have_posts() ) {
			while ( $report_query->have_posts() ) {
				$report_query->the_post();
				$prodnum = get_field( 'child_prod_id_list' );
				if ( ! empty( $prodnum ) ) {
					$parent = get_the_title();
					$childprodar = explode( ',', $prodnum );
					foreach ( $childprodar as $childprod ) {
						$newargs = array(
							'post_type' => 'products',
							'publish' => 'publish',
							'meta_query' => array(
								array(
									'key' => 'prod_id_val',
									'value' => $childprod,
								),
							),
						);
						$posts_list = get_posts( $newargs );
						if ( ! empty( $posts_list ) ) {
							$title = $posts_list[0]->post_title;
							$csv[ $i ][0] = $title;
							$csv[ $i ][1] = $parent;
							$i++;
						}
					}
				}
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * Get products that have been updated in the last two weeks.
	 */
	public function updated_products_two_weeks_report() {
		$this->setup_report_headers( 'updated-products-two-weeks-report' );
		$i = 0;
		$csv = array();
		$xml_files = $this->get_xml_files();
		foreach ( $xml_files as $xml_file ) {
			$xml_info = simplexml_load_file( $xml_file );
			foreach ( $xml_info->Product as $key => $value ) {
				$datelastweekformat = strtotime( gmdate( 'Y-m-d', strtotime( '-2 week' ) ) );
				$pub_date_format = strtotime( substr( $value->Product->ModifiedDate, 0, 10 ) );

				$correct_region = $this->is_product_sold_in_region( $value->Product, 'North America NA', 'USA' );

				if ( $datelastweekformat < $pub_date_format && $correct_region ) {
					$product_id = (string) $value->Product->ProductId;
					if ( ! empty( $product_id ) ) {
						$args = array(
							'post_type' => 'products',
							'publish' => 'publish',
							'meta_query' => array(
								array(
									'key' => 'prod_id_val',
									'value' => $product_id,
								),
							),
						);
						$posts_list = get_posts( $args );
						if ( ! empty( $posts_list ) ) {
							$post_id = $posts_list[0]->ID;
							$post_title = get_the_title( $post_id );
							$csv[ $i ][0] = $product_id;
							$csv[ $i ][1] = $post_title;
							$i++;
						}
					}
				}
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * Get products that have been created in the last month.
	 */
	public function new_products_last_month_report() {
		$this->setup_report_headers( 'new-products-last-month-report' );
		$i = 0;
		$csv = array();
		$xml_files = $this->get_xml_files();
		foreach ( $xml_files as $xml_file ) {
			$xml_info = simplexml_load_file( $xml_file );
			foreach ( $xml_info->Product as $key => $value ) {
				$date_last_month_format = strtotime( gmdate( 'Y-m-d', strtotime( '-1 month' ) ) );
				$pub_date_format = strtotime( substr( $value->Product->CreatedDate, 0, 10 ) );

				$correct_region = $this->is_product_sold_in_region( $value->Product, 'North America NA', 'USA' );

				if ( $date_last_month_format < $pub_date_format && $correct_region ) {
					$product_id = (string) $value->Product->ProductId;
					if ( ! empty( $product_id ) ) {
						$args = array(
							'post_type' => 'products',
							'publish' => 'publish',
							'meta_query' => array(
								array(
									'key' => 'prod_id_val',
									'value' => $product_id,
								),
							),
						);
						$posts_list = get_posts( $args );
						if ( ! empty( $posts_list ) ) {
							$post_id = $posts_list[0]->ID;
							$post_title = get_the_title( $post_id );
							$csv[ $i ][0] = $product_id;
							$csv[ $i ][1] = $post_title;
							$i++;
						}
					}
				}
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * This will create a csv file of every product's child products.
	 * Then compare with the child products that are shown for the product in the xml files.
	 */
	public function matching_child_products_report() {
		$this->setup_report_headers( 'matching-child-products-report' );
		$i = 1;
		$csv = array();
		$csv[0][0] = 'Product Title';
		$csv[0][1] = 'Product ID Number';
		$csv[0][2] = 'Common Framework Child Products';
		$csv[0][3] = 'Vertiv Child Products';
		$xml_files = $this->get_xml_files();
		foreach ( $xml_files as $xml_file ) {
			$xml_info = simplexml_load_file( $xml_file );
			foreach ( $xml_info->Product as $key => $value ) {
				$prodidval = (string) $value->Product->ProductId;
				$sub_products = (string) $value->Product->SubProducts;
				if ( ! empty( $sub_products ) ) {
					$parts = explode( ',', $sub_products );
					$sub_products = implode( ', ', $parts );
				}
				$args = array(
					'post_type' => 'products',
					'meta_query' => array(
						array(
							'key' => 'prod_id_val',
							'value' => $prodidval,
						),
					),
				);
				$posts_list = get_posts( $args );
				if ( ! empty( $posts_list ) ) {
					$title = wp_strip_all_tags( $posts_list[0]->post_title );
					$child_prod = get_field( 'child_prod_id_list', $posts_list[0]->ID );
					if ( $child_prod != $sub_products ) {
						$csv[ $i ][0] = $title;
						$csv[ $i ][1] = $prodidval;
						$csv[ $i ][2] = $child_prod;
						$csv[ $i ][3] = $sub_products;
						$i++;
					}
				}
			}
		}
		$this->output_csv( $csv );
	}

	/**
	 * Creates csv of all products that are not on CF, but are in the XML files.
	 */
	public function all_unsynced_products_report() {
		$this->setup_report_headers( 'all-unsynced-products-report' );
		// Gets all xml files in /app/uploads/xml
		$i = 0;
		$all_xml_products = array();
		$xml_files = $this->get_xml_files();
		// Goes through each file and grabs products. Puts them in an array with name and id.
		foreach ( $xml_files as $xml_file ) {
			$xml_info = simplexml_load_file( $xml_file );
			foreach ( $xml_info->Product as $key => $value ) {
				$prod_name = (string) $value->Product->ProductName;
				$prod_id = (string) $value->Product->ProductId;
				if ( ! empty( $prod_name ) ) {
					$all_xml_products[ $i ]['title'] = $prod_name;
					$all_xml_products[ $i ]['id'] = $prod_id;
					$i++;
				}
			}
		}

		// $all_xml_products[][] has all products currently in our xml files
		// Gets all products we have on CF that have been synced at one point in time.
		$i = 0;
		$cf_products = array();
		$args = array(
			'post_type' => 'products',
			'posts_per_page' => -1,
		);

		// Goes through every product and finds the ones which have been in the xml feed.
		// Puts them in an array with name and id.
		$products_query = new WP_Query( $args );
		if ( $products_query->have_posts() ) {
			while ( $products_query->have_posts() ) {
				$products_query->the_post();
				$prodnum = get_field( 'prod_id_val' );
				if ( ! empty( $prodnum ) ) {
					$cf_products[ $i ]['title'] = get_the_title();
					$cf_products[ $i ]['id'] = get_the_ID();
					$i++;
				}
			}
		}

		// $cf_products[][] has all products currently on cf that have been in the xml feed
		// Changes the arrays to one dimension in order to relieve errors in string comparison.
		foreach ( $all_xml_products as $xml_product ) {
			$xml_product_one_d[] = $xml_product['id'];
		}
		foreach ( $cf_products as $cf_product ) {
			$cf_product_one_d[] = $cf_product['id'];
		}
		// Compares the ID's in each array and finds the difference.
		$new_product_ids = array_diff( $xml_product_one_d, $cf_product_one_d );

		/**
		 * Creates array of new products.
		 * Takes all ids from $new_products[];
		 * Searches original array $all_xml_products with the ids from $new_products[] to find the product title.
		 * Builds a new array with the title and id for export.
		 */
		$x = 0;
		$csv = array();

		foreach ( $new_product_ids as $product_id ) {
			$new_product_ids[ $x ][0] = $product_id;
			// find product id inside $all_xml_products
			// build an array with product name and id
			$key = array_search( $product_id, array_column( $all_xml_products, 'id' ) );
			$csv[ $x ][0] = $all_xml_products[ $key ]['title'];
			$csv[ $x ][1] = $all_xml_products[ $key ]['id'];
			$x++;
		}
		$this->output_csv( $csv );
	}
}
