<?php
namespace BwWinner\Entries;

function add_entry ( $entry ) {
	if ( !isset( $entry['company_import_id'] ) || !is_numeric( $entry['company_import_id'] ) ) {
		trigger_error( 'Missing EntrantID!', E_USER_WARNING );
		return new \WP_Error( 'missing_entrant_id', 'Missing Entrant ID', $entry );
	}
	if ( !isset( $entry['entry_import_id'] ) || !is_numeric( $entry['entry_import_id'] ) ) {
		$entry['entry_import_id'] = 0;
	}

	// $entry['entry_import_id'] = intval($entry['entry_import_id']) * 10000 + intval($entry['year']);

	// Remove prices from categories
	$entry['product_price'] = filter_categories($entry['product_categories']);

	// Set the score based on award
	if ( empty( $entry['score'] ) && isset( $entry['award'] ) ) {
		$options = \BwWinner\Options\get_options();

		$awardToScore = array(
			'Double Gold' => isset ( $options['displayScoreAs']['doubleGold'] ) ? intval( $options['displayScoreAs']['doubleGold'] ) : 96,
			'Gold' =>  isset ( $options['displayScoreAs']['gold'] ) ? intval( $options['displayScoreAs']['gold'] ) : 91,
			'Silver' =>  isset ( $options['displayScoreAs']['silver'] ) ? intval( $options['displayScoreAs']['silver'] ) : 86,
			'Bronze' =>  isset ( $options['displayScoreAs']['bronze'] ) ? intval( $options['displayScoreAs']['bronze'] ) : 81
		);

		if ( isset( $awardToScore[$entry['award']] ) ) {
			$entry['score'] = $awardToScore[$entry['award']];
		}

	}

	return update_entry( $entry );
}

function update_company ( $entry ) {
	global $wpdb;
	global $bw_winners;
	// Get the company id. Add new post and company if none exist
	if ( isset( $entry['company_id'] ) ) {
		$company_id = $entry['company_id'];
	} else {
		$company_id = $wpdb->get_var( $wpdb->prepare(
			"SELECT id
			FROM {$wpdb->prefix}bw_winners_companies
			WHERE name = %s",
			$entry['company_name']
		) );

		if ( $wpdb->last_error ) {
			trigger_error( $wpdb->last_error, E_USER_WARNING );
		}
	}

	if ( ! $company_id ) {
		$company_id = wp_insert_post( array(
			'post_title' => isset( $entry['company_name'] ) ? $entry['company_name'] : '',
			'post_content' => empty( $entry['company_name'] ) ? '<!-- wp:paragraph --><p></p><!-- /wp:paragraph -->' : '',
			'post_status' => 'private',
			'post_type' => 'company'
		), true );

		if ( is_wp_error( $company_id ) ) {
			trigger_error( $company_id->get_error_message(), E_USER_WARNING );
			$company_id->add( 'failed_to_create_post', 'Failed to create company post', $entry );
			return $company_id; // failed to create post
		}
	}

	$new_company = array( 'id' => $company_id );

	if ( isset( $entry['company_name'] ) ) $new_company['name'] = $entry['company_name'];
	if ( isset( $entry['company_url'] ) ) $new_company['url'] = $entry['company_url'];
	if ( isset( $entry['email'] ) ) $new_company['email'] = $entry['email'];

	$company = $bw_winners->entities->update_company( $new_company );

	if ( $company === false ) {
		return new \WP_Error( 'failed_to_add_company', 'Failed to add company', array( 'error' => 'failed to add company', 'entry' => $entry ) );
	}

	return $company_id;
}

function update_brand ( $entry ) {
	$company_id = update_company( $entry );
	if ( is_wp_error( $company_id ) ) return $company_id;

	global $wpdb;
	global $bw_winners;
	// Get the brand id. Add new post and brand if none exist
	if ( isset( $entry['brand_id'] ) ) {
		$brand_id = $entry['brand_id'];
	} else {
		$brand_id = $wpdb->get_var( $wpdb->prepare(
			"SELECT id
			FROM {$wpdb->prefix}bw_winners_brands
			WHERE company_id = %d AND name = %s",
			$company_id,
			$entry['brand_name']
		) );

		if ( $wpdb->last_error ) {
			trigger_error( $wpdb->last_error, E_USER_WARNING );
		}
	}

	if ( ! $brand_id ) {
		$brand_id = wp_insert_post( array(
			'post_title' => isset( $entry['brand_name'] ) ? $entry['brand_name'] : '',
			'post_content' => empty( $entry['brand_name'] ) ? '<!-- wp:paragraph --><p></p><!-- /wp:paragraph -->' : '',
			'post_status' => 'private',
			'post_type' => 'brand'
		), true );
		if ( is_wp_error( $brand_id ) ) {
			trigger_error( $brand_id->get_error_message(), E_USER_WARNING );
			$brand_id->add( 'failed_to_create_post', 'Failed to create brand post', $entry );
			return $brand_id; // failed to create post
		}
	}

	$new_brand = array(	'id' => $brand_id, 'company_id' => $company_id	);

	if ( isset( $entry['brand_name'] ) ) $new_brand['name'] = $entry['brand_name'];
	if ( isset( $entry['brand_url'] ) ) $new_brand['url'] = $entry['brand_url'];

	$brand = $bw_winners->entities->update_brand( $new_brand );

	if ( $brand === false ) {
		return new \WP_Error( 'failed_to_add_brand', 'Failed to add brand', array( 'error' => 'failed to add brand', 'entry' => $entry ) );
	}
	return $brand_id;
}

function update_product ( $entry ) {
	$brand_id = update_brand( $entry );
	if ( is_wp_error( $brand_id ) ) return $brand_id;

	global $wpdb;
	global $bw_winners;
	// Get the product id. Add new post and product if none exist
	if ( isset( $entry['product_id'] ) ) {
		$product_id = $entry['product_id'];
	} else {
		$product_id = $wpdb->get_var( $wpdb->prepare(
			"SELECT id
			FROM {$wpdb->prefix}bw_winners_products
			WHERE brand_id = %d AND name = %s",
			$brand_id,
			$entry['product_name']
		) );

		if ( $wpdb->last_error ) {
			trigger_error( $wpdb->last_error, E_USER_WARNING );
		};
	}

	if ( ! $product_id ) {
		$product_id = wp_insert_post( array(
			'post_title' => isset( $entry['product_name'] ) ? $entry['product_name'] : '',
			'post_content' => empty( $entry['product_name'] ) ? '<!-- wp:paragraph --><p></p><!-- /wp:paragraph -->' : '',
			'post_status' => 'private',
			'post_type' => 'bw-product'
		), true );
		if ( is_wp_error( $product_id ) ) {
			trigger_error( $product_id->get_error_message(), E_USER_WARNING );
			$product_id->add( 'failed_to_create_post', 'Failed to create product post', $entry );
			return $product_id; // failed to create post
		}
	}

	$new_product = array(
		'id' => $product_id,
		'brand_id' => $brand_id
	);

	if ( isset( $entry['product_name'] ) ) $new_product['name'] = $entry['product_name'];
	if ( isset( $entry['product_url'] ) ) $new_product['url'] = $entry['product_url'];
	if ( isset( $entry['product_type'] ) ) $new_product['type'] = $entry['product_type'];
	if ( isset( $entry['product_price'] ) ) $new_product['price'] = $entry['product_price'];
	if ( isset( $entry['product_country'] ) ) $new_product['country'] = $entry['product_country'];

	$product = $bw_winners->entities->update_product( $new_product );

	if ( $product === false ) {
		return new \WP_Error( 'failed_to_add_product', 'Failed to add product', array( 'error' => 'failed to add product', 'entry' => $entry ) );
	}

	// set the product categories
	$product_terms = array_map( function ( $name ) {
		
		if ( empty( $name ) )  return false;

		$term = get_term_by( 'name', $name, 'product-category' );
		if ($term) return $term->term_id;

		$term = wp_insert_term( $name, 'product-category' );
		if ( is_wp_error( $term ) ) {
			trigger_error( $term->get_error_message(), E_USER_WARNING );
			return false; // failed to create post
		}
		return $term['term_id'];
	}, isset( $entry['product_categories'] ) ? $entry['product_categories'] : array() );

	if ( ! $added_terms = wp_set_post_terms( $product_id, array_filter($product_terms), 'product-category' ) ) {
		if ( is_wp_error( $added_terms ) ) {
			trigger_error( $added_terms->get_error_message(), E_USER_WARNING );
		}
	}
		
	return $product_id;
}

function update_entry ( $entry ) {
	if ( empty( $entry['product_name'] ) ) {
		$entry['product_name'] = isset( $entry['brand_name'] ) ?
			( isset( $entry['product_type'] ) ? $entry['brand_name'] . ' - ' . $entry['product_type'] : $entry['brand_name'] ) :
			( isset( $entry['product_type'] ) ? $entry['product_type'] : '' );
	}

	global $bw_winners;

	// add_entry_ids( $entry );

	$product_id = update_product( $entry );
	if ( is_wp_error( $product_id ) ) return $product_id;

	$product_entry = $bw_winners->entities->insert_entry( array(
		'import_id' => $entry['entry_import_id'],
		'product_id' => $product_id,
		'year' => $entry['year'],
		'score' => $entry['score']
	) );

	if ( $product_entry === false ) {
		return new \WP_Error( 'failed_to_update_entry', 'Failed to update entry', array( 'error' => 'failed to update entry', 'entry' => $entry ) );
	}

	return true;
}


function filter_categories ( &$categories ) {
	// remove the price categories from the array and return the last one
	$price = '';
	for ( $i = 0; $i < count($categories); $i++ ) {
		if ( preg_match( '/\$\d/', $categories[$i] ) ) {
			$price = array_splice($categories, $i, 1)[0];
			$i--;
		}
	}
	return $price;
}


function clean_up () {
	global $wpdb;

	$delete_products = "DELETE FROM {$wpdb->prefix}posts WHERE post_type = 'bw-product' AND ID NOT IN (
			SELECT product_id FROM {$wpdb->prefix}bw_winners_entries
		);";

	$wpdb->query( $delete_products );
	if ( $wpdb->last_error ) {
		trigger_error( $wpdb->last_error, E_USER_WARNING );
		return false;
	};

	$delete_brands = "DELETE FROM {$wpdb->prefix}posts WHERE post_type = 'brand' AND ID NOT IN (
			SELECT brand_id FROM {$wpdb->prefix}bw_winners_products
		);";
	
	$wpdb->query( $delete_brands );
	if ( $wpdb->last_error ) {
		trigger_error( $wpdb->last_error, E_USER_WARNING );
		return false;
	};

	$delete_companies = "DELETE FROM {$wpdb->prefix}posts WHERE post_type = 'company' AND ID NOT IN (
			SELECT company_id FROM {$wpdb->prefix}bw_winners_brands
		);";
	
	$wpdb->query( $delete_companies );
	if ( $wpdb->last_error ) {
		trigger_error( $wpdb->last_error, E_USER_WARNING );
		return false;
	};

	$delete_term_relationships = "DELETE FROM {$wpdb->prefix}term_relationships
		WHERE object_id NOT IN (SELECT ID FROM {$wpdb->prefix}posts);";
	
	$wpdb->query( $delete_term_relationships );
	if ( $wpdb->last_error ) {
		trigger_error( $wpdb->last_error, E_USER_WARNING );
		return false;
	};

	$update_term_counts = "UPDATE {$wpdb->prefix}term_taxonomy AS term_tax
		SET count = (
			SELECT count(post.ID)
			FROM {$wpdb->prefix}term_relationships AS term_rel
			LEFT JOIN {$wpdb->prefix}posts AS post ON post.ID = term_rel.object_id
			WHERE term_rel.term_taxonomy_id = term_tax.term_taxonomy_id
		);";
	
	$wpdb->query( $update_term_counts );
	if ( $wpdb->last_error ) {
		trigger_error( $wpdb->last_error, E_USER_WARNING );
		return false;
	};

	$delete_unused_terms = "DELETE term FROM {$wpdb->prefix}terms AS term
		INNER JOIN {$wpdb->prefix}term_taxonomy AS term_tax ON term.term_id = term_tax.term_id
		WHERE term_tax.taxonomy = 'product-category' AND term_tax.count = 0;";
	
	$wpdb->query( $delete_unused_terms );
	if ( $wpdb->last_error ) {
		trigger_error( $wpdb->last_error, E_USER_WARNING );
		return false;
	};

	$delete_unused_terms = "DELETE FROM {$wpdb->prefix}term_taxonomy WHERE taxonomy = 'product-category' AND count = 0;";
	
	$wpdb->query( $delete_unused_terms );
	if ( $wpdb->last_error ) {
		trigger_error( $wpdb->last_error, E_USER_WARNING );
		return false;
	};

	return true;
}

// function create_slug ( $str ) {
// 	$str = preg_replace('/&+/', 'and', $str);
// 	$str = preg_replace('/\W+/', '_', $str);
// 	$str = preg_replace('/_+/', '_', $str);
// 	$str = strtolower($str);
// 	return trim($str, '_');
// }

function csv_import ( $csv, $year ) {

	global $wpdb;
	global $bw_winners;

	$wpdb->query( $wpdb->prepare(
		"DELETE FROM {$wpdb->prefix}bw_winners_entries WHERE year=%d",
		$year
	) );
	$bw_winners->entities->flush_cache();

	$valid_columns = array(
		'eccID' => array(
			'multivalue' => false,
			'key' => 'entry_import_id'
		),
		'wineType' => array(
			'multivalue' => false,
			'key' => 'product_type'
		),
		'categoryName' => array(
			'multivalue' => true,
			'separator' => '; ',
			'key' => 'product_categories'
		),
		'____priceCategory' => array(
			'multivalue' => false,
			'key' => 'product_price'
		),
		'entrantID' => array(
			'multivalue' => false,
			'key' => 'company_import_id'
		),
		'company' => array(
			'multivalue' => false,
			'key' => 'company_name'
		),
		'brand' => array(
			'multivalue' => false,
			'key' => 'brand_name'
		),
		'____productName' => array(
			'multivalue' => false,
			'key' => 'product_name'
		),
		'awardType' => array(
			'multivalue' => false,
			'key' => 'award'
		),
		'score' => array(
			'multivalue' => false,
			'key' => 'score'
		),
		'____year' => array(
			'multivalue' => false,
			'key' => 'year'
		),
		'website' => array(
			'multivalue' => false,
			'key' => 'company_url'
		),
		'____brandURL' => array(
			'multivalue' => false,
			'key' => 'brand_url'
		),
		'____productURL' => array(
			'multivalue' => false,
			'key' => 'product_url'
		),
		'email' => array(
			'multivalue' => false,
			'key' => 'email'
		),
		// thedatastill.com
		'Entry ID' => array(
			'multivalue' => false,
			'key' => 'entry_import_id'
		),
		'Type' => array(
			'multivalue' => false,
			'key' => 'product_type'
		),
		'Category' => array(
			'multivalue' => true,
			'separator' => ', ',
			'key' => 'product_categories'
		),
		'EntrantID' => array(
			'multivalue' => false,
			'key' => 'company_import_id'
		),
		'Company' => array(
			'multivalue' => false,
			'key' => 'company_name'
		),
		'Brand' => array(
			'multivalue' => false,
			'key' => 'brand_name'
		),
		'Name' => array(
			'multivalue' => false,
			'key' => 'product_name'
		),
		'Award' => array(
			'multivalue' => false,
			'key' => 'award',
		),
		'Score' => array(
			'multivalue' => false,
			'key' => 'score'
		),
		'Country' => array(
			'multivalue' => false,
			'key' => 'product_country'
		),
		// ???
		'Country of Origin' => array(
			'multivalue' => false,
			'key' => 'product_country'
		),
	);

	$successCount = 0;
	$failedCount = 0;
	$errors = array();

	// array_shift($csv);
	$col_names = array_shift($csv);

	foreach ( $csv as $row_index => $row ) {
		$entry = array( 'year' => $year );
		foreach ( $row as $col_index => $col ) {
			if ( ! isset( $valid_columns[$col_names[$col_index]] ) ) continue;
			$column_meta = $valid_columns[$col_names[$col_index]];
			if ( $column_meta['multivalue'] ) {
				$entry[$column_meta['key']] = explode( $column_meta['separator'], $col);
				array_filter( array_map( 'trim', $entry[$column_meta['key']] ) );
			} else {
				$entry[$column_meta['key']] = trim($col);
			}
		}
		$added = add_entry( $entry );
		if ( ! is_wp_error( $added ) && $added ) {
			$successCount++;
		} else {
			$failedCount++;
			$errors[] = $added;
		}
	}

	$result = array (
		'success' => $successCount,
		'failed' => $failedCount
	);

	if ( ! empty( $errors ) ) {
		$result['errors'] = $errors;
	}

	return $result;
}
