<?php

class Wiaas_Order_Project {

	public static function init() {
		add_action('woocommerce_after_register_taxonomy', array(__CLASS__, 'register_order_project_taxonomy'));
	}

	/**
	 * Register order project taxonomy
	 */
	public static function register_order_project_taxonomy() {
		$labels = array(
			'name'              => _x( 'Project', 'taxonomy general name', 'wiaas' ),
			'singular_name'     => _x( 'Project', 'taxonomy singular name', 'wiaas' ),
			'search_items'      => __( 'Search Order Projects', 'wiaas' ),
			'all_items'         => __( 'All Order Projects', 'wiaas' ),
			'parent_item'       => __( 'Parent Order Project', 'wiaas' ),
			'parent_item_colon' => __( 'Parent Order Project:', 'wiaas' ),
			'edit_item'         => __( 'Edit Order Project', 'wiaas' ),
			'update_item'       => __( 'Update Order Project', 'wiaas' ),
			'add_new_item'      => __( 'Add New Order Project', 'wiaas' ),
			'new_item_name'     => __( 'New Order Project Name', 'wiaas' ),
			'menu_name'         => __( 'Order Project', 'wiaas' ),
		);

		$args = array(
			'hierarchical'      => false,
			'labels'            => $labels,
			'show_ui'           => true,
			'show_admin_column' => true,
			'query_var'         => true,
			'rewrite'           => array( 'slug' => 'shop_order_project' ),
			'update_count_callback' => array(__CLASS__, 'update_count_callback')
		);

		register_taxonomy( 'shop_order_project', array( 'shop_order' ), $args );
	}

	/**
	 * Callback to handle counting of number of orders inside every project
	 * This does not work out of the box for orders since they are marked as private post type
	 *
	 * @param array $project_ids
	 */
	public static function update_count_callback($project_ids) {
		// Update counts
		_update_generic_term_count( $project_ids, get_taxonomy('shop_order_project') );
	}

	/**
	 * Retrieves available order projects
	 * @return array List of available order projects
	 */
	public static function get_available_order_projects() {
		$all_terms =  get_terms(array(
			'taxonomy' => 'shop_order_project',
			'hide_empty' => false
		));

		if (is_wp_error($all_terms)) {
			return array();
		}

		$available_terms = array();

		foreach ($all_terms as $term) {
			if (self::is_order_project_available($term->term_id)) {
				$available_terms[] = array(
					'id' => $term->term_id,
					'name' => $term->name
				);
			}
		}

		return $available_terms;
	}

	/**
	 * Retrieves order project name
	 * @param int $order_id
	 *
	 * @return string|null Project name if order is assigned to project, null otherwise
	 */
	public static function get_project_name_for_order($order_id) {
		$terms = wp_get_object_terms($order_id, 'shop_order_project');
		return isset($terms[0]) ? $terms[0]->name : null;
	}

	/**
	 * Assigns giver order to given project
	 * @param int $order_id
	 * @param int $project_id
	 */
	public static function set_project_for_order($order_id, $project_id) {
		wp_set_object_terms($order_id, $project_id, 'shop_order_project', false);
	}

	/**
	 * Adds new order project
	 * @param string $name Order Project name
	 * @param bool $is_available Flag indicating is order project available
	 *
	 * @return bool True on success, False on failure.
	 */
	public static function add_order_project($name, $is_available = true) {
		$result = wp_create_term($name, 'shop_order_project');

		if (is_wp_error($result)) {
			return false;
		}

		// save is term available
		$id = is_numeric($result) ? $result : $result['term_id'];
		self::_save_available_field($id, $is_available);

		return true;
	}

	/**
	 * @param int|WP_Term $project Order project or order project id
	 * @param bool $is_available
	 */
	public static function set_is_order_project_available($project, $is_available) {
		$project_id = is_numeric($project) ? $project : $project->term_id;
		self::_save_available_field($project_id, $is_available);
	}

	/**
	 * Retrieves if order project is available
	 * @param int|WP_Term $project Order project objects or id of order project
	 *
	 * @return bool TRUE if available, FALSE if not available
	 */
	public static function is_order_project_available($project) {
		$project_id = is_numeric($project) ? $project : $project->term_id;
		return get_term_meta($project_id, '_wiaas_is_available', true) === 'yes';
	}

	// PRIVATE

	/**
	 * @param int $id Order project id
	 * @param bool $is_available
	 */
	private static function _save_available_field($id, $is_available) {
		update_term_meta($id, '_wiaas_is_available', $is_available ? 'yes' : 'no');
	}
}

Wiaas_Order_Project::init();