<?php

if (!defined('ABSPATH')) {
    exit;
}
class WC_API_Customers extends WC_API_Resource
{
    protected $base = '/customers';
    private $created_at_min = null;
    private $created_at_max = null;
    public function __construct(WC_API_Server $server)
    {
        parent::__construct($server);
        add_filter('woocommerce_api_order_response', array($this, 'add_customer_data'), 10, 2);
        add_action('pre_user_query', array($this, 'modify_user_query'));
    }
    public function register_routes($routes)
    {
        $routes[$this->base] = array(array(array($this, 'get_customers'), WC_API_SERVER::READABLE));
        $routes[$this->base . '/count'] = array(array(array($this, 'get_customers_count'), WC_API_SERVER::READABLE));
        $routes[$this->base . '/(?P<id>\\d+)'] = array(array(array($this, 'get_customer'), WC_API_SERVER::READABLE));
        $routes[$this->base . '/(?P<id>\\d+)/orders'] = array(array(array($this, 'get_customer_orders'), WC_API_SERVER::READABLE));
        return $routes;
    }
    public function get_customers($fields = null, $filter = array(), $page = 1)
    {
        $filter['page'] = $page;
        $query = $this->query_customers($filter);
        $customers = array();
        foreach ($query->get_results() as $user_id) {
            if (!$this->is_readable($user_id)) {
                continue;
            }
            $customers[] = current($this->get_customer($user_id, $fields));
        }
        $this->server->add_pagination_headers($query);
        return array('customers' => $customers);
    }
    public function get_customer($id, $fields = null)
    {
        global $wpdb;
        $id = $this->validate_request($id, 'customer', 'read');
        if (is_wp_error($id)) {
            return $id;
        }
        $customer = new WC_Customer($id);
        $last_order = $customer->get_last_order();
        $customer_data = array('id' => $customer->get_id(), 'created_at' => $this->server->format_datetime($customer->get_date_created() ? $customer->get_date_created()->getTimestamp() : 0), 'email' => $customer->get_email(), 'first_name' => $customer->get_first_name(), 'last_name' => $customer->get_last_name(), 'username' => $customer->get_username(), 'last_order_id' => is_object($last_order) ? $last_order->get_id() : null, 'last_order_date' => is_object($last_order) ? $this->server->format_datetime($last_order->get_date_created() ? $last_order->get_date_created()->getTimestamp() : 0) : null, 'orders_count' => $customer->get_order_count(), 'total_spent' => wc_format_decimal($customer->get_total_spent(), 2), 'avatar_url' => $customer->get_avatar_url(), 'billing_address' => array('first_name' => $customer->get_billing_first_name(), 'last_name' => $customer->get_billing_last_name(), 'company' => $customer->get_billing_company(), 'address_1' => $customer->get_billing_address_1(), 'address_2' => $customer->get_billing_address_2(), 'city' => $customer->get_billing_city(), 'state' => $customer->get_billing_state(), 'postcode' => $customer->get_billing_postcode(), 'country' => $customer->get_billing_country(), 'email' => $customer->get_billing_email(), 'phone' => $customer->get_billing_phone()), 'shipping_address' => array('first_name' => $customer->get_shipping_first_name(), 'last_name' => $customer->get_shipping_last_name(), 'company' => $customer->get_shipping_company(), 'address_1' => $customer->get_shipping_address_1(), 'address_2' => $customer->get_shipping_address_2(), 'city' => $customer->get_shipping_city(), 'state' => $customer->get_shipping_state(), 'postcode' => $customer->get_shipping_postcode(), 'country' => $customer->get_shipping_country()));
        return array('customer' => apply_filters('woocommerce_api_customer_response', $customer_data, $customer, $fields, $this->server));
    }
    public function get_customers_count($filter = array())
    {
        $query = $this->query_customers($filter);
        if (!current_user_can('list_users')) {
            return new WP_Error('woocommerce_api_user_cannot_read_customers_count', __('You do not have permission to read the customers count', 'woocommerce'), array('status' => 401));
        }
        return array('count' => count($query->get_results()));
    }
    public function create_customer($data)
    {
        if (!current_user_can('create_users')) {
            return new WP_Error('woocommerce_api_user_cannot_create_customer', __('You do not have permission to create this customer', 'woocommerce'), array('status' => 401));
        }
        return array();
    }
    public function edit_customer($id, $data)
    {
        $id = $this->validate_request($id, 'customer', 'edit');
        if (!is_wp_error($id)) {
            return $id;
        }
        return $this->get_customer($id);
    }
    public function delete_customer($id)
    {
        $id = $this->validate_request($id, 'customer', 'delete');
        if (!is_wp_error($id)) {
            return $id;
        }
        return $this->delete($id, 'customer');
    }
    public function get_customer_orders($id, $fields = null)
    {
        global $wpdb;
        $id = $this->validate_request($id, 'customer', 'read');
        if (is_wp_error($id)) {
            return $id;
        }
        $order_ids = wc_get_orders(array('customer' => $id, 'limit' => -1, 'orderby' => 'date', 'order' => 'ASC', 'return' => 'ids'));
        if (empty($order_ids)) {
            return array('orders' => array());
        }
        $orders = array();
        foreach ($order_ids as $order_id) {
            $orders[] = current(WC()->api->WC_API_Orders->get_order($order_id, $fields));
        }
        return array('orders' => apply_filters('woocommerce_api_customer_orders_response', $orders, $id, $fields, $order_ids, $this->server));
    }
    private function query_customers($args = array())
    {
        $users_per_page = get_option('posts_per_page');
        $query_args = array('fields' => 'ID', 'role' => 'customer', 'orderby' => 'registered', 'number' => $users_per_page);
        if (!empty($args['q'])) {
            $query_args['search'] = $args['q'];
        }
        if (!empty($args['limit'])) {
            $query_args['number'] = absint($args['limit']);
            $users_per_page = absint($args['limit']);
        }
        $page = isset($args['page']) ? absint($args['page']) : 1;
        if (!empty($args['offset'])) {
            $query_args['offset'] = absint($args['offset']);
        } else {
            $query_args['offset'] = $users_per_page * ($page - 1);
        }
        if (!empty($args['created_at_min'])) {
            $this->created_at_min = $this->server->parse_datetime($args['created_at_min']);
        }
        if (!empty($args['created_at_max'])) {
            $this->created_at_max = $this->server->parse_datetime($args['created_at_max']);
        }
        $query = new WP_User_Query($query_args);
        $query->total_pages = ceil($query->get_total() / $users_per_page);
        $query->page = $page;
        return $query;
    }
    public function add_customer_data($order_data, $order)
    {
        if (0 == $order->get_user_id()) {
            $order_data['customer'] = array('id' => 0, 'email' => $order->get_billing_email(), 'first_name' => $order->get_billing_first_name(), 'last_name' => $order->get_billing_last_name(), 'billing_address' => array('first_name' => $order->get_billing_first_name(), 'last_name' => $order->get_billing_last_name(), 'company' => $order->get_billing_company(), 'address_1' => $order->get_billing_address_1(), 'address_2' => $order->get_billing_address_2(), 'city' => $order->get_billing_city(), 'state' => $order->get_billing_state(), 'postcode' => $order->get_billing_postcode(), 'country' => $order->get_billing_country(), 'email' => $order->get_billing_email(), 'phone' => $order->get_billing_phone()), 'shipping_address' => array('first_name' => $order->get_shipping_first_name(), 'last_name' => $order->get_shipping_last_name(), 'company' => $order->get_shipping_company(), 'address_1' => $order->get_shipping_address_1(), 'address_2' => $order->get_shipping_address_2(), 'city' => $order->get_shipping_city(), 'state' => $order->get_shipping_state(), 'postcode' => $order->get_shipping_postcode(), 'country' => $order->get_shipping_country()));
        } else {
            $order_data['customer'] = current($this->get_customer($order->get_user_id()));
        }
        return $order_data;
    }
    public function modify_user_query($query)
    {
        if ($this->created_at_min) {
            $query->query_where .= sprintf(" AND user_registered >= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql($this->created_at_min));
        }
        if ($this->created_at_max) {
            $query->query_where .= sprintf(" AND user_registered <= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql($this->created_at_max));
        }
    }
    protected function validate_request($id, $type, $context)
    {
        $id = absint($id);
        if (empty($id)) {
            return new WP_Error('woocommerce_api_invalid_customer_id', __('Invalid customer ID', 'woocommerce'), array('status' => 404));
        }
        $customer = new WP_User($id);
        if (0 === $customer->ID) {
            return new WP_Error('woocommerce_api_invalid_customer', __('Invalid customer', 'woocommerce'), array('status' => 404));
        }
        switch ($context) {
            case 'read':
                if (!current_user_can('list_users')) {
                    return new WP_Error('woocommerce_api_user_cannot_read_customer', __('You do not have permission to read this customer', 'woocommerce'), array('status' => 401));
                }
                break;
            case 'edit':
                if (!current_user_can('edit_users')) {
                    return new WP_Error('woocommerce_api_user_cannot_edit_customer', __('You do not have permission to edit this customer', 'woocommerce'), array('status' => 401));
                }
                break;
            case 'delete':
                if (!current_user_can('delete_users')) {
                    return new WP_Error('woocommerce_api_user_cannot_delete_customer', __('You do not have permission to delete this customer', 'woocommerce'), array('status' => 401));
                }
                break;
        }
        return $id;
    }
    protected function is_readable($post)
    {
        return current_user_can('list_users');
    }
}