<?php
namespace BwWinner\API;

class API {
	
	public $rest_namespace;

	public function __construct () {
		$this->rest_namespace = 'bw-winners/v1';
		add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );

	}
	public function register_rest_routes () {
		// csv import
		register_rest_route( $this->rest_namespace, '/csv-import/save', array(
			'methods' => 'POST',
			'callback' => array( $this, 'csv_import' ),
			'permission_callback' => array( $this, 'csv_import_permissions' )
		) );
		// options
		register_rest_route( $this->rest_namespace, '/options', array(
			'methods' => 'GET',
			'callback' => array( $this, 'get_options' ),
			'permission_callback' => array( $this, 'options_permissions' )
		) );
		register_rest_route( $this->rest_namespace, '/options', array(
			'methods' => 'POST',
			'callback' => array( $this, 'set_options' ),
			'permission_callback' => array( $this, 'options_permissions' )
		) );
		// block editor
		register_rest_route( $this->rest_namespace, '/block-settings', array(
			'methods' => 'GET',
			'callback' => array( $this, 'block_settings' ),
		) );
		// block data
		register_rest_route( $this->rest_namespace, '/block-data', array(
			'methods' => 'POST',
			'callback' => array( $this, 'block_data' ),
		) );
		// block data all sites
		register_rest_route( $this->rest_namespace, '/block-data-all-sites', array(
			'methods' => 'POST',
			'callback' => array( $this, 'block_data_all_sites' ),
		) );
		// block editor
		register_rest_route( $this->rest_namespace, '/sites', array(
			'methods' => 'GET',
			'callback' => array( $this, 'get_sites' ),
			// 'permission_callback' => array( $this, 'edit_posts' )
		) );
		// csv export
		register_rest_route( $this->rest_namespace, '/export/(?P<year>\d+)', array(
			'methods' => 'GET',
			'callback' => array( $this, 'csv_export' ),
			// 'permission_callback' => array( $this, 'csv_import_permissions' )
		) );
		// csv export
		register_rest_route( $this->rest_namespace, '/export-all', array(
			'methods' => 'GET',
			'callback' => array( $this, 'csv_export_all' ),
			// 'permission_callback' => array( $this, 'csv_import_permissions' )
		) );
		// brands
		register_rest_route( $this->rest_namespace, '/brands', array(
			'methods' => 'GET',
			'callback' => array( $this, 'get_brands' ),
			'permission_callback' => array( $this, 'edit_posts' )
		) );
		// post brands
		register_rest_route( $this->rest_namespace, '/post/(?P<post_id>\d+)/brands', array(
			'methods' => 'GET',
			'callback' => array( $this, 'get_post_brands' ),
			'permission_callback' => array( $this, 'edit_posts' )
		) );
		register_rest_route( $this->rest_namespace, '/post/(?P<post_id>\d+)/brands', array(
			'methods' => 'PUT',
			'callback' => array( $this, 'update_post_brands' ),
			'permission_callback' => array( $this, 'edit_posts' )
		) );

	}

	public function edit_posts ( $request ) {
		return current_user_can( 'edit_posts' );
	}

	public function csv_export ( $request ) {
		$year = $request->get_param( 'year' );

		global $blog_id;
		$current_blog_details = get_blog_details( array( 'blog_id' => $blog_id ) );

		$site = $current_blog_details->blogname;
		$site = strtolower( $site );
		$site = preg_replace( '/[\W_]+/', '-', $site );

		$filename = "winners-export-{$site}-{$year}.csv";
		header("Access-Control-Expose-Headers: Content-Disposition", false);
		header('Content-type: text/csv');
		header("Content-Disposition: attachment; filename=\"$filename\"");

		$csv_file = fopen('php://output', 'w');

		$csv_header = array(
			'Company',
			'Brand',
			'Product',
			'Status',
			'Product Page',
			'Update Form',
			'Email'
		);

		fputcsv($csv_file, $csv_header);

		global $wpdb;

		$company_table_name = $wpdb->prefix . 'bw_winners_companies';
		$brand_table_name = $wpdb->prefix . 'bw_winners_brands';
		$product_table_name = $wpdb->prefix . 'bw_winners_products';
		$entry_table_name = $wpdb->prefix . 'bw_winners_entries';

		$post_table_name = $wpdb->posts;

		$query = $wpdb->prepare(
			"SELECT company.name AS company_name, company.email AS company_email, brand.name AS brand_name,  product.name AS name, product.id AS id, product_post.post_status AS status
				FROM $company_table_name AS company
					INNER JOIN $brand_table_name AS brand ON company.id = brand.company_id
					INNER JOIN $product_table_name AS product ON brand.id = product.brand_id
					INNER JOIN $post_table_name AS product_post ON product.id = product_post.ID
				WHERE product.id IN (SELECT product_id FROM $entry_table_name WHERE year = %d)",
			$year
		);

		$results = $wpdb->get_results( $query );

		if ( $wpdb->last_error ) {
			error_log( $wpdb->last_error );
		}

		foreach ($results as $result) {
			$csv_data_entry = array(
				$result->company_name,
				$result->brand_name,
				$result->name,
				$result->status,
				get_permalink( $result->id ),
				get_home_url( null, "listing-upgrade/{$result->id}/" ),
				$result->company_email
			);

			fputcsv($csv_file, $csv_data_entry);
		}

		fclose($csv_file);

		exit;

	}

	public function csv_export_all ( $request ) {

		set_time_limit(1800);
		wp_suspend_cache_addition( true );
		wp_suspend_cache_invalidation( true );

		$filename = "winners-export-all.csv";
		header("Access-Control-Expose-Headers: Content-Disposition", false);
		header('Content-type: text/csv');
		header("Content-Disposition: attachment; filename=\"$filename\"");

		$csv_file = fopen('php://output', 'w');

		$csv_header = [
			'Last Modified Date',
			'Entry ID',
			'Award Year',
			'Award Score',
			'Award Name',
			'Award Country',
			'Award Region',
			'Product ID',
			'Product Name',
			'Type',
			'CategoryID',
			'Category',
			'Brand ID',
			'Brand Name',
			'Competition ID',
			'Competition Name',
			'Competition Type',
			'Competition Product Category',
			'Brand Award'
		];

		fputcsv($csv_file, $csv_header);

		$sites = get_sites();

		global $wpdb;

		foreach ( $sites as $site ) {
			switch_to_blog( $site->blog_id );

			$company_table_name = $wpdb->prefix . 'bw_winners_companies';
			$brand_table_name = $wpdb->prefix . 'bw_winners_brands';
			$product_table_name = $wpdb->prefix . 'bw_winners_products';
			$entry_table_name = $wpdb->prefix . 'bw_winners_entries';

			$blogname = $site->blogname;
			
			try {
				$limit  = 500;
				$offset = 0;

				do {

					$query = $wpdb->prepare(
						"SELECT
							entry.id AS entry_id,
							entry.year AS entry_year,
							entry.score AS entry_score,
							product.id AS product_id,
							product.name AS product_name,
							product.type AS product_type,
							product.price AS product_price,
							brand.id AS brand_id,
							brand.name AS brand_name
							FROM $brand_table_name AS brand
								INNER JOIN $product_table_name AS product ON brand.id = product.brand_id
								INNER JOIN $entry_table_name AS entry ON entry.product_id = product.id
							ORDER BY entry.year DESC
							LIMIT %d OFFSET %d",
						[
							$limit,
							$offset
						]
					);

					$results = $wpdb->get_results( $query, ARRAY_A );

					if ( $wpdb->last_error ) {
						error_log( $wpdb->last_error );
						break;
					}

					foreach ($results as $result) {
						$csv_data_entry = [
							date('Y-m-d H:i:s'),                                      // Last Modified Date
							"<missing_entry_id_for_{$result['entry_id']}>",             // Entry ID
							$result['entry_year'],                                      // Award Year
							$result['entry_score'],                                     // Award Score
							'',                                                       // Award Name
							'',                                                       // Award Country
							'',                                                       // Award Region
							"<missing_product_id_for_{$result['product_id']}>",         // Product ID
							$result['product_name'],                                    // Product Name
							$result['product_type'],                                    // Type
							'',                                                       // CategoryID
							$result['product_price'],                                   // Category
							"<missing_brand_id_for_{$result['brand_id']}>",             // Brand ID
							$result['brand_name'],                                      // Brand Name
							"<missing_competition_id_for_{$blogname}>",               // Competition ID
							"<missing_competition_name_for_{$blogname}>",             // Competition Name
							"<missing_competition_type_for_{$blogname}>",             // Competition Type
							"<missing_competition_product_category_for_{$blogname}>", // Competition Product Category
							''                                                        // Brand Award
						];

						fputcsv($csv_file, $csv_data_entry);
					}

					$offset += $limit;

				} while ( count( $results ) === $limit );

			} catch ( \Throwable $e ) {

			}
			
			restore_current_blog(); // Switch back to the original blog context
		}

		fclose($csv_file);

		exit;
	}

	public function csv_import_permissions () {
		return current_user_can( 'manage_options' ) && current_user_can( 'publish_posts' );
	}
	public function csv_import ( $request ) {

		// Prepare array for output
		$output = array();

		$body = $request->get_body_params();
		$files = $request->get_file_params();

		$year = $body['year'];

		if ( isset( $files['csv']['tmp_name'] ) ) {
			$tmpName = $files['csv']['tmp_name'];
			$csv = array_map('str_getcsv', file($tmpName));

			require_once \BwWinner\PLUGIN_PATH . 'includes/entries.php';
			$output = \BwWinner\Entries\csv_import( $csv, $year );
		}

		return $output;
	}
	public function options_permissions () {
		return current_user_can( 'manage_options' );
	}
	public function get_options ( $request ) {
		return \BwWinner\Options\get_options();
	}
	public function set_options ( $request ) {
		$options = $request->get_json_params();
		return \BwWinner\Options\update_options($options);
	}
	public function block_settings ( $request ) {
		$options = \BwWinner\Options\get_options();
		$resp = array(
			'filterSuggestions' => array(
				'award' => array( 'doubleGold', 'gold', 'silver', 'bronze' )
			),
			'settings' => array(
				'displayScoreAs' => $options['displayScoreAs']
			)
		);
		// $resp['filterSuggestions']['price_category'] =

		global $wpdb;

		// product category
		$results = $wpdb->get_results(
			"SELECT term.name as name
			FROM {$wpdb->terms} as term
				INNER JOIN {$wpdb->term_taxonomy} as tax ON tax.term_id = term.term_id
			WHERE tax.taxonomy = 'product-category'
			GROUP BY term.name
			ORDER BY term.name"
		);
		if ( ! $wpdb->last_error ) {
			$resp['filterSuggestions']['product_category'] = array();
			foreach ( $results as $result ) {
				$resp['filterSuggestions']['product_category'][] = $result->name;
			}
		} else {
			$resp['filterSuggestions']['product_category'] = $wpdb->last_error;
		}

		// post tag
		$results = $wpdb->get_results(
			"SELECT term.name as name
			FROM {$wpdb->terms} as term
				INNER JOIN {$wpdb->term_taxonomy} as tax ON tax.term_id = term.term_id
			WHERE tax.taxonomy = 'post_tag'
			GROUP BY term.name
			ORDER BY term.name"
		);
		if ( ! $wpdb->last_error ) {
			$resp['filterSuggestions']['tag'] = array();
			foreach( $results as $result ) {
				$resp['filterSuggestions']['tag'][] = $result->name;
			}
		} else {
			$resp['filterSuggestions']['tag'] = $wpdb->last_error;
		}

		// year
		$results = $wpdb->get_results(
			"SELECT year
			FROM {$wpdb->prefix}bw_winners_entries
			GROUP BY year
			ORDER BY year DESC"
		);
		if ( ! $wpdb->last_error ) {
			$resp['filterSuggestions']['year'] = array();
			foreach( $results as $result ) {
				$resp['filterSuggestions']['year'][] = $result->year;
			}
		} else {
			$resp['filterSuggestions']['year'] = $wpdb->last_error;
		}

		// company_name
		$results = $wpdb->get_results(
			"SELECT name
			FROM {$wpdb->prefix}bw_winners_companies
			GROUP BY name
			ORDER BY name"
		);
		if ( ! $wpdb->last_error ) {
			$resp['filterSuggestions']['company_name'] = array();
			foreach( $results as $result ) {
				$resp['filterSuggestions']['company_name'][] = $result->name;
			}
		} else {
			$resp['filterSuggestions']['company_name'] = $wpdb->last_error;
		}

		// price_category
		$results = $wpdb->get_results(
			"SELECT price
			FROM {$wpdb->prefix}bw_winners_products
			GROUP BY price
			ORDER BY price"
		);
		if ( ! $wpdb->last_error ) {
			$resp['filterSuggestions']['price_category'] = array();
			foreach( $results as $result ) {
				$value = trim( $result->price );
				if ( ! empty( $value ) ) {
					$resp['filterSuggestions']['price_category'][] = $value;
				}
			}
		} else {
			$resp['filterSuggestions']['price_category'] = $wpdb->last_error;
		}

		return $resp;
	}
	public function block_data( $request ) {
		$args = $request->get_json_params();
		return \BwWinner\get_winners($args);
	}
	public function block_data_all_sites( $request ) {
		$args = $request->get_json_params();
		// ToDO: fix
		// return \BwWinner\get_winners_all_sites($args);
		return \BwWinner\get_winners($args);
	}
	public function get_sites () {
		$sites = get_sites();
		$data = array();
		foreach ( $sites as $site ) {
			$blog = get_blog_details( array( 'blog_id' => $site->blog_id ) );
			$data[] = array(
				'name' => $blog->blogname,
				'blog_id' => $blog->blog_id,
				'rest_url' => get_rest_url( $blog->blog_id )
			);
		}
		return $data;
	}
	public function get_brands ( $request ) {
		global $wpdb;

		$query = "SELECT id, name 
			FROM {$wpdb->prefix}bw_winners_brands";

		$results = $wpdb->get_results($query, ARRAY_A);

		if ( $wpdb->last_error ) {
			return array();
		}

		return $results;
	}
	public function get_post_brands ( $request ) {
		global $bw_winners;

		$brands = $bw_winners->entities->get_post_brands( $request['post_id'] );

		return $brands;
	}
	public function update_post_brands ( $request ) {
		$brand_ids = $request->get_json_params();

		global $bw_winners;

		$bw_winners->entities->update_post_brands( $request['post_id'], $brand_ids );

		$brands = $bw_winners->entities->get_post_brands( $request['post_id'] );

		return $brands;
	}
}
