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

class WPCP_EventFul extends WPCP_Module {

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

    /**
     * WPCP_Module constructor.
     */
    public function __construct() {
        //option fields
        add_action( 'wpcp_eventful_campaign_options_meta_fields', 'wpcp_keyword_suggestion_field' );
        add_action( 'wpcp_eventful_campaign_options_meta_fields', 'wpcp_keyword_field' );
        parent::__construct( 'eventful' );
    }

    /**
     * @return string
     */
    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' ),
            'content'     => __( 'Content', 'wp-content-pilot-pro' ),
            'image_url'   => __( 'Main image url', 'wp-content-pilot-pro' ),
            'source_url'  => __( 'Source link', 'wp-content-pilot-pro' ),
            'venue'       => __( 'Venue', 'wp-content-pilot-pro' ),
            'venue_url'   => __( 'Venue Url', 'wp-content-pilot-pro' ),
            'tickets'     => __( 'Tickets', 'wp-content-pilot-pro' ),
            'category'    => __( 'Category', 'wp-content-pilot-pro' ),
            'price'       => __( 'Price', 'wp-content-pilot-pro' ),
            'start_time'  => __( 'Start Time', 'wp-content-pilot-pro' ),
            'going_count' => __( 'Going Count', 'wp-content-pilot-pro' ),
            'all_day'     => __( 'All Day', 'wp-content-pilot-pro' ),
        );
    }

    /**
     * @return string
     * @since 1.1.7
     */
    public function get_default_template() {
        $template =
            <<<EOT
<img src="{image_url}">
{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::textarea_input( array(
            'label' => __( 'Event Location', 'wp-content-pilot-pro' ),
            'name'  => '_location',
            'desc'  => __( 'Event Location to filter the search Results. Supported Formats ("San Diego", "San Diego, TX", "London, United Kingdom", and "Calgary, Alberta, Canada"). Also postal codes and common geocoordinate formats ("32.746682, -117.162741") are also accepted', 'wp-content-pilot-pro' )
        ) );

        echo WPCP_HTML::start_double_columns();

        echo WPCP_HTML::select_input( array(
            'label'    => __( 'Event Category', 'wp-content-pilot-pro' ),
            'name'     => '_category',
            'class'    => 'wpcp-select2',
            'options'  => $this->event_categories(),
            'multiple' => true,
            'tooltip'  => __( 'Limit the search results to this category ID', 'wp-content-pilot-pro' ),
        ) );

        echo WPCP_HTML::select_input( array(
            'label'    => __( 'Exclude Category', 'wp-content-pilot-pro' ),
            'name'     => '_ex_category',
            'class'    => 'wpcp-select2',
            'options'  => $this->event_categories(),
            'multiple' => true,
            'tooltip'  => __( 'Exclude search results from including this category ID', 'wp-content-pilot-pro' ),
        ) );

        echo WPCP_HTML::select_input( array(
            'label'   => __( 'Sort Order', 'wp-content-pilot-pro' ),
            'name'    => '_sort_order',
            'class'   => 'wpcp-select',
            'options' => array(
                'popularity' => __( 'Popularity', 'wp-content-pilot-pro' ),
                'date'       => __( 'Date', 'wp-content-pilot-pro' ),
                'relevance'  => __( 'Relevance', 'wp-content-pilot-pro' ),
            ),
            'default' => 'relevance'
        ) );

        echo WPCP_HTML::select_input( array(
            'label'   => __( 'Sort Direction', 'wp-content-pilot-pro' ),
            'name'    => '_sort_direction',
            'class'   => 'wpcp-select',
            'options' => array(
                'ascending'  => __( 'ASC', 'wp-content-pilot-pro' ),
                'descending' => __( 'DESC', '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, '_location', empty( $posted['_location'] ) ? '' : sanitize_textarea_field( $posted['_location'] ) );
        update_post_meta( $campaign_id, '_category', empty( $posted['_category'] ) ? '' : sanitize_key( $posted['_category'] ) );
        update_post_meta( $campaign_id, '_ex_category', empty( $posted['_ex_category'] ) ? '' : sanitize_key( $posted['_ex_category'] ) );
        update_post_meta( $campaign_id, '_sort_order', empty( $posted['_sort_order'] ) ? 'relevance' : sanitize_key( $posted['_sort_order'] ) );
        update_post_meta( $campaign_id, '_sort_direction', empty( $posted['_sort_direction'] ) ? 'ascending' : sanitize_key( $posted['_sort_direction'] ) );
    }

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

        return $sections;
    }

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

        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 Eventful Campaign', 'wp-content-pilot-pro' ), $campaign_id );

        $api_key = wpcp_get_settings( 'eventful_api', 'wpcp_settings_eventful' );

        wpcp_logger()->info( __( 'Checking eventful api key for authentication', 'wp-content-pilot-pro' ), $campaign_id );
        if ( empty( $api_key ) ) {
            wpcp_disable_campaign( $campaign_id );
            $notice = __( 'Eventful api key is not set.So, the campaign won\'t 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( 'Eventful 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;

                if ( is_array( $meta['description'] ) ) {
                    $content = ! empty( $meta['description'][0] ) ? $meta['description'][0] : '';
                } else {
                    $content = ! empty( $meta['description'] ) ? $meta['description'] : '';
                }
                $venue = ! empty( $meta['venue_name'] ) ? $meta['venue_name'] : '';
                $venue .= ' , ';
                $venue .= ! empty( $meta['venue_address'] ) ? $meta['venue_address'] : '';
                $venue .= ' , ';
                $venue .= ! empty( $meta['city_name'] ) ? $meta['city_name'] : '';
                $venue .= ' , ';
                $venue .= ! empty( $meta['postal_code'] ) ? $meta['postal_code'] : '';
                $venue .= ' , ';
                $venue .= ! empty( $meta['region_name'] ) ? $meta['region_name'] : '';
                $venue .= ' , ';
                $venue .= ! empty( $meta['country_name'] ) ? $meta['country_name'] : '';
                $venue .= '  ';


                //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 );
                }

                $tickets_url = '';
                if ( ! empty( $meta['tickets'] ) ) {
                    foreach ( $meta['tickets'] as $single ) {
                        $tickets_url .= "<a href=" . $single . "'target=_blank'>__('Tickets ','wp-content-pilot-pro')</a>";
                    }
                }

                wpcp_logger()->info( __( 'Combining all parts for article', 'wp-content-pilot-pro' ), $campaign_id );
                $article = array(
                    'title'       => $title,
                    'image_url'   => ! empty( $meta['image_url'] ) ? str_replace( 'small', 'blackborder500', $meta['image_url'] ) : '',
                    'content'     => $content,
                    'source_url'  => $link->url,
                    'venue'       => $venue,
                    'venue_url'   => ! empty( $meta['venue_url'] ) ? "<a href=" . $meta['venue_url'] . " target='_blank'>Venue Url</a>" : '',
                    'category'    => ! empty( $meta['category'] ) ? implode( ", ", $meta['category'] ) : '',
                    'start_time'  => ! empty( $meta['start_time'] ) ? $meta['start_time'] : '',
                    'tickets'     => ! empty( $meta['tickets'] ) ? $tickets_url : '',
                    'price'       => ! empty( $meta['price'] ) ? $meta['price'] : '',
                    'going_count' => ! empty( $meta['going_count'] ) ? implode( "", $meta['going_count'] ) : '',
                    'all_day'     => ! empty( $meta['all_day'] ) ? 'Yes' : 'No',
                );

                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( 'eventful_api', 'wpcp_settings_eventful' );
        $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, '_location' );
        $categories       = wpcp_get_post_meta( $campaign_id, '_category' );
        $exclude_category = wpcp_get_post_meta( $campaign_id, '_ex_category' );
        $sort_order       = wpcp_get_post_meta( $campaign_id, '_sort_order', 'relevance' );
        $sort_direction   = wpcp_get_post_meta( $campaign_id, '_sort_direction', 'descending' );

        $api_url = sprintf( 'http://api.eventful.com/rest/events/search' );

        $query_args = array(
            'app_key'     => $api_key,
            'keywords'    => $keyword,
            'include'     => 'categories,tickets,price,links',
            'page_number' => $page_number,
            'page_size'   => 10,
        );

        if ( $location != null ) {
            $query_args['location'] = $location;
        }
        if ( $categories != null ) {
            $query_args['category'] = $categories;
        }
        if ( $exclude_category != null ) {
            $query_args['ex_category'] = $exclude_category;
        }
        if ( $sort_order != null ) {
            $query_args['sort_order']     = $sort_order;
            $query_args['sort_direction'] = $sort_direction;
        }


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

        wpcp_logger()->info( sprintf( __( 'Requesting urls from eventful [%s]', 'wp-content-pilot-pro' ), preg_replace( '/app_key=([^&]+)/m', 'app_key=X', $endpoint ) ) );
        $curl = $this->setup_curl();

        $curl->get( $endpoint );
        if ( $curl->isError() ) {
            $message = sprintf( __( 'Eventful api request failed response [%s]', 'wp-content-pilot-pro' ), $curl->errorMessage );
            wpcp_logger()->error( $message );

            return false;
        }

        $response = $curl->getResponse();

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

            return new WP_Error( 'no-links-found', $message );
        }
        if ( (int) $response->page_number > (int) $response->page_count ) {
            $message = __( 'Could not find any new events, deactivating keyword for an hour.', 'wp-content-pilot-pro' );
            wpcp_logger()->error( $message, $campaign_id );
            $this->deactivate_key( $campaign_id, $keyword );

            return new WP_Error( 'no-links-found', $message );
        }

        $events = $response->events;

        $event_array = json_decode( json_encode( $events ), true );
        $events      = $event_array['event'];

        $links   = [];
        $counter = 0;
        wpcp_logger()->info( __( 'Looping through links for storing..', 'wp-content-pilot-pro' ), $campaign_id );
        foreach ( $events as $event ) {

            $title     = $event['title'];
            $item_link = $event['url'];

            $meta = array();

            $meta['start_time']    = $event['start_time'];
            $meta['description']   = $event['description'];
            $meta['venue_url']     = $event['venue_url'];
            $meta['venue_name']    = $event['venue_name'];
            $meta['venue_address'] = $event['venue_address'];
            $meta['city_name']     = $event['city_name'];
            $meta['region_name']   = $event['region_name'];
            $meta['country_name']  = $event['country_name'];
            $meta['postal_code']   = $event['postal_code'];
            $meta['image_url']     = ! empty( $event['image']['url'] ) ? $event['image']['url'] : '';
            $meta['price']         = $event['price'];
            $meta['all_day']       = $event['all_day'];
            $meta['going_count']   = $event['going_count'];


            $categories = array();

            if ( is_array( $event['categories'] ) && ! empty( $event['categories'] ) ) {
                if ( empty( $event['categories']['category'][0] ) ) {
                    $categories[] = $event['categories']['category']['name'];
                } else {
                    foreach ( $event['categories']['category'] as $category ) {
                        $categories[] = $category['name'];
                    }
                }
            }

            $meta['category'] = $categories;

            $tickets = array();
            if ( is_array( $event['tickets'] ) && ! empty( $event['tickets'] ) ) {
                if ( empty( $event['tickets']['link'][0] ) ) {
                    $tickets[] = $events['tickets']['link']['url'];
                } else {
                    foreach ( $event['tickets']['link'] as $ticket ) {
                        $tickets[] = $ticket['url'];
                    }
                }
            }

            $meta['tickets'] = $tickets;

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

            /** Not skipping title because several events have same name but the url is different **/
            //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 ) {
//                wpcp_logger()->info( __( 'Duplicate title skipping', 'wp-content-pilot-pro' ), $campaign_id );
//                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( $events ), $counter, ( count( $events ) - $counter ) ), $campaign_id );

        return true;
    }

    /**
     * To get eventful categories
     * return @array
     * @since 1.1.7
     */

    public function event_categories() {
        $category = array(
            ''                      => __( 'Select Categories', 'wp-content-pilot-pro' ),
            'music'                 => __( 'Concerts &amp; Tour Dates', 'wp-content-pilot-pro' ),
            'conference'            => __( 'Conferences &amp; Tradeshows', 'wp-content-pilot-pro' ),
            'comedy'                => __( 'Comedy', 'wp-content-pilot-pro' ),
            'learning_education'    => __( 'Education', 'wp-content-pilot-pro' ),
            'family_fun_kids'       => __( 'Kids &amp; Family', 'wp-content-pilot-pro' ),
            'festivals_parades'     => __( 'Festivals', 'wp-content-pilot-pro' ),
            'movies_film'           => __( 'Film', 'wp-content-pilot-pro' ),
            'food'                  => __( 'Food &amp; Wine', 'wp-content-pilot-pro' ),
            'fundraisers'           => __( 'Fundraising &amp; Charity', 'wp-content-pilot-pro' ),
            'art'                   => __( 'Art Galleries &amp; Exhibits', 'wp-content-pilot-pro' ),
            'support'               => __( 'Health &amp; Wellness', 'wp-content-pilot-pro' ),
            'holiday'               => __( 'Holiday', 'wp-content-pilot-pro' ),
            'books'                 => __( 'Literary &amp; Books', 'wp-content-pilot-pro' ),
            'attractions'           => __( 'Museums &amp; Attractions', 'wp-content-pilot-pro' ),
            'community'             => __( 'Neighborhood', 'wp-content-pilot-pro' ),
            'business'              => __( 'Business &amp; Networking', 'wp-content-pilot-pro' ),
            'singles_social'        => __( 'Nightlife &amp; Singles', 'wp-content-pilot-pro' ),
            'schools_alumni'        => __( 'University &amp; Alumni', 'wp-content-pilot-pro' ),
            'clubs_associations'    => __( 'Organizations &amp; Meetups', 'wp-content-pilot-pro' ),
            'outdoors_recreation'   => __( 'Outdoors &amp; Recreation', 'wp-content-pilot-pro' ),
            'performing_arts'       => __( 'Performing Arts', 'wp-content-pilot-pro' ),
            'animals'               => __( 'Pets', 'wp-content-pilot-pro' ),
            'politics_activism'     => __( 'Politics &amp; Activism', 'wp-content-pilot-pro' ),
            'sales'                 => __( 'Sales &amp; Retail', 'wp-content-pilot-pro' ),
            'science'               => __( 'Science', 'wp-content-pilot-pro' ),
            'religion_spirituality' => __( 'Religion &amp; Spirituality', 'wp-content-pilot-pro' ),
            'sports'                => __( 'Sports', 'wp-content-pilot-pro' ),
            'technology'            => __( 'Technology', 'wp-content-pilot-pro' ),
            'other'                 => __( 'Other &amp; Miscellaneous', 'wp-content-pilot-pro' ),

        );

        return $category;
    }

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

        return self::$_instance;
    }
}

WPCP_EventFul::instance();
