<?php
// don't call the file directly
defined( 'ABSPATH' ) || exit();

class WPCP_Yelp extends WPCP_Module {

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

    /**
     * WPCP_Module constructor.
     * @since 1.1.7
     */
    public function __construct() {
        //option fields
        add_action( 'wpcp_yelp_campaign_options_meta_fields', 'wpcp_keyword_suggestion_field' );
        add_action( 'wpcp_yelp_campaign_options_meta_fields', 'wpcp_keyword_field' );
        parent::__construct( 'yelp' );
    }

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

    /**
     * @return array
     * @since 1.1.7
     */
    public function get_template_tags() {
        return array(
            'title'        => __( 'Title', 'wp-content-pilot-pro' ),
            'image_url'    => __( 'Main image url', 'wp-content-pilot-pro' ),
            'source_url'   => __( 'Source link', 'wp-content-pilot-pro' ),
            'open_time'    => __( 'Opening Time', 'wp-content-pilot-pro' ),
            'category'     => __( 'Category', 'wp-content-pilot-pro' ),
            'reviews'      => __( 'Reviews', 'wp-content-pilot-pro' ),
            'ratings'      => __( 'Ratings', 'wp-content-pilot-pro' ),
            'location'     => __( 'Location', 'wp-content-pilot-pro' ),
            'phone'        => __( 'Phone', 'wp-content-pilot-pro' ),
            'total_review' => __( 'Total Review', 'wp-content-pilot-pro' ),
        );
    }

    /**
     * @return string
     * @since 1.1.7
     */
    public function get_default_template() {
        $template =
            <<<EOT
<img src="{image_url}">
{ratings}<br>
{total_review}<br>
{location}<br>
{phone}
<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::textarea_input( array(
            'name'        => '_yelp_location',
            'label'       => __( 'Location', 'wp-content-pilot-pro' ),
            'size'        => 'regular',
            'attrs'       => array(
                'required' => "required"
            ),
            'placeholder' => __( 'Enter address here', 'wp-content-pilot-pro' ),
            'desc'        => __( 'Example "New York City", "NYC", "350 5th Ave, New York, NY 10118"', 'wp-content-pilot-pro' ),
        ) );

        echo WPCP_HTML::start_double_columns();

        echo WPCP_HTML::select_input( array(
            'name'    => '_yelp_category',
            'label'   => __( 'Yelp Category', 'wp-content-pilot-pro' ),
            'options' => $this->get_help_category(),
            'class'   => 'wpcp-select2',
            'default' => 'All',
            'tooltip' => __( 'Select Category for searching businesses', 'wp-content-pilot-pro' ),
        ) );

        echo WPCP_HTML::select_input( array(
            'name'    => '_yelp_locale',
            'label'   => __( 'Yelp Locale', 'wp-content-pilot-pro' ),
            'options' => $this->get_yelp_locale(),
            'default' => 'en_US',
            'class'   => 'wpcp-select2',
            'tooltip' => __( 'Select locale. Value Type: Country-Name - Language', '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, '_yelp_location', empty( $posted['_yelp_location'] ) ? '' : sanitize_textarea_field( $posted['_yelp_location'] ) );
        update_post_meta( $campaign_id, '_yelp_locale', empty( $posted['_yelp_locale'] ) ? '' : $posted['_yelp_locale'] );
        update_post_meta( $campaign_id, '_yelp_category', empty( $posted['_yelp_category'] ) ? '' : $posted['_yelp_category'] );
    }

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

        return $sections;
    }

    /**
     * @param $fields
     *
     * @return array
     * @since 1.1.7
     */
    public function get_setting_fields( $fields ) {
        $fields['wpcp_settings_yelp'] = [
            array(
                'name'  => 'yelp_api',
                'label' => __( 'Api Key', 'wp-content-pilot-pro' ),
                'desc'  => sprintf( __( '<a href="%s" target="_blank">Here</a> is the guide to get your Yelp API key.', 'wp-content-pilot-pro' ), 'https://pluginever.com/docs/wp-content-pilot/yelp-campaign-settings/' ),
                'type'  => 'password',
            ),
        ];

        return $fields;
    }


    /**
     * @param int $campaign_id
     *
     * @return array|mixed|WP_Error
     * @throws ErrorException
     * @since 1.1.7
     */
    public function get_post( $campaign_id ) {
        wpcp_logger()->info( __( 'Loaded Yelp Campaign', 'wp-content-pilot-pro' ), $campaign_id );

        $api_key = wpcp_get_settings( 'yelp_api', 'wpcp_settings_yelp' );

        wpcp_logger()->info( __( 'Checking yelp api key for authentication', 'wp-content-pilot-pro' ), $campaign_id );
        if ( empty( $api_key ) ) {
            wpcp_disable_campaign( $campaign_id );

            $notice = __( 'Yelp api key is not set.So, the campaign wont run, disabling campaign.', 'wp-content-pilot-pro' );
            wpcp_logger()->error( $notice, $campaign_id );

            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' ) );
        }
        wpcp_logger()->info( 'Article Campaign Started', $campaign_id );

        //loop through keywords
        foreach ( $keywords as $keyword ) {
            wpcp_logger()->info( sprintf( __( 'Looping through keywords now trying with keyword [ %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 cached 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 );

                $this->update_link( $link->id, [ 'status' => 'failed', 'meta' => '' ] );

                $meta         = $link->meta;
                $business_url = sprintf( 'https://api.yelp.com/v3/businesses/%1s', $meta['id'] );
                $curl         = $this->setup_curl();
                $header_value = 'Bearer ' . $api_key;
                $curl->setHeader( 'Authorization', $header_value );
                $curl->get( $business_url );

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

                if ( $curl->isError() && $this->initiator != 'cron' ) {
                    wpcp_logger()->error( sprintf( __( "Failed processing business link reason [%s]", 'wp-content-pilot-pro' ), $curl->getErrorMessage() ), $campaign_id );
                    continue;
                }
                $response     = $curl->getResponse();
                $opening_hour = $response->hours[0]->open;

                wpcp_logger()->info( sprintf( __( 'Requesting reviews from links [%s]', 'wp-content-pilot-pro' ), $link->url ), $campaign_id );
                $review_url   = sprintf( 'https://api.yelp.com/v3/businesses/%1s/reviews', $meta['id'] );
                $curl         = $this->setup_curl();
                $header_value = 'Bearer ' . $api_key;
                $curl->setHeader( 'Authorization', $header_value );
                $curl->get( $review_url );

                if ( $curl->isError() && $this->initiator != 'cron' ) {
                    wpcp_logger()->error( sprintf( __( "Failed processing review link reason [%s]", "wp-content-pilot-pro" ), $curl->getErrorMessage() ), $campaign_id );
                    continue;
                }
                $response = $curl->getResponse();
                $reviews  = $response->reviews;


                $opening_time  = '';
                $content       = '';
                $category      = array();
                $review        = '';
                $ratings       = '';
                $total_reviews = '';
                $location      = '';
                $phone_number  = '';


                $ratings .= ! empty( $meta['ratings'] ) ? $meta['ratings'] : '';
                $ratings .= __( ' Out of 5', 'wp-content-pilot-pro' ) . '<br/>';

                $total_reviews .= ! empty( $meta['review_count'] ) ? $meta['review_count'] : '';
                $location      .= ! empty( $meta['address'] ) ? implode( " , ", $meta['address'] ) : '';
                $phone_number  .= ! empty( $meta['display_phone'] ) ? $meta['display_phone'] : '';

                foreach ( $opening_hour as $hour ) {
                    $day = '';
                    switch ( $hour->day ) {
                        case 0:
                            $day = 'Sunday';
                            break;
                        case 1:
                            $day = 'Monday';
                            break;
                        case 2:
                            $day = 'Tuesday';
                            break;
                        case 3:
                            $day = 'Wednesday';
                            break;
                        case 4:
                            $day = 'Thursday';
                            break;
                        case 5:
                            $day = 'Friday';
                            break;
                        case 6:
                            $day = 'Saturday';
                            break;
                    }
                    $opening_time .= $day;
                    $opening_time .= " From " . date( "g:i a", strtotime( $hour->start ) );
                    $opening_time .= " To " . date( "g:i a", strtotime( $hour->end ) );
                    $opening_time .= "<br/>";
                }

                $categories = $meta['categories'];
                if ( is_array( $categories ) && count( $categories ) ) {
                    foreach ( $categories as $single ) {
                        $category [] = $single->title;
                    }
                }

                if ( is_array( $reviews ) && count( $reviews ) ) {
                    $review .= 'Top Reviews: ' . '<br/>';
                    foreach ( $reviews as $single ) {
                        $review .= 'Review: ';
                        $review .= ! empty( $single->text ) ? strip_tags( $single->text ) : '';
                        $review .= '<br/>';
                        $review .= 'Ratings: ';
                        $review .= ! empty( $single->rating ) ? $single->rating : '';
                        $review .= '<br/>';
                        $review .= 'Reviewer: ';
                        $review .= ! empty( $single->user->name ) ? $single->user->name : '';
                        $review .= '<br/>';
                    }

                }

                //check if the clean title metabox is checked and perform title cleaning
                $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 = array(
                    'title'        => $title,
                    'image_url'    => $meta['img_url'],
                    'content'      => $content,
                    'source_url'   => $link->url,
                    'open_time'    => $opening_time,
                    'category'     => ! empty( $category ) ? implode( " , ", $category ) : '',
                    'reviews'      => $review,
                    'ratings'      => $ratings,
                    'location'     => $location,
                    'phone'        => $phone_number,
                    'total_review' => $total_reviews,
                );

                wpcp_logger()->info( __( 'Article processed from campaign', 'wp-content-pilot-pro' ), $campaign_id );
                $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 bool|mixed|WP_Error
     * @throws ErrorException
     * @since 1.1.7
     */
    protected function discover_links( $campaign_id, $keyword ) {
        $api_key     = wpcp_get_settings( 'yelp_api', 'wpcp_settings_yelp' );
        $page_key    = sanitize_key( '_page_' . $campaign_id . '_' . md5( $keyword ) );
        $page_number = wpcp_get_post_meta( $campaign_id, $page_key, '1' );
        $location    = wpcp_get_post_meta( $campaign_id, '_yelp_location' );
        $locale      = wpcp_get_post_meta( $campaign_id, '_yelp_locale', 'en_US' );
        $category    = wpcp_get_post_meta( $campaign_id, '_yelp_category' );

        $api_url    = sprintf( 'https://api.yelp.com/v3/businesses/search' );
        $query_args = array(
            'term'     => $keyword,
            'location' => $location,
            'offset'   => ( $page_number - 1 ) * 20,
            'locale'   => $locale,
        );

        if ( $category != null ) {
            $query_args['categories'] = $category;
        }

        $endpoint = add_query_arg( $query_args, $api_url );

        wpcp_logger()->info( sprintf( __( 'Searching page url [%s]', 'wp-content-pilot-pro' ), $endpoint ), $campaign_id );

        $curl         = $this->setup_curl();
        $header_value = 'Bearer ' . $api_key;
        $curl->setHeader( 'Authorization', $header_value );
        $curl->get( $endpoint );

        if ( $curl->isError() ) {
            $message = sprintf( __( 'Something happened wrong when requesting, response [%s]', 'wp-content-pilot-pro' ), $curl->response->error->description );
            wpcp_logger()->error( $message, $campaign_id );
            $this->deactivate_key( $campaign_id, $keyword );

            return false;
        }

        $response = $curl->getResponse();

        if ( $response->total == 0 ) {
            $message = __( 'Could not find any items, deactivating keyword for an hour. ', 'wp-content-pilot-pro' );
            wpcp_logger()->error( $message, $campaign_id );
            $this->deactivate_key( $campaign_id, $keyword );

            return false;
        }

        $businesses = $response->businesses;

        $counter = 0;
        wpcp_logger()->info( __( 'Looping through links for storing..', 'wp-content-pilot-pro' ), $campaign_id );
        foreach ( $businesses as $business ) {
            $meta                  = [];
            $meta['id']            = $business->id;
            $meta['img_url']       = $business->image_url;
            $meta['ratings']       = $business->rating;
            $meta['review_count']  = $business->review_count;
            $meta['address']       = $business->location->display_address;
            $meta['categories']    = $business->categories;
            $meta['phone']         = $business->phone;
            $meta['display_phone'] = $business->display_phone;

            $title     = $business->name;
            $item_link = $business->url;

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

            //check duplicate title and don't publish the post with duplicate title
            $skip = apply_filters( 'wpcp_skip_duplicate_title', true, $title, $campaign_id );
            if ( $skip ) {
                continue;
            }

            $data = [
                'url'     => esc_url( $item_link ),
                'title'   => $title,
                'for'     => $keyword,
                'camp_id' => $campaign_id,
                'meta'    => $meta,
            ];

            if ( ! false == $this->insert_link( $data ) ) {
                $counter += 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( $businesses ), $counter, ( count( $businesses ) - $counter ) ), $campaign_id );

        return true;
    }

    /**
     * Get all supported local for yelp
     *
     * @return array
     * @since 1.1.7
     *
     */
    public function get_yelp_locale() {
        return array(
            ''       => 'Select Locale',
            'cs_CZ'  => 'Czech Republic - Czech',
            'da_DK'  => 'Denmark - Danish',
            'de_AT'  => 'Austria - German',
            'de_CH'  => 'Switzerland - German',
            'de_DE'  => 'Germany - German',
            'en_AU'  => 'Australia - English',
            'en_BE'  => 'Belgium - English',
            'en_CA'  => 'Canada - English',
            'en_CH'  => 'Switzerland - English',
            'en_GB'  => 'United Kingdom - English',
            'en_HK'  => 'Hong Kong - English',
            'en_IE'  => 'Republic of Ireland - English',
            'en_MY'  => 'Malaysia - English',
            'en_NZ'  => 'New Zealand - English',
            'en_PH'  => 'Philippines - English',
            'en_SG'  => 'Singapore - English',
            'en_US'  => 'United States - English',
            'es_AR'  => 'Argentina - Spanish',
            'es_CL'  => 'Chile - Spanish',
            'es_ES'  => 'Spain - Spanish',
            'es_MX'  => 'Mexico - Spanish',
            'fi_FI'  => 'Finland - Finnish',
            'fil_PH' => 'Philippines - Filipino',
            'fr_BE'  => 'Belgium - French',
            'fr_CA'  => 'Canada - French',
            'fr_CH'  => 'Switzerland - French',
            'fr_FR'  => 'France - French',
            'it_CH'  => 'Switzerland - Italian',
            'it_IT'  => 'Italy - Italian',
            'ja_JP'  => 'Japan - Japanese',
            'ms_MY'  => 'Malaysia - Malay',
            'nb_NO'  => 'Norway - Norwegian',
            'nl_BE'  => 'Belgium - Dutch',
            'nl_NL'  => 'The Netherlands - Dutch',
            'pl_PL'  => 'Poland - Polish',
            'pt_BR'  => 'Brazil - Portuguese',
            'pt_PT'  => 'Portugal - Portuguese',
            'sv_FI'  => 'Finland - Swedish',
            'sv_SE'  => 'Sweden - Swedish',
            'tr_TR'  => 'Turkey - Turkish',
            'zh_HK'  => 'Hong Kong - Chinese',
            'zh_TW'  => 'Taiwan - Chinese',
        );
    }

    /**
     * Get main categories for yelp
     *
     * @return array
     * @since 1.1.7
     *
     */

    public function get_help_category() {
        return array(
            'All'                => __( 'All', 'wp-content-pilot-pro' ),
            'active'             => __( 'Active Life', 'wp-content-pilot-pro' ),
            'arts'               => __( 'Arts & Entertainment', 'wp-content-pilot-pro' ),
            'auto'               => __( 'Automotive', 'wp-content-pilot-pro' ),
            'beautysvc'          => __( 'Beauty & Spas', 'wp-content-pilot-pro' ),
            'bicycles'           => __( 'Bicycles', 'wp-content-pilot-pro' ),
            'education'          => __( 'Education', 'wp-content-pilot-pro' ),
            'eventservices'      => __( 'Event Planning & Services', 'wp-content-pilot-pro' ),
            'financialservices'  => __( 'Financial Services', 'wp-content-pilot-pro' ),
            'food'               => __( 'Food ', 'wp-content-pilot-pro' ),
            'health'             => __( 'Health & Medical', 'wp-content-pilot-pro' ),
            'homeservices'       => __( 'Home Services', 'wp-content-pilot-pro' ),
            'hotelstravel'       => __( 'Hotels & Travel', 'wp-content-pilot-pro' ),
            'localflavor'        => __( 'Local Flavor', 'wp-content-pilot-pro' ),
            'localservices'      => __( 'Local Services', 'wp-content-pilot-pro' ),
            'massmedia'          => __( 'Mass Media', 'wp-content-pilot-pro' ),
            'nightlife'          => __( 'Nightlife', 'wp-content-pilot-pro' ),
            'pets'               => __( 'Pets', 'wp-content-pilot-pro' ),
            'professional'       => __( 'Professional Services', 'wp-content-pilot-pro' ),
            'publicservicesgovt' => __( 'Public Services & Government', 'wp-content-pilot-pro' ),
            'realestate'         => __( 'Real Estate', 'wp-content-pilot-pro' ),
            'religiousorgs'      => __( 'Religious Organizations', 'wp-content-pilot-pro' ),
            'restaurants'        => __( 'Restaurants ', 'wp-content-pilot-pro' ),
            'shopping'           => __( 'Shopping', 'wp-content-pilot-pro' ),
        );
    }


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

        return self::$_instance;
    }
}

WPCP_Yelp::instance();
