<?php

namespace auctionforge\inc\model;

use auctionforge\inc\InstanceDB;
use auctionforge\inc\model\LotMetaData;

class ViewHistory
{
    const TABLE_VIEW_HISTORY = "bp_user_view_history";
    const MAX_HISTORY_ITEMS = 20;

    /**
     * Get the full table name with prefix
     * @return string
     */
    public static function getTableName()
    {
        $db = InstanceDB::getInstanceDB();
        return $db->prefix . self::TABLE_VIEW_HISTORY;
    }

    /**
     * Record a lot view for a user. Uses INSERT ... ON DUPLICATE KEY UPDATE
     * to update the timestamp if the user views the same lot again.
     *
     * @param string $userEmail BidSpirit user email
     * @param int $postId WP post ID of the lot
     * @param int $termId Auction term ID
     * @return bool|int
     */
    public static function recordView($userEmail, $postId, $termId = 0)
    {
        if (empty($userEmail) || empty($postId)) {
            return false;
        }

        $db = InstanceDB::getInstanceDB();
        $table = self::getTableName();

        $sql = $db->prepare(
            "INSERT INTO `{$table}` (user_email, post_id, term_id, viewed_at)
             VALUES (%s, %d, %d, NOW())
             ON DUPLICATE KEY UPDATE viewed_at = NOW(), term_id = VALUES(term_id)",
            $userEmail,
            $postId,
            $termId
        );

        $result = $db->query($sql);

        // Prune old entries beyond MAX_HISTORY_ITEMS
        self::pruneHistory($userEmail);

        return $result;
    }

    /**
     * Get the most recent viewed lots for a user
     *
     * @param string $userEmail BidSpirit user email
     * @param int $limit Number of items to return
     * @return array
     */
    public static function getHistory($userEmail, $limit = 0)
    {
        if (empty($userEmail)) {
            return array();
        }

        if ($limit <= 0) {
            $limit = self::MAX_HISTORY_ITEMS;
        }

        $db = InstanceDB::getInstanceDB();
        $table = self::getTableName();
        $metaTable = LotMetaData::getTableName();

        $sql = $db->prepare(
            "SELECT vh.id, vh.post_id, vh.term_id, vh.viewed_at,
                    p.post_title, p.post_name,
                    m.itemIndex, m.name as lot_name, m.startPrice, m.soldBid,
                    m.leadingBid, m.estimatedPrice, m.imagesListStr, m.imagesBase,
                    m.id as bidspirit_lot_id, m.auctionId, m.imagesCloned,
                    t.name as auction_name, t.slug as auction_slug
             FROM `{$table}` vh
             INNER JOIN {$db->posts} p ON vh.post_id = p.ID
             LEFT JOIN `{$metaTable}` m ON vh.post_id = m.postId
             LEFT JOIN {$db->term_taxonomy} tt ON vh.term_id = tt.term_id AND tt.taxonomy = 'auction_number'
             LEFT JOIN {$db->terms} t ON vh.term_id = t.term_id
             WHERE vh.user_email = %s
               AND p.post_status = 'publish'
             ORDER BY vh.viewed_at DESC
             LIMIT %d",
            $userEmail,
            $limit
        );

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

        return $results ? $results : array();
    }

    /**
     * Keep only the most recent MAX_HISTORY_ITEMS for a user
     *
     * @param string $userEmail
     */
    private static function pruneHistory($userEmail)
    {
        $db = InstanceDB::getInstanceDB();
        $table = self::getTableName();

        $sql = $db->prepare(
            "DELETE FROM `{$table}`
             WHERE user_email = %s
               AND id NOT IN (
                   SELECT id FROM (
                       SELECT id FROM `{$table}`
                       WHERE user_email = %s
                       ORDER BY viewed_at DESC
                       LIMIT %d
                   ) AS keep_rows
               )",
            $userEmail,
            $userEmail,
            self::MAX_HISTORY_ITEMS
        );

        $db->query($sql);
    }

    /**
     * Clear all view history for a user
     *
     * @param string $userEmail
     * @return bool|int
     */
    public static function clearHistory($userEmail)
    {
        if (empty($userEmail)) {
            return false;
        }

        $db = InstanceDB::getInstanceDB();
        $table = self::getTableName();

        return $db->delete($table, array('user_email' => $userEmail), array('%s'));
    }
}
