<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}


/**
 * Class Wiaas_Order
 *
 * Integrates Woocommerce order with Wiaas order
 */

class Wiaas_Order {

	private static $object_order_type = 'shop_order';

	public static function init() {

		require_once dirname( __FILE__ ) . '/order/class-wiaas-order-project.php';

		add_filter('woocommerce_register_post_type_shop_order', array(__CLASS__, 'manage_order_settings'));

		add_filter('woocommerce_rest_check_permissions', array( __CLASS__, 'check_order_access'), 10, 4);

		add_filter('woocommerce_rest_prepare_shop_order_object', array(__CLASS__, 'transform_rest_order'), 999, 3);

		add_filter('woocommerce_rest_orders_prepare_object_query', array( __CLASS__, 'wiaas_prepare_rest_orders_query'), 10, 2);

        add_filter('woocommerce_new_order_note_data',  array( __CLASS__, 'update_new_order_comment_date'), 10, 3);
	}

	/**
	 * Update `shop_order` post type settings before creation to enable better order management for wiaas
	 *
	 * @param array $args
	 *
	 * @return array
	 */
	public static function manage_order_settings($args) {
		// show orders in backend menu
		$args['show_in_menu'] = true;

		//set icon
		$args['menu_icon'] = 'dashicons-cart';

		// set capabilities
		$args['capabilities'] = array(
			'edit_post'          => 'edit_shop_order',
			'read_post'          => 'read_shop_order',
			'delete_post'        => 'delete_shop_order',
			'edit_posts'         => 'edit_shop_orders',
			'edit_others_posts'  => 'edit_others_shop_orders',
			'publish_posts'      => 'publish_shop_orders',
			'read_private_posts' => 'read_private_shop_orders',
			'create_posts'       => 'create_shop_orders', // use `create_shop_orders` instead of `edit_shop_orders`
		);

		return $args;
	}

	public static function update_new_order_comment_date($comment_data, $order_data) {
	    $user = wp_get_current_user();

        $comment_data['comment_author'] = $user->display_name;
        $comment_data['comment_author_email'] = $user->user_email;

        return $comment_data;
    }

	/**
	 * Checks if current user has access to requested order/{orderId} via woocommerce REST API.
	 * Endpoint `/orders` is filtered correctly by groups, but endpoint `/orders/{orderId}` will return order even if
	 * user does not have access to it.
	 * Groups has general support for this using rest_prepare_{$post_type} but woocommerce api does not
	 * use this filter anymore. So we will just call the same function just with woocommerce filter.
	 *
	 * @param $permission
	 * @param $context
	 * @param $object_id
	 * @param $post_type
	 * @return bool
	 */
	public static function check_order_access($permission, $context, $object_id, $post_type) {
		if ($post_type === self::$object_order_type && $object_id !== 0) {
			return Groups_Post_Access::user_can_read_post($object_id);
		}
		return $permission;
	}

	/**
	 * Handles custom wiaas arguments to woocommerce orders api endpoint `wc/v2/orders`
	 * @param $args
	 * @param $request
	 *
	 * @return mixed
	 */
	public static function wiaas_prepare_rest_orders_query($args, $request) {

		# Handle wiaas_is_active flag
		if (isset($request['wiaas_is_active'])) {
			if ($request['wiaas_is_active'] === '1') {
				$args['post_status'] = array('wc-open', 'wc-processing');
			}
			if ($request['wiaas_is_active'] === '0') {
				$args['post_status'] = array('wc-completed', 'wc-cancelled');
			}
		}

		return $args;
	}

	/**
	 * Apply wiaas custom transformation on retrieved JSON order object
	 *
	 * @param $response
	 * @param $order
	 * @param $request
	 *
	 * @return mixed
	 */
	public static function transform_rest_order($response, $order, $request) {
		$data = $response->get_data();

		# apply overrides

		$data = self::_append_customer_info($data, $order, $request);

		$data = self::_append_commercial_lead_info($data, $order, $request);

		$data = self::_append_wiaas_order_details($data, $order, $request);

		$data = self::_append_packages($data, $order, $request);

		if (isset($request['id'])) {

			$data = self::_append_order_process($data, $order, $request);

			$data = self::_append_order_comments($data, $order, $request);

			$data = self::_append_documents($data, $order, $request);
		}

		$response->set_data($data);

		return $response;
	}

	public static function set_order_vat($order_id, $vat_code) {
		add_post_meta($order_id, '_wiaas_vat_code', $vat_code);
	}

	public static function get_order_vat($order_id) {
		return get_post_meta($order_id, '_wiaas_vat_code', true);
	}

	public static function set_order_company($order_id, $company_name) {
		add_post_meta($order_id, '_wiaas_company_name', $company_name);
	}

	public static function get_order_company($order_id) {
		return get_post_meta($order_id, '_wiaas_company_name', true);
	}

	public static function set_order_reference($order_id, $reference) {
		add_post_meta($order_id, '_wiaas_reference', $reference);
	}

	public static function get_order_reference($order_id) {
		return get_post_meta($order_id, '_wiaas_reference', true);
	}

	public static function set_order_tender($order_id, $tender) {
		add_post_meta($order_id, '_wiaas_tender', $tender);
	}

	public static function get_order_tender($order_id) {
		return get_post_meta($order_id, '_wiaas_tender', true);
	}

	/**
	 * PRIVATE
	 */

	/**
	 * Append specific wiaas order details, like reference
	 * @param $data
	 * @param $order
	 * @param $request
	 */
	private static function _append_wiaas_order_details($data, $order, $request) {
		$data['reference'] = self::get_order_reference($order->get_id());
		$data['tender'] = self::get_order_tender($order->get_id());
		$data['vat'] = self::get_order_vat($order->get_id());
		$data['company_name'] = self::get_order_company($order->get_id());

		$data['project_name'] = Wiaas_Order_Project::get_project_name_for_order($order->get_id());

		return $data;
	}
	/**
	 * Appends additional wiaas customer lead info to order json response
	 * @param $data
	 * @param $order
	 * @param $request
	 *
	 * @return mixed
	 */
	private static function _append_commercial_lead_info($data, $order, $request) {

		$data['commercial_lead'] = array(
			'id' => 1,
			'name' => 'Coor Service Management',
			'phone' => '123456789',
			'email' => 'rikard@co-ideation.com'
		);

		return $data;
	}

	/**
	 * Appends additional wiaas customer info to order json response
	 * @param $data
	 * @param $order
	 * @param $request
	 *
	 * @return mixed
	 */
	private static function _append_customer_info($data, $order, $request) {

		$current_user = wp_get_current_user();

		$customer_id = $data['customer_id'];

		$customer_user = get_user_by('id', $customer_id);
		$data['customer'] = array(
			'email' => $customer_user->user_email,
			'name' => $customer_user->display_name,
			'phone' => '+46 (10) 5595148'
		);

		$data['is_my_order'] = $customer_id === $current_user->ID;

		return $data;
	}

	/**
	 * Filters only package product lines and appends additional wiaas products info to order json response
	 * @param $data
	 * @param $order
	 * @param $request
	 *
	 * @return mixed
	 */
	private static function _append_packages($data, $order, $request) {
		$line_items = array();

		$order_items = $order->get_items( 'line_item' );

		foreach ($data['line_items'] as $index => $product_line) {

			$item = $order->get_item($product_line['id']);

			// add only product lines that represent product bundles
			if (isset($item['wiaas_standard_package'])) {
				# get payment type info
				$product_line['payment_type'] = $item['wiaas_payment_type'];
				$product_line['service_price'] = floatval($item['wiaas_services_extra']);
				$product_line['service_contract_period'] = floatval($item['wiaas_service_contract_period']);
				$product_line['max_contract_period'] = floatval($item['wiaas_max_contract_period']);
				$product_line['period_unit'] = $item['wiaas_period_unit'];
				$product_line['recurring_price'] = floatval($item['wiaas_recurrent_extra']);
				$product_line['pay_period'] = floatval($item['wiaas_pay_period']);

				# collect status from  order
				if ($data['status'] === 'completed') {
					$product_line['status'] = 'production';
				} else if ($data['status'] === 'cancelled') {
					$product_line['status'] = 'cancelled';
				} else {
					$product_line['status'] = 'processing';
				}

				$product_line['short_desc'] = $product_line['status'];

				# collect completion data from order
				$product_line['date_completed'] = $data['date_completed'];

				if (isset($request['id'])) {
					// collect package addons
					$product_line['additional_packages'] = array();
					$addon_items = wiaas_get_order_item_addons($order_items, $item);
					foreach ($addon_items as $addon_item) {
						$product_line['additional_packages'][] = array(
							'id' => $addon_item->get_id(),
							'name' => $addon_item->get_name(),
						);
					}

					// collect package options
					$product_line['options'] = array();
					$option_items = wiaas_get_order_item_options($order_items, $item);
					foreach ($option_items as $option_item) {
						$product_line['options'][] = array(
							'id' => $option_item->get_id(),
							'name' => $option_item->get_name(),
							'group_name' => $option_item['wiaas_option_group_name']
						);
					}
				}

				$line_items[] = $product_line;
			}
		}
		$data['line_items'] = $line_items;

		$total_recurring_price = 0;

		foreach ($order_items as $order_item) {
			if (isset($order_item['wiaas_standard_package'])) {
				$total_recurring_price += floatval($order_item['quantity']) * floatval($order_item['wiaas_services_extra']) +
				                          floatval($order_item['quantity']) * floatval($order_item['wiaas_recurrent_extra']);
			}
		}

		$data['recurring_price'] = $total_recurring_price;

		return $data;
	}

	/**
	 * Append order delivery process info if single order is requested
	 * @param $data
	 * @param $order
	 * @param $request
	 *
	 * @return mixed
	 */
	private static function _append_order_process($data, $order, $request) {

		# if this is response to `/order/[id]`
		if (isset($request['id'])) {
			$data['delivery-process'] = Wiaas_Delivery_Process::get_order_delivery_process($order->get_id());
		}

		return $data;
	}

    /** Append order comments if single order is requested
     * @param $data
     * @param $order
     * @param $request
     */
	private static function _append_order_comments($data, $order, $request) {

        if (isset($request['id'])) {
            $current_user = wp_get_current_user();

            $comments = $order->get_customer_order_notes();

            $data['comments'] = array();

            foreach ($comments as $comment) {
                $data['comments'][] = array(
                    'id' => $comment->comment_ID,
                    'content' => $comment->comment_content,
                    'username' => $comment->comment_author,
                    'date' => $comment->comment_date,
                    'is_owner' => $comment->comment_author === $current_user->display_name,
                );
            }
        }

	    return $data;
	}
	
	/** Append downloadable documents from order products if single order is requested
     * @param $data
     * @param $order
     * @param $request
     */
	private static function _append_documents($data, $order, $request) {

		// Go trough available line items and append documents for wiaas standard packages line items
		foreach ($data['line_items'] as $index => $product_line) {
			$order_item = $order->get_item($product_line['id']);

			if (wiaas_is_order_item__standard_package($order_item)) {
				$documents = wiaas_get_standard_package_order_item_documents($order, $product_line['id']);
				$data['line_items'][$index] ['documents'] = $documents;
			}

		}

	    return $data;
    }
}

Wiaas_Order::init();
