<?php

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class Realia_Statistics
 *
 * @class Realia_Statistics
 * @package Realia/Classes
 * @author Pragmatic Mates
 */
class Realia_Statistics {
    /**
     * Initialize statistics functionality
     *
     * @access public
     * @return void
     */
    public static function init() {
	    add_action( 'admin_menu', array( __CLASS__, 'menu' ) );
	    add_action( 'pre_get_posts', array( __CLASS__, 'save_search_queries' ) );
	    add_filter( 'the_content', array( __CLASS__, 'save_property_views' ) );
	    add_filter( 'query_vars', array( __CLASS__, 'add_query_vars' ) );
	    add_action( 'template_redirect', array( __CLASS__, 'redirects' ) );
    }

    /**
     * Registers menu items
     *
     * @access public
     * @return void
     */
    public static function menu() {
	    if ( current_theme_supports( 'realia-statistics' ) ) {
		    add_submenu_page( 'edit.php?post_type=property', __( 'Property Views', 'realia' ), __( 'Property Views', 'realia' ), 'manage_options', 'property_views', array(
			    __CLASS__,
			    'property_views_template'
		    ) );

		    add_submenu_page( 'edit.php?post_type=property', __( 'Search Queries', 'realia' ), __( 'Search Queries', 'realia' ), 'manage_options', 'search_queries', array(
			    __CLASS__,
			    'search_queries_template'
		    ) );
	    }
    }

    /**
     * Search queries template
     *
     * @access public
     * @return void
     */
    public static function search_queries_template() {
        echo Realia_Template_Loader::load( 'statistics/search-queries' );
    }

    /**
     * Property views template
     *
     * @access public
     * @return void
     */
    public static function property_views_template() {
        echo Realia_Template_Loader::load( 'statistics/property-views' );
    }

    /**
     * Add query vars
     *
     * @access public
     * @param $vars
     * @return array
     */
    public static function add_query_vars( $vars ) {
        $vars[] = 'api-query';
        $vars[] = 'api-property-views';
        return $vars;
    }

    /**
     * Redirects to functions by query var
     *
     * @access public
     * @return void
     */
    public static function redirects() {
        if ( ! is_user_logged_in() || ! current_user_can( 'manage_options' ) ) {
            return;
        }

        if ( get_query_var( 'api-query' ) ) {
            header( 'HTTP/1.0 200 OK' );
            header( 'Content-Type: application/json' );

            switch ( $_GET['type'] ) {
                case 'filters_per_day':
                    $data = self::search_queries_filters_per_day();
                    echo json_encode( $data );
                    break;
                case 'property_type':
                    $data = self::search_queries_property_type();
                    echo json_encode( $data );
                    break;
                case 'contract':
                    $data = self::search_queries_contract();
                    echo json_encode( $data );
                    break;
                case 'price':
                    $data = self::search_queries_price();
                    echo json_encode( $data );
                    break;
            }
            exit();
        }

        if ( get_query_var( 'api-property-views' ) ) {
            header( 'HTTP/1.0 200 OK' );
            header( 'Content-Type: application/json' );
            $data = self::property_views_get_statistics_per_day();
            echo json_encode( $data );
            exit();
        }
    }

    /**
     * Saves search query
     *
     * @access public
     * @param $query array
     * @return void
     */
    public static function save_search_queries( $query ) {
        global $wpdb;

        $query_logging = get_theme_mod( 'realia_general_enable_query_logging', false );

        if ( ! $query_logging ) {
            return;
        }

        $suppress_filters = ! empty( $query->query_vars['suppress_filters'] ) ? $query->query_vars['suppress_filters'] : '';

        if ( ! is_post_type_archive( 'property' ) || ! $query->is_main_query() || is_admin() || $query->query_vars['post_type'] != 'property' || $suppress_filters ) {
            return;
        }

        if ( is_array( $_GET ) && count( $_GET ) > 0 ) {
            foreach ( $_GET as $key => $value ) {
                if ( substr( $key, 0, strlen( 'filter-' ) ) === 'filter-' && ! empty( $value ) ) {
                    $key = str_replace( array( 'filter-', '-' ), array( '', '_' ), $key);

                    $wpdb->insert( $wpdb->prefix . 'query_stats', array(
                        'key'       => $key,
                        'value'     => $value,
                        'created'   => date( 'Y-m-d H:i:s' ),
                    ) );
                }
            }

            $wpdb->insert( $wpdb->prefix . 'query_stats', array(
                'key'       => 'filter',
                'value'     => $_SERVER['REMOTE_ADDR'],
                'created'   => date( 'Y-m-d H:i:s' ),
            ) );
        }
    }

    /**
     * Saves property view
     *
     * @access public
     * @param $content string
     * @return mixed
     */
    public static function save_property_views( $content ) {
        global $wpdb;

        if ( get_theme_mod( 'realia_general_enable_property_logging') && is_singular( 'property' ) ) {
            $sql = 'SELECT * FROM ' . $wpdb->prefix . 'property_stats
            WHERE `key` = "' . get_the_ID() . '" AND
                  `value` = "' . session_id() . '" AND
                  `created` > DATE_SUB(NOW(), INTERVAL 15 MINUTE)';
            $results = $wpdb->get_results( $sql );

            if ( count( $results ) == 0 ) {
                $wpdb->insert( $wpdb->prefix . 'property_stats', array(
                    'key'       => get_the_ID(),
                    'value'     => session_id(),
                    'ip'        => $_SERVER['REMOTE_ADDR'],
                    'created'   => current_time( 'mysql' ),
                ) );
            }
        }

        return $content;
    }

    /**
     * Installs search query table
     *
     * @access public
     * @return void
     */
    public static function install_search_queries() {
        global $wpdb;

        $table_name = $wpdb->prefix . 'query_stats';

        if( $wpdb->get_var( "SHOW TABLES LIKE '$table_name'" ) != $table_name)  {
            $charset_collate = $wpdb->get_charset_collate();

            $sql = 'CREATE TABLE `' . $wpdb->prefix . 'query_stats` (
                    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
                    `key` varchar(200) NOT NULL DEFAULT \'\',
                    `value` text NOT NULL,
                    `created` timestamp NOT NULL DEFAULT \'0000-00-00 00:00:00\' ON UPDATE CURRENT_TIMESTAMP,
                    PRIMARY KEY (`id`),
                    KEY `key` (`key`)
                ) ENGINE=InnoDB DEFAULT CHARSET=' . $charset_collate . ';';

            require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
            dbDelta( $sql );
        }
    }

    /**
     * Installs property views table
     *
     * @access public
     * @return void
     */
    public static function install_property_views() {
        global $wpdb;

        $table_name = $wpdb->prefix . 'property_stats';

        if( $wpdb->get_var( "SHOW TABLES LIKE '$table_name'" ) != $table_name)  {
            $charset_collate = $wpdb->get_charset_collate();

            $sql = 'CREATE TABLE `' . $wpdb->prefix . 'property_stats` (
                    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
                    `key` varchar(200) NOT NULL DEFAULT \'\',
                    `value` text NOT NULL,
                    `ip` varchar(200) NOT NULL DEFAULT \'\',
                    `created` timestamp NOT NULL DEFAULT \'0000-00-00 00:00:00\' ON UPDATE CURRENT_TIMESTAMP,
                    PRIMARY KEY (`id`),
                    KEY `key` (`key`)
                ) ENGINE=InnoDB DEFAULT CHARSET=' . $charset_collate . ';';

            require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
            dbDelta( $sql );
        }
    }

    /**
     * Search queries price statistics
     *
     * @access public
     * @return array
     */
    public static function search_queries_price() {
        global $wpdb;

        $data = array(
            array(
                'key'           => 'Price from',
                'values'        => array()
            ),
            array(
                'key'           => 'Price to',
                'values'        => array()
            ),
        );

        // Price from
        $sql = 'SELECT ROUND(value, -3) as price, COUNT(*) as count FROM ' . $wpdb->prefix . 'query_stats
                WHERE `key` = "price_from"
                GROUP BY price';

        $results = $wpdb->get_results( $sql );

        foreach( $results as $result ) {
            $data[0]['values'][] = array(
                'x'     => (int) $result->count,
                'y'     => (int) $result->price,
                'size'  => (int) $result->count * $result->price,
            );
        }

        // Price to
        $sql = 'SELECT ROUND(value, -3) as price, COUNT(*) as count FROM ' . $wpdb->prefix . 'query_stats
                WHERE `key` = "price_to"
                GROUP BY price';

        $results = $wpdb->get_results( $sql );

        foreach( $results as $result ) {
            $data[1]['values'][] = array(
                'x'     => (int) $result->count,
                'y'     => (int) $result->price,
                'size'  => (int) $result->count * $result->price
            );
        }

        return $data;
    }

    /**
     * Search queries per day statistics
     *
     * @access public
     * @return array
     */
    public static function search_queries_filters_per_day() {
        global $wpdb;

        $data = array();
        $data[] = array(
            'key'       => __( 'Per day', 'realia' ),
            'area'      => true,
            'values'    => array(),
        );

        $sql = 'SELECT DATE(created) as date, COUNT(*) as count FROM ' . $wpdb->prefix . 'query_stats
                WHERE `key` = "filter" AND
                      `created` >= DATE_SUB(NOW(), INTERVAL 2 WEEK)
                GROUP BY date
                ORDER BY date';

        $results = $wpdb->get_results( $sql );

        for ( $i = 13; $i >= 0 ; $i-- ) {
            $date = date( 'Y-m-d', strtotime( '-' . $i . ' days' ) );

            $data[0]['values'][] = array(
                13 - $i, $date, 0
            );
        }

        $index = 1;
        foreach ( $results as $result ) {
            foreach ( $data[0]['values'] as $key => $value ) {
                if ( $value[1] == $result->date ) {
                    $data[0]['values'][$key] = array(
                        $key, $result->date, (int) $result->count
                    );
                }
            }

            $index++;
        }

        return $data;
    }

    /**
     * Search queries property type statistics
     *
     * @access public
     * @return array
     */
    public static function search_queries_property_type() {
        global $wpdb;

        $sql = 'SELECT name as label, COUNT(*) as value FROM ' . $wpdb->prefix . 'query_stats
                LEFT JOIN ' . $wpdb->prefix . 'terms
                ON value = term_id
                WHERE `key` = "property_type"
                GROUP BY ' . $wpdb->prefix . 'query_stats.value;';

        return $wpdb->get_results( $sql, ARRAY_A );
    }

    /**
     * Search queries contract statistics
     *
     * @access public
     * @return array
     */
    public static function search_queries_contract() {
        global $wpdb;

        $sql = 'SELECT name as label, COUNT(*) as value FROM ' . $wpdb->prefix . 'query_stats
                LEFT JOIN ' . $wpdb->prefix . 'terms
                ON value = term_id
                WHERE `key` = "contract_type"
                GROUP BY ' . $wpdb->prefix . 'query_stats.value;';

        return $wpdb->get_results( $sql, ARRAY_A );
    }

    /**
     * Property views popular statistics
     *
     * @access public
     * @param int $count
     * @return mixed
     */
    public static function property_views_get_popular_properties( $count = 10 ) {
        global $wpdb;

        $sql = 'SELECT `key`, post_title, COUNT(*) as count FROM ' . $wpdb->prefix . 'property_stats
                LEFT JOIN ' . $wpdb->prefix . 'posts ON ' . $wpdb->prefix . 'posts.ID=' . $wpdb->prefix . 'property_stats.key
                GROUP BY `key`
                ORDER BY count DESC
                LIMIT ' . $count . ';';

        return $wpdb->get_results( $sql );
    }

    /**
     * Property views popular locations statistics
     *
     * @access public
     * @param int $count
     * @return mixed
     */
    public static function property_views_get_popular_locations( $count = 10 ) {
        global $wpdb;

        $sql = 'SELECT ' . $wpdb->prefix . 'term_taxonomy.term_taxonomy_id, taxonomy, COUNT(*) as count FROM ' . $wpdb->prefix . 'property_stats
                LEFT JOIN ' . $wpdb->prefix . 'term_relationships ON ' . $wpdb->prefix . 'term_relationships.object_id=' . $wpdb->prefix . 'property_stats.key
                LEFT JOIN ' . $wpdb->prefix . 'term_taxonomy ON ' . $wpdb->prefix . 'term_taxonomy.term_taxonomy_id=' . $wpdb->prefix . 'term_relationships.term_taxonomy_id
                WHERE taxonomy = \'locations\'
                GROUP BY term_taxonomy_id
                ORDER BY count DESC
                LIMIT ' . $count . ';';

        return $wpdb->get_results( $sql );
    }

    /**
     * Property views per day statistics
     *
     * @access public
     * @return mixed
     */
    public static function property_views_get_statistics_per_day() {
        global $wpdb;

        $data = array();
        $data[] = array(
            'key'       => __( 'Per day', 'realia' ),
            'area'      => true,
            'values'    => array(),
        );

        $sql = 'SELECT DATE(created) as date, COUNT(*) as count FROM ' . $wpdb->prefix . 'property_stats
                WHERE `created` >= DATE_SUB(NOW(), INTERVAL 2 WEEK)
                GROUP BY date
                ORDER BY date';

        $results = $wpdb->get_results( $sql );

        for ( $i = 13; $i >= 0 ; $i-- ) {
            $date = date( 'Y-m-d', strtotime( '-' . $i . ' days' ) );

            $data[0]['values'][] = array(
                13 - $i, $date, 0
            );
        }

        $index = 1;
        foreach ( $results as $result ) {
            foreach ( $data[0]['values'] as $key => $value ) {
                if ( $value[1] == $result->date ) {
                    $data[0]['values'][$key] = array(
                        $key, $result->date, (int) $result->count
                    );
                }
            }

            $index++;
        }

        return $data;
    }

    /**
     * Gets property total views
     *
     * @access public
     * @param null $post_id
     * @return int
     */
    public static function property_views_get_total( $post_id = null ) {
        global $wpdb;

        if ( $post_id == null ) {
            $post_id = get_the_ID();
        }

        $sql = 'SELECT `key`, COUNT(*) as count FROM ' . $wpdb->prefix . 'property_stats
                WHERE `key` = "' . $post_id . '"
                GROUP BY `key`';

        $results = $wpdb->get_results( $sql );
        if ( is_array( $results ) && count( $results ) > 0 ) {
            return $results[0]->count;
        }

        return 0;
    }

    /**
     * Gets property weekly progress
     *
     * @access public
     * @param null $post_id
     * @return float|int
     */
    public static function property_views_get_weekly_progress( $post_id = null ) {
        global $wpdb;

        if ( $post_id == null ) {
            $post_id = get_the_ID();
        }

        // Last week
        $last_week_sql = 'SELECT `key`, COUNT(*) as count FROM ' . $wpdb->prefix . 'property_stats
                        WHERE   `key` = "' . $post_id . '" AND
                                WEEK(created) = WEEK( current_date ) - 1 AND
                                YEAR(created) = YEAR( current_date );';
        $last_week_results = $wpdb->get_results( $last_week_sql );
        $last_week_count = 0;

        if ( is_array( $last_week_results ) && count( $last_week_results ) > 0 ) {
            $last_week_count = $last_week_results[0]->count;
        }

        // Two weeks ago
        $two_weeks_ago_sql = 'SELECT `key`, COUNT(*) as count FROM ' . $wpdb->prefix . 'property_stats
                        WHERE   `key` = "' . $post_id . '" AND
                                WEEK(created) = WEEK( current_date ) - 2 AND
                                YEAR(created) = YEAR( current_date );';
        $two_weeks_ago_results = $wpdb->get_results( $two_weeks_ago_sql );

        if ( is_array( $two_weeks_ago_results ) && count( $two_weeks_ago_results ) > 0 ) {
            $two_weeks_ago_count = $two_weeks_ago_results[0]->count;
        }

        if ( $two_weeks_ago_count == 0 && $last_week_count > 0 ) {
            return 100;
        } elseif ( $two_weeks_ago_count == 0 && $last_week_count == 0 ) {
            return 0;
        } elseif ( $two_weeks_ago_count > 0 && $last_week_count == 0 ) {
            return -100;
        } elseif ( $two_weeks_ago_count == $last_week_count ) {
            return 0;
        } elseif ( $two_weeks_ago_count > 0 && $last_week_count > 0 ) {
            return round( ( 100 / $two_weeks_ago_count * $last_week_count ) - 100, 2 );
        }

        return 0;
    }
}

Realia_Statistics::init();