<?php
/**
 * Walmart Class
 *
 * @package     WP Content Pilot Pro
 * @subpackage  Feed
 * @copyright   Copyright (c) 2019, MD Sultan Nasir Uddin(manikdrmc@gmail.com)
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       1.1.0
 */

defined( 'ABSPATH' ) || exit();

class WPCP_Walmart extends WPCP_Module {
    /**
     * The single instance of the class
     *
     * @var $this ;
     */
    protected static $_instance = null;

    /**
     * WPCP_Walmart constructor.
     */
    public function __construct() {
        //fields
        add_action( 'wpcp_walmart_campaign_options_meta_fields', 'wpcp_keyword_suggestion_field' );
        add_action( 'wpcp_walmart_campaign_options_meta_fields', 'wpcp_keyword_field' );
        parent::__construct( 'walmart' );
    }

    /**
     * @return string
     */
    public function get_module_icon() {
        return '';
    }

    /**
     * @return array
     * @since 1.1.0
     */
    public function get_template_tags() {
        return array(
            'title'                     => __( 'Title', 'wp-content-pilot-pro' ),
            'content'                   => __( 'Content', 'wp-content-pilot-pro' ),
            'image_url'                 => __( 'Main image url', 'wp-content-pilot-pro' ),
            'source_url'                => __( 'Source link', 'wp-content-pilot-pro' ),
            'sale_price'                => __( 'Sale price', 'wp-content-pilot-pro' ),
            'msrp_price'                => __( 'MSRP price', 'wp-content-pilot-pro' ),
            'upc'                       => '',
            'categories'                => __( 'Categories', 'wp-content-pilot-pro' ),
            'brand_name'                => __( 'Brand name', 'wp-content-pilot-pro' ),
            'product_tracking_url'      => __( 'Product tracking URL', 'wp-content-pilot-pro' ),
            'color'                     => __( 'Color', 'wp-content-pilot-pro' ),
            'model_number'              => __( 'Model number', 'wp-content-pilot-pro' ),
            'product_url'               => __( 'Product URL', 'wp-content-pilot-pro' ),
            'customer_rating'           => __( 'Customer rating', 'wp-content-pilot-pro' ),
            'num_reviews'               => __( 'Number of reviews', 'wp-content-pilot-pro' ),
            'customer_rating_image'     => __( 'Customer rating image', 'wp-content-pilot-pro' ),
            'stock'                     => __( 'Stock', 'wp-content-pilot-pro' ),
            'add_to_cart_url'           => __( 'Add to cart URL', 'wp-content-pilot-pro' ),
            'affiliate_add_to_cart_url' => __( 'Affiliate add to cart URL', 'wp-content-pilot-pro' ),
            'offer_type'                => __( 'Offer Type', 'wp-content-pilot-pro' ),
        );
    }

    /**
     * @return string
     * @since 1.1.0
     */
    public function get_default_template() {
        $template
            = <<<EOT
<img src="{image_url}" alt=""><br>
<strong>Price:</strong> {sale_price}<br>
<a href="{product_url}"><img src="https://i.imgur.com/SUv4PIl.png"></a>
{content}
<br> <a href="{source_url}" target="_blank">Source</a>
EOT;

        return $template;
    }

    /**
     * @param $post
     *
     * @since 1.1.7
     */
    public function add_campaign_option_fields( $post ) {
        echo WPCP_HTML::text_input(
            array(
                'name'  => '_walmart_category',
                'label' => __( 'Category', 'wp-content-pilot-pro' ),
                'desc'  => __( 'Ex add "91083_1074767_4623199" without quotes for "Auto Paint" Category. Check list of IDs <a target="_blank" href="http://pastebin.com/56JC4xrB">here</a>', 'wp-content-pilot-pro' )
            )
        );
        echo WPCP_HTML::start_double_columns();

        echo WPCP_HTML::select_input(
            array(
                'name'    => '_walmart_sort_order',
                'label'   => __( 'Sort Order', 'wp-content-pilot-pro' ),
                'options' => array(
                    'relevance'      => __( 'Relevance', 'wp-content-pilot-pro' ),
                    'price'          => __( 'Price', 'wp-content-pilot-pro' ),
                    'title'          => __( 'Title', 'wp-content-pilot-pro' ),
                    'bestseller'     => __( 'Best Seller', 'wp-content-pilot-pro' ),
                    'customerRating' => __( 'Customer Rating', 'wp-content-pilot-pro' ),
                    'New'            => __( 'New', 'wp-content-pilot-pro' ),
                ),
                'default' => 'relevance',
                'class'   => 'wpcp-select',
            )
        );
        echo WPCP_HTML::select_input(
            array(
                'name'    => '_walmart_sort_direction',
                'label'   => __( 'Sort direction', 'wp-content-pilot-pro' ),
                'options' => array(
                    'asc'  => __( 'Asc', 'wp-content-pilot-pro' ),
                    'desc' => __( 'Desc', 'wp-content-pilot-pro' ),
                ),
                'default' => 'asc',
                'class'   => 'wpcp-select',
                'tooltip'    => __( 'work if the sort order is price or title or customer rating', 'wp-content-pilot-pro' )
            )
        );
        echo WPCP_HTML::end_double_columns();
    }

    /**
     * @param $campaign_id
     * @param $posted
     *
     * @since 1.1.7
     */
    public function save_campaign_meta( $campaign_id, $posted ) {
        update_post_meta( $campaign_id, '_walmart_category', empty( $posted['_walmart_category'] ) ? '' : sanitize_text_field( $posted['_walmart_category'] ) );
        update_post_meta( $campaign_id, '_walmart_sort_order', empty( $posted['_walmart_sort_order'] ) ? 'relevance' : sanitize_key( $posted['_walmart_sort_order'] ) );
        update_post_meta( $campaign_id, '_walmart_sort_direction', empty( $posted['_walmart_sort_direction'] ) ? 'asc' : sanitize_key( $posted['_walmart_sort_direction'] ) );
    }

    /**
     * @param $sections
     *
     * @return array
     * @since 1.1.0
     */
    public function get_setting_section( $sections ) {
        $sections[] = [
            'id'    => 'wpcp_settings_walmart',
            'title' => __( 'Walmart Settings', 'wp-content-pilot-pro' )
        ];

        return $sections;
    }

    /**
     * @param $fields
     *
     * @return array
     * @since 1.1.0
     */
    public function get_setting_fields( $fields ) {
        $fields['wpcp_settings_walmart'] = array(
            array(
                'name'    => 'api_key',
                'label'   => __( 'API Key', 'wp-content-pilot-pro' ),
                'desc'    => sprintf( __( 'Follow <a href="%s" target="_blank">this guide</a> to create Walmart API key.', 'wp-content-pilot-pro' ), 'https://www.pluginever.com/docs/wp-content-pilot/walmart-campaign-settings/' ),
                'type'    => 'password',
                'default' => ''
            ),
            array(
                'name'  => 'pid',
                'label' => __( 'Publisher ID', 'wp-content-pilot-pro' ),
                'desc'  => sprintf( __( 'Follow <a href="%s" target="_blank">this guide</a> to get your Walmart publisher ID.', 'wp-content-pilot-pro' ), 'https://www.pluginever.com/docs/wp-content-pilot/walmart-campaign-settings/' ),
                'type'  => 'password',
            ),
        );

        return $fields;
    }

    /**
     * @param $campaign_id
     *
     * @return mixed|void
     * @since 1.2.0
     */
    public function get_post( $campaign_id ) {
        wpcp_logger()->info( __( 'Loaded Walmart Campaign', 'wp-content-pilot-pro' ), $campaign_id );

        $api_key = wpcp_get_settings( 'api_key', 'wpcp_settings_walmart' );
        $pid     = wpcp_get_settings( 'pid', 'wpcp_settings_walmart' );

        wpcp_logger()->info( __( 'Checking walmart api key and publisher id  for authentication', 'wp-content-pilot-pro' ), $campaign_id );
        if ( empty( $api_key ) || empty($pid) ) {
            wpcp_disable_campaign( $campaign_id );

            $notice = __( 'Walmart api key or Published ID is not set.So, the campaign won\'t run, disabling campaign.', 'wp-content-pilot-pro' );
            wpcp_logger()->error( $notice );

            return new WP_Error( 'missing-data', $notice );
        }

        $keywords = $this->get_campaign_meta( $campaign_id );
        if ( empty( $keywords ) ) {
            return new WP_Error( 'missing-data', __( 'Campaign do not have keyword to proceed, please set keyword', 'wp-content-pilot-pro' ) );
        }

        //loop through keywords
        foreach ( $keywords as $keyword ) {
            wpcp_logger()->info( sprintf( __( 'Looping through keywords [ %s ]', 'wp-content-pilot-pro' ), $keyword ), $campaign_id );

            if ( $this->is_deactivated_key( $campaign_id, $keyword ) ) {
                wpcp_logger()->error( sprintf( __( 'The keyword is deactivated for 1 hr because last time could not find any article with keyword [%s]', 'wp-content-pilot-pro' ), $keyword ), $campaign_id );
                continue;
            }

            //get links from database
            wpcp_logger()->info( __( 'Checking existing links in store...', 'wp-content-pilot-pro' ), $campaign_id );
            $links = $this->get_links( $keyword, $campaign_id );
            if ( empty( $links ) ) {
                wpcp_logger()->info( __( 'No generated links in store. Generating new links...', 'wp-content-pilot-pro' ), $campaign_id );
                $this->discover_links( $campaign_id, $keyword );
                $links = $this->get_links( $keyword, $campaign_id );
            }

            foreach ( $links as $link ) {
                wpcp_logger()->info( sprintf( __( 'Grabbing article from [%s]', 'wp-content-pilot-pro' ), $link->url ), $campaign_id );

                $content = @$link->meta['longDescription'] . '<br/>';
                $content .= @$link->meta['shortDescription'] . '<br/>';

                //check clean title and perform title cleaning when checked
                $check_clean_title = wpcp_get_post_meta( $campaign_id, '_clean_title', 'off' );

                if ( 'on' == $check_clean_title ) {
                    wpcp_logger()->info( __( 'Cleaning title', 'wp-content-pilot-pro' ), $campaign_id );
                    $title = wpcp_clean_title( $link->title );
                } else {
                    $title = html_entity_decode( $link->title, ENT_QUOTES );
                }

                wpcp_logger()->info( __( 'Combining all parts for article', 'wp-content-pilot-pro' ), $campaign_id );
                $article = [
                    'title'                     => $title,
                    'content'                   => $content,
                    'image_url'                 => @$link->meta['image_url'],
                    'source_url'                => $link->url,
                    'msrp_price'                => @$link->meta['msrp_price'],
                    'sale_price'                => @$link->meta['sale_price'],
                    'upc'                       => @$link->meta['upc'],
                    'categories'                => @$link->meta['categories'],
                    'brand_name'                => @$link->meta['brand_name'],
                    'product_tracking_url'      => @$link->meta['product_tracking_url'],
                    'color'                     => @$link->meta['color'],
                    'model_number'              => @$link->meta['model_number'],
                    'product_url'               => @$link->meta['product_url'],
                    'customer_rating'           => @$link->meta['customer_rating'],
                    'num_reviews'               => @$link->meta['num_reviews'],
                    'customer_rating_image'     => @$link->meta['customer_rating_image'],
                    'stock'                     => @$link->meta['stock'],
                    'add_to_cart_url'           => @$link->meta['add_to_cart_url'],
                    'affiliate_add_to_cart_url' => @$link->meta['affiliate_add_to_cart_url'],
                    'offer_type'                => @$link->meta['offer_type'],
                    'longDescription'           => @$link->meta['longDescription'],
                    'shortDescription'          => @$link->meta['shortDescription'],
                ];
                $this->update_link( $link->id, [ 'status' => 'success', 'meta' => '' ] );

                return $article;
            }


        }
        $log_url = admin_url( '/edit.php?post_type=wp_content_pilot&page=wpcp-logs' );

        return new WP_Error( 'campaign-error', __( sprintf( 'No article generated check <a href="%s">log</a> for details.', $log_url ), 'wp-content-pilot-pro' ) );
    }

    /**
     * @param $campaign_id
     * @param $keyword
     *
     * @return array|bool|int|WP_Error
     * @since 1.2.0
     */
    protected function discover_links( $campaign_id, $keyword ) {
        $page_key       = sanitize_key( '_page_' . $campaign_id . '_' . md5( $keyword ) );
        $page_number    = wpcp_get_post_meta( $campaign_id, $page_key, '1' );
        $api_key        = wpcp_get_settings( 'api_key', 'wpcp_settings_walmart' );
        $pid            = wpcp_get_settings( 'pid', 'wpcp_settings_walmart' );
        $total_page_key = $this->get_unique_key( 'total_page_' . $keyword );
        $total_page     = wpcp_get_post_meta( $campaign_id, $total_page_key, 999999999 );

        //category, sort and price filters
        $category_id    = wpcp_get_post_meta( $campaign_id, '_walmart_category', '' );
        $sort_order     = wpcp_get_post_meta( $campaign_id, '_walmart_sort_order', 'relevance' );
        $sort_direction = wpcp_get_post_meta( $campaign_id, '_walmart_sort_direction', 'asc' );
        $min_price      = wpcp_get_post_meta( $campaign_id, '_min_price', '' );
        $max_price      = wpcp_get_post_meta( $campaign_id, '_max_price', '' );

        if ( $page_number > $total_page && ! empty( $total_page ) ) {
            $msg = sprintf( __( 'Maximum page number reached for the keyword [%s] deactivating campaign', 'wp-content-pilot-pro' ), $keyword );
            wpcp_logger()->warning( $msg, $campaign_id );
            wpcp_disable_campaign( $this->campaign_id );

            return false;
        }

        $api_url    = 'http://api.walmartlabs.com/v1/search';
        $query_args = array(
            'query'         => $keyword,
            'apiKey'        => $api_key,
            'publisherId'   => $pid,
            'sort'          => $sort_order,
            'responseGroup' => 'full',
            'pageSize'      => 10,
            'start'         => $page_number,
            //'format'        => 'json',
        );

        /**
         * added extra search parameters for searching
         * @since 1.1.7
         */
        if ( $category_id != '' ) {
            $query_args['categoryId'] = $category_id;
        }

        if ( $sort_order == 'price' || $sort_order == 'title' || $sort_order == 'customerRating' ) {
            $query_args['order'] = $sort_direction;
        }

//        if ( $min_price != '' && $max_price != '' && is_numeric( $min_price ) && is_numeric( $max_price ) ) {
//            $query_args['facet']       = 'on';
//            $query_args['facet.range'] = "price:[$min_price TO $max_price]";
//        }

        $endpoint = add_query_arg( $query_args, $api_url );
        $curl     = $this->setup_curl();
        $curl->get( $endpoint );
        wpcp_logger()->info( sprintf( __( "Searching for links [%s]", 'wp-content-pilot-pro' ), preg_replace( '/apiKey=([^&]+)/m', 'apiKey=X', $endpoint ) ), $campaign_id );

        $response = $curl->getResponse();

        if ( $curl->isError() ) {
            wpcp_logger()->error( $curl->errorMessage, $campaign_id );
            $this->deactivate_key( $campaign_id, $keyword );
            wpcp_update_post_meta( $campaign_id, $page_key, $page_number + 1 );

            return false;
        }

        if ( empty( $response->items ) || ! is_array( $response->items ) ) {
            $message = __( 'Could not find any links from walmart, deactivating keyword for an hour.', 'wp-content-pilot-pro' );
            wpcp_logger()->error( $message, $campaign_id );
            $this->deactivate_key( $campaign_id, $keyword );

            return false;
        }

        wpcp_logger()->info( __( "Updating total page count", 'wp-content-pilot-pro' ), $campaign_id );
        if ( empty( $total_page ) ) {
            $total_page = ( $response->totalResults / 10 );
            update_post_meta( $campaign_id, $total_page_key, $total_page );
        }


        $items    = $response->items;
        $inserted = 0;
        wpcp_logger()->info( __( 'Looping through links for storing..', 'wp-content-pilot-pro' ), $campaign_id );
        foreach ( $items as $item ) {
            $url   = esc_url_raw( $item->productUrl );
            $title = remove_accents( $item->name );


            if ( wpcp_is_duplicate_url( $url ) ) {
                continue;
            }

            $skip = apply_filters( 'wpcp_skip_duplicate_title', true, $title, $campaign_id );
            if ( $skip ) {
                continue;
            }

            $categories = explode( '/', $item->categoryPath );
            $categories = wpcp_array_to_html( $categories );

            $meta = [
                'msrp_price'                => wpcp_price( $item->msrp ),
                'sale_price'                => wpcp_price( $item->salePrice ),
                'upc'                       => @$item->upc,
                'categories'                => $categories,
                'brand_name'                => @$item->brandName,
                'product_tracking_url'      => @$item->productTrackingUrl,
                'color'                     => @$item->color,
                'model_number'              => @$item->modelNumber,
                'product_url'               => @$item->productUrl,
                'customer_rating'           => @$item->customerRating,
                'num_reviews'               => @$item->numReviews,
                'customer_rating_image'     => @$item->customerRatingImage,
                'stock'                     => @$item->stock,
                'add_to_cart_url'           => @$item->addToCartUrl,
                'affiliate_add_to_cart_url' => @$item->affiliateAddToCartUrl,
                'offer_type'                => @$item->offerType,
                'longDescription'           => @$item->longDescription,
                'shortDescription'          => @$item->shortDescription,
                'image_url'                 => @$item->largeImage
            ];


            $data = array(
                'url'     => $url,
                'title'   => $title,
                'for'     => $keyword,
                'camp_id' => $campaign_id,
                'meta'    => $meta,
            );

            if ( false !== $this->insert_link( $data ) ) {
                $inserted += 1;
            }
        }

        wpcp_update_post_meta( $campaign_id, $page_key, $page_number + 1 );
        wpcp_logger()->info( sprintf( __( 'Total found links [%d] and accepted [%d] and rejected [%d]', 'wp-content-pilot-pro' ), count( $items ), $inserted, ( count( $items ) - $inserted ) ), $campaign_id );

        return true;
    }

    /**
     * Main WPCP_Walmart Instance.
     *
     * Ensures only one instance of WPCP_Walmart is loaded or can be loaded.
     *
     * @return WPCP_Walmart Main instance
     * @since 1.1.0
     * @static
     */
    public static function instance() {
        if ( is_null( self::$_instance ) ) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

}

WPCP_Walmart::instance();
