<?php

/**
 * Class Wiaas_Document
 */
class Wiaas_Document {

	/**
	 * Default available document types for wiaas
	 * @var array
	 */
	private static $available_doc_types = array(
		'template_questionaire' => array(
			'name' => 'Template Questionaire',
			'is_special_type' => false,
		),
		'order_questionaire' => array(
			'name' => 'Order Questionaire',
			'is_special_type' => true,
		),
		'configuration' => array(
			'name' => 'Configuration',
			'is_special_type' => true,
		),
		'install_guide' => array(
			'name' => 'Install guide',
			'is_special_type' => false,
		),
		'customer_acceptance' => array(
			'name' => 'Customer acceptance',
			'is_special_type' => true,
		),
		'template_agreement' => array(
			'name' => 'Template Agreement',
			'is_special_type' => false,
		),
		'order_agreement' => array(
			'name' => 'Order Agreement',
			'is_special_type' => true,
		),
		'installation_protocol' => array(
			'name' => 'Installation protocol',
			'is_special_type' => true,
		),
		'statements' => array(
			'name' => 'Statements',
			'is_special_type' => false,
		),
		'customer_acceptance_template' => array(
			'name' => 'Customer acceptance template',
			'is_special_type' => false,
		),
	);

	private static $special_doc_types= array(
		'order_questionaire', 'configuration', 'customer_acceptance', 'order_agreement', 'installation_protocol'
	);

	public static function init() {

		add_action('registered_taxonomy', array( __CLASS__, 'register_wiaas_doc_categories' ));

		add_action('init', array(__CLASS__, 'register_wiaas_document'));
	}



	/**
	 * Retrieve available categories for wiaas documents
	 *
	 * @return array Array of available document categories
	 */
	public static function get_available_doc_types() {

		$terms = get_terms(array(
			'taxonomy' => 'wiaas_doc_type',
			'hide_empty' => false,
		));

		return array_map(function($term) {
			$is_special = array_key_exists($term->slug, self::$available_doc_types) ?
				self::$available_doc_types[$term->slug]['is_special_type'] :
				false;

			return array(
				'id' => $term->slug,
				'name' => $term->name,
				'is_special_type' => $is_special,

			);

		}, $terms);
	}

	/**
	 * Create new document
	 * @param $name
	 * @param $path
	 * @param bool $visible
	 *
	 * @return bool|int|WP_Error
	 */
	public static function add_document($name, $path, $visible = false) {
		// create
		$id = wp_insert_post( array(
			'post_title'   => $name,
			'post_author'  => wp_get_current_user()->ID,
			'post_type'    => 'wiaas_doc',
			'post_status'  => 'publish',
		) );

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

		update_post_meta($id, '_wiaas_doc_versions', array( $path ));

		self::set_is_doc_visible($id, $visible);

		return $id;
	}

	/**
	 * Add new version for document
	 * @param $doc_id
	 * @param $url
	 */
	public static function add_document_version($doc_id, $url) {
		$versions = get_post_meta($doc_id, '_wiaas_doc_versions', true);

		$versions[] = $url;

		update_post_meta($doc_id, '_wiaas_doc_versions', $versions);
	}

	/**
	 * Assign type to document
	 * @param $id
	 * @param $type
	 */
	public static function set_doc_type($id, $type) {
		wp_set_object_terms($id, $type, 'wiaas_doc_type');
	}

	/**
	 * Set if document visible to customer
	 * @param $id
	 * @param $is_visible
	 */
	public static function set_is_doc_visible($id, $is_visible) {

		update_post_meta($id, '_wiaas_doc_visible', $is_visible ? 'yes' : 'no');
	}

	/**
	 * Retrieve document type
	 * @param $id
	 *
	 * @return array|null
	 */
	public static function get_doc_type($id) {
		$terms = wp_get_object_terms($id, 'wiaas_doc_type');

		if (is_wp_error($terms) || count($terms) === 0) {
			return null;
		}

		$term = $terms[0];
		return array(
			'id' => $term->slug,
			'name' => $term->name,
			'is_special_type' => in_array($term->slug, self::$special_doc_types),
		);
	}

	/**
	 * Retrieve if document visible to customer
	 * @param $id
	 *
	 * @return bool
	 */
	public static function is_doc_visible($id) {
		return get_post_meta($id, '_wiaas_doc_visible', true) === 'yes';
	}

	/**
	 * Retrieve all versions for document
	 * @param $doc_id
	 *
	 * @return mixed
	 */
	public static function get_document_versions($doc_id) {
		return get_post_meta($doc_id, '_wiaas_doc_versions', true);
	}

	/**
	 * Get latest or specific document version
	 * @param $id
	 * @param null $version_id
	 *
	 * @return null
	 */
	public static function get_doc_version($id, $version_id = null) {
		$versions = self::get_document_versions($id);

		if (count($versions) === 0) {
			return null;
		}

		return isset($versions[$version_id]) ?
			$versions[$version_id] : $versions[count($versions) - 1];
	}

	/**
	 * Get document download link for latest or specified version
	 * @param $id
	 * @param null $version
	 *
	 * @return string
	 */
	public static function get_doc_download_link($id, $version = null) {
		$permalink = get_permalink($id);
		$sap = strpos($permalink, '?')?'&':'?';

		$ver = isset($version) ? "&v={$version}" : '';
		return $permalink.$sap."wiaasdoc={$id}{$ver}";
	}

	/**
	 * Retrieve document informations
	 * @param $id
	 *
	 * @return array|null
	 */
	public static function get_doc_info($id) {
		$post = get_post($id, ARRAY_A);

		if (!$post) {
			return null;
		}

		$version = self::get_doc_version($id);

		return array(
			'id' => $id,
			'name' => $post['post_title'],
			'url' => self::get_doc_download_link($id),
			'type' => self::get_doc_type($id),
			'version' => $version,
			'visible' => self::is_doc_visible($id),
			'extension' => wiaas_get_doc_version_extension($version),
		);

	}


	/**
	 * Search document by name
	 * @param $name
	 * @param int $limit
	 * @param bool $include_special
	 *
	 * @return array
	 */
	public static function search($name, $limit = 10, $include_special = false) {
		$query = new WP_Query();

		$args = array(
			'post_status' => 'publish',
			'post_type' => 'wiaas_doc',
			'posts_per_page' => $limit,
			's' => $name
		);

		if (!$include_special) {
			$args['tax_query'] = array(
				array(
					'taxonomy' => 'wiaas_doc_type',
					'field'    => 'slug',
					'operator' => 'NOT IN',
					'terms'    => self::$special_doc_types,
				)
			);
		}

		$items = $query->query($args);

		return array_map(function($item) {
			$id = $item->ID;
			return array(
				'id' => $id,
				'name' => $item->post_title,
			);
		}, $items);
	}

	/**
	 * Registers taxonomy and default values for wiaas document types
	 */
	public static function register_wiaas_doc_categories($taxonomy) {

		if ($taxonomy !== 'wpdmcategory') {
			return;
		}

		foreach (self::$available_doc_types as $key => $available_doc_type) {
			wp_insert_term($available_doc_type['name'], 'wpdmcategory', array(
				'slug' => $key
			));
		}
	}

	public static function register_wiaas_document() {
		// Register document object
		self::_register_document();
		// Register document types taxonomy
		self::_register_doc_types();
	}

	// PRIVATE

	/**
	 * Register wiaas_doc post type
	 */
	private static function _register_document() {
		$labels = array(
			'name' => __('Documents','wiaas'),
			'singular_name' => __('Document','wiaas'),
			'add_new' => __('Add New','wiaas'),
			'add_new_item' => __('Add New Document','wiaas'),
			'edit_item' => __('Edit Document','wiaas'),
			'new_item' => __('New Document','wiaas'),
			'all_items' => __('All Documents','wiaas'),
			'view_item' => __('View Document','wiaas'),
			'search_items' => __('Search Documents','wiaas'),
			'not_found' => __('No Document Found','wiaas'),
			'not_found_in_trash' => __('No Documents found in Trash','wiaas'),
			'parent_item_colon' => '',
			'menu_name' => __('Documents','wiaas')

		);

		$args = array(
			'labels' => $labels,
			'public' => true,
			'publicly_queryable' => false,
			'show_ui' => true,
			'show_in_menu' => true,
			'show_in_nav_menus' => true,
			'query_var' => true,
			'rewrite' => array('slug' => 'wiaas_doc', 'with_front' => false),
			'capability_type' => 'wiaas_doc',
			'has_archive' => false,
			'hierarchical' => false,
			'taxonomies' => array(),
			'menu_icon' => 'dashicons-media-document',
			'exclude_from_search' => false,
			'supports' => array('title'),

		);

		register_post_type('wiaas_doc', $args);
	}

	/**
	 * Register wiaas_doc_type taxonomy for wiaas_doc post type
	 */
	private static function _register_doc_types() {
		$labels = array(
			'name'              => _x( 'Document type', 'taxonomy general name', 'wiaas' ),
			'singular_name'     => _x( 'Document type', 'taxonomy singular name', 'wiaas' ),
			'menu_name'         => _x( 'Document types', 'Admin menu name', 'wiaas' ),
			'search_items'      => __( 'Search Document types', 'wiaas' ),
			'all_items'         => __( 'All Document types', 'wiaas' ),
			'parent_item'       => __( 'Parent Document type', 'wiaas' ),
			'parent_item_colon' => __( 'Parent Document type:', 'wiaas' ),
			'edit_item'         => __( 'Edit Document type', 'wiaas' ),
			'update_item'       => __( 'Update Document type', 'wiaas' ),
			'add_new_item'      => __( 'Add New Document type', 'wiaas' ),
			'new_item_name'     => __( 'New Document type Name', 'wiaas' ),
		);

		$args = array(
			'hierarchical'      => false,
			'label'                 => __( 'Document type', 'wiaas' ),
			'labels'            => $labels,
			'show_ui'           => true,
			'show_admin_column' => true,
			'query_var'         => true,
			'rewrite'           => array( 'slug' => 'wiaas_doc_type' ),
			'show_in_rest'      => false,
            'capabilities'          => array(
                'manage_terms' => 'manage_wiaas_doc_terms',
                'edit_terms'   => 'edit_wiaas_doc_terms',
                'delete_terms' => 'delete_wiaas_doc_terms',
                'assign_terms' => 'assign_wiaas_doc_terms',
            ),
		);

		register_taxonomy( 'wiaas_doc_type', array( 'wiaas_doc' ), $args );

		foreach (self::$available_doc_types as $key => $available_doc_type) {
			if (! has_term($available_doc_type['name'], 'wiaas_doc_type')) {
				wp_insert_term($available_doc_type['name'], 'wiaas_doc_type', array(
					'slug' => $key
				));
			}
		}
	}

}

Wiaas_Document::init();
