<?php

namespace auctionforge\inc\controllers;

use Kreait\Firebase\Exception\FirebaseException;
use Kreait\Firebase\Exception\MessagingException;
use Kreait\Firebase\Factory;
use stdClass;
use auctionforge\inc\abs\BidspiritWebhooks;
use auctionforge\inc\abs\Importer;
use auctionforge\inc\BidSpiritRequest;
use auctionforge\inc\Debug;
use auctionforge\inc\helpers\BS_API;
use auctionforge\inc\helpers\LotHelper;
use auctionforge\inc\helpers\SettingsHelper;
use auctionforge\inc\import\LotList;
use auctionforge\inc\model\Auction;
use auctionforge\inc\model\FirebaseLog;
use auctionforge\inc\model\FirebaseUser;
use Kreait\Firebase\Messaging\CloudMessage;
use auctionforge\inc\model\interfaces\AuctionStartsSoon;
use auctionforge\inc\model\interfaces\ItemLiveSoon;
use auctionforge\inc\model\interfaces\LeadingBidSurpassed;
use auctionforge\inc\model\Lot;
use auctionforge\inc\traits\LoggerInfo;
use WP_REST_Request;
use WP_REST_Server;

class SendAppNotification extends BidspiritWebhooks
{
    use LoggerInfo;

    public function init()
    {
//        add_action('init', array($this, 'init_app'));
        add_action('rest_api_init', array($this, 'login'));
        add_action('rest_api_init', array($this, 'event'));

//        add_action('rest_api_init', array($this, 'event'));
        add_action('rest_api_init', array($this, 'translate'));
    }

    public function init_app()
    {
        if (!empty($_GET["app_init"])) {
            $homeUrl = get_option('home');
            header('Refresh:0; url=' . $homeUrl);
            exit;
        }
    }

    public function login () {
        if (!defined('ABSPATH')) {
            die( 'You shouldnt be here' );
        }

        $namespace = self::API_NAMESPACE;

        $rout = '/user/login';

        $rout_params = array(
            'methods' => WP_REST_Server::CREATABLE,
            'callback' => array($this, 'event_login'),
            'args' => array(
                'bidspirit_user_email' => array(
                    'type' => 'string',
                    'required' => true
                ),
                'firebase_id' => array(
                    'type' => 'string',
                    'required' => true
                ),
            ),
            'permission_callback' => function ($request) {
                return $this->checkPermission();
            },
        );

        register_rest_route($namespace, $rout, $rout_params);
    }

    public function event_login(WP_REST_Request $request)
    {
        $data = $request->get_params();
        $fireUser = new FirebaseUser();
        $fireUser->loadAttributes($data);
        $fireUser->load();

        if (!empty($fireUser->getFirebaseId())) {
            $fireUser->save();
        }

        return array(
            'request' => $request->get_params(),
            'id' => $fireUser->getId(),
            'email' => $fireUser->getBidspiritUserEmail(),
            'fireId' => $fireUser->getFirebaseId(),
            'created' => $fireUser->getCreated()
        );
    }

    public function event () {
        if (!defined('ABSPATH')) {
            die( 'You shouldnt be here' );
        }

        $namespace = self::API_NAMESPACE;

        $rout = '/sync';

        $rout_params = array(
            'methods' => ['POST', 'GET'],
            'callback' => array($this, 'event_action'),
            'args' => array(),
            'permission_callback' => function ($request) {
                return $this->checkPermission();
            },
        );

        register_rest_route($namespace, $rout, $rout_params);
    }

    public function translate () {
        if (!defined('ABSPATH')) {
            die('You shouldnt be here');
        }

        $namespace = self::API_NAMESPACE;

        $rout = '/translate';

        $rout_params = array(
            'methods' => 'POST',
            'callback' => array($this, 'translate_action'),
            'args' => array(),
            'permission_callback' => function ($request) {
                return $this->checkPermission();
            },
        );

        register_rest_route($namespace, $rout, $rout_params);
    }

    public function event_action(WP_REST_Request $request)
    {
        if (!isset($_SERVER['HTTP_X_BIDSPIRIT_SIGNATURE'])) {
            $error = new \WP_Error(500, "You shouldnt be here");
            echo $error->get_error_message();
            die;
        }

        $signature = $_SERVER['HTTP_X_BIDSPIRIT_SIGNATURE'];
        /** @var stdClass $response */
        $response = new \stdClass();
        $requestBody = file_get_contents('php://input');
        $authToken = SettingsHelper::getOption('auth_token', '');

        if ($authToken == "" && defined("AUCTIONFORGE_API_TOKEN")) {
            $authToken = AUCTIONFORGE_API_TOKEN;
        }

        $fbResponse = array();
        $obj = new stdClass();


        if (md5($authToken . "_" . $requestBody) == $signature) {
            $obj = json_decode($requestBody);

            Debug::webhookLog($requestBody, $obj->notificationType);

            switch ($obj->notificationType) {
                case "LEADING_BID_SURPASSED":
                    $fbResponse = $this->leading_bid_surpassed($obj);
                    break;
                case "AUCTION_STARTS_SOON":
                    $fbResponse = $this->auction_starts_soon($obj);
                    break;
                case "ITEM_LIVE_SOON":
                    $fbResponse = $this->item_live_soon($obj);
                    break;
                case "AUCTION_CATALOG_UPDATED":
                    $this->auctionCatalogUpdated($obj);
                    $fbResponse["result"] = true;
                    break;
                case "AUCTION_UPDATED":
                    $this->auctionUpdated($obj);
                    $fbResponse["result"] = true;
                    break;
                case "AUCTION_STATE_UPDATED":
                    $fbResponse["result"] = $this->auctionStateUpdated($obj);
                    break;
                case "AUCTION_PUBLISHED":
                    $this->auctionPublished($obj);
                    $fbResponse["result"] = true;
                    break;
                case "CATALOG_PUBLISHED":
                    $this->catalogPublished($obj);
                    $fbResponse["result"] = true;
                    break;
                case "AUCTION_DAY_ENDED":
                    $this->auctionDayEnded($obj);
                    $fbResponse["result"] = true;
                    break;
                case "ITEMS_UPDATED":
                    $this->itemsUpdated($obj);
                    $fbResponse["result"] = true;
                    break;
                case "ANNOUNCEMENT":
                    $this->announcement($obj);
                    $fbResponse["result"] = true;
                    break;
                case "TEST":
                    $fbResponse = $this->test($obj);
                    break;
            }

            if ($fbResponse["result"]) {
                $response->notify = true;
            } else {
                $response->notify = false;
            }
            $response->success = true;
        } else {
            $response->success = false;
            $response->notify = false;
            $response->error = "Bad signature";
        }

        if (!empty($obj->user)) {
            $this->logSave($obj->user, $obj, $requestBody, $fbResponse, $response);
        } elseif (!empty($obj->users)) {
            $this->logSave(json_encode($obj->users), $obj, $requestBody, $fbResponse, $response);
        } else {
            if (isset($obj->notificationType)) {
                $this->logSave($obj->notificationType, $obj, $requestBody, $fbResponse, $response);
            } else {
                $this->logSave("EMPTY_TEST", $obj, $requestBody, $fbResponse, $response);
            }
        }

        echo json_encode($response);
    }

    /**
     * @param $obj LeadingBidSurpassed
     * @return array
     */
    private function leading_bid_surpassed($obj)
    {
        $data = array(
            'request' => array(),
            'response' => array(),
            'result' => true
        );

        $fireUser = new FirebaseUser();
        $fireUser->loadAttributes((array)$obj);
        $fireUser->load();
        $postId = $this->findPostId($obj);

        // Being outbid is proof this person bid. Capture regardless of whether
        // they have an app token to push to.
        $this->captureBidders(isset($obj->user) ? $obj->user : '', $postId, 'bid');

        if ($fireUser->getFirebaseId()) {
            $data["request"] = array(
                'token' => $fireUser->getFirebaseId(),
                'notification' => array(
                    'title' => $obj->auctionNumber . "/" . $obj->itemIndex . " " . __("leading bid surpassed", "auctionforge"),
                    'body' => $obj->itemName,
                    'image' => $this->getFeatureImageByLotId($postId),
                ),
                'data' => array(
                    'url' => get_permalink($postId),
                    'notificationId' => $obj->itemId . rand(111, 999)
                )
            );

            $data = $this->sendMessage($data);
        }

        return $data;
    }

    /**
     * @param $obj ItemLiveSoon
     * @return array
     */
    private function item_live_soon($obj)
    {
        $data = array(
            'request' => array(),
            'response' => array(),
            'result' => true
        );

        $deviceTokens = FirebaseUser::deviceTokensForUsers($obj->users);
        $postId = $this->findPostId($obj);

        // Bidspirit tells us WHO is watching this lot. Record it before the
        // push-notification gate below — device tokens are empty on sites with
        // no mobile-app users, but the bidder data is just as valid there.
        // Recorded as 'alert', not 'bid': holding a lot alert correlates
        // strongly with bidding but does not prove one.
        $this->captureBidders(isset($obj->users) ? $obj->users : array(), $postId, 'alert');

        if (!empty($deviceTokens)) {
            $data["request"] = array(
                'notification' => array(
                    'title' => $obj->auctionNumber . "/" . $obj->itemIndex . " " . __("item live soon", "auctionforge"),
                    'body' => $obj->itemName,
                    'image' => $this->getFeatureImageByLotId($postId),
                    'imageUrl' => $this->getFeatureImageByLotId($postId)
                ),
                'data' => array(
                    'url' => get_permalink($postId),
                    'notificationId' => $obj->itemId . rand(111, 999)
                )
            );

            $data = $this->sendMessage($data, $deviceTokens);
        }

        return $data;
    }

    /**
     * @param $obj AuctionStartsSoon
     * @return array
     */
    private function auction_starts_soon($obj)
    {
        $data = array(
            'request' => array(),
            'response' => array(),
            'result' => true
        );

        $deviceTokens = FirebaseUser::deviceTokensForUsers($obj->users);
        $termId = $this->findTermId($obj);
        if (!empty($deviceTokens)) {
            $data["request"] = array(
                'notification' => array(
                    'title' => $obj->auctionNumber . " " . __("auction starts soon", "auctionforge"),
                    'body' => $obj->auctionName,
                    'image' => $this->getFeatureImageByAuctionId($obj, $termId),
                    'imageUrl' => $this->getFeatureImageByAuctionId($obj, $termId)
                ),
                'data' => array(
                    'url' => get_term_link($termId),
                    'notificationId' => $obj->auctionId . rand(111, 999)
                )
            );

            $data = $this->sendMessage($data, $deviceTokens);
        }

        return $data;
    }

    private function sendMessage($data, $deviceTokens = array())
    {
        $messaging = $this->getFactoryMessaging();
        $message = CloudMessage::fromArray($data["request"])->withDefaultSounds();
        try {
            if (!empty($deviceTokens)) {
                $validTokens = $messaging->validateRegistrationTokens($deviceTokens);
                if (!empty($validTokens["valid"])) {
                    $data["response"] = $messaging->sendMulticast($message, $validTokens["valid"]);
                }
            } else {
                $data["response"] = $messaging->send($message);
            }
        } catch (MessagingException $e) {
            $data["response"]["MessagingException"] = $e->getMessage();
            $data["result"] = false;
        } catch (FirebaseException $e) {
            $data["response"]["FirebaseException"] = $e->getMessage();
            $data["result"] = false;
        }
        return $data;
    }

    /**
     * @param $obj stdClass
     * @return array
     */
    private function test($obj)
    {
        $data = array(
            'request' => array(),
            'response' => array(),
            'result' => true
        );

        $deviceTokens = FirebaseUser::deviceTokensForUsers([
            'support@smoothbyteit.dev',
            'support@bidspirit-themes.com'
        ]);
        if (!empty($deviceTokens)) {
            $data["request"] = array(
                'notification' => array(
                    'title' => "Test notice",
                    'body' => "Body test notice",
                ),
                'data' => array(
                    'notificationId' => '1001' . rand(111, 999)
                )
            );

            $data['response'] = $this->sendMessage($data, $deviceTokens);
        }

        return $data;
    }

    /**
     * @param $fireUser string
     * @param $obj stdClass
     * @param $requestBody string
     * @param $fbResponse array
     * @param $response stdClass
     * @return void
     */
    /**
     * Record bidder engagement carried on a Bidspirit webhook into the local
     * bid-events queue, which feeds the Statistics "Engagement Funnel".
     *
     * Bidspirit has always sent the bidder email(s) on LEADING_BID_SURPASSED
     * (singular `user`) and ITEM_LIVE_SOON (plural `users`), but nothing
     * consumed them: AF_Bids_Sync::queue() had no callers, so wp_af_bid_events
     * stayed permanently empty and the funnel reported "Bidders 0" on sites
     * with thousands of real bids.
     *
     * De-duplicates on (email, lot) so a webhook retry — or running the admin
     * backfill more than once — cannot inflate the figures.
     *
     * @param array|string $emails One or many bidder email addresses.
     * @param int          $postId Resolved WP lot post id.
     * @param string       $source 'bid' for a confirmed bid (outbid notice) or
     *                             'alert' for a lot-alert holder, which is a
     *                             strong proxy but NOT proof of a bid. Stored so
     *                             nothing downstream conflates the two.
     * @return int Number of events queued.
     */
    private function captureBidders($emails, $postId, $source = 'bid')
    {
        if (empty($emails) || empty($postId)) {
            return 0;
        }

        // NB: leading backslashes are required — this file is namespaced
        // (auctionforge\inc\controllers) and PHP does not fall back to the
        // global namespace for class names the way it does for functions.
        if (!class_exists('\AF_Bids_Sync')) {
            $syncFile = __DIR__ . '/../sync/class-bids-sync.php';
            if (file_exists($syncFile)) {
                require_once $syncFile;
            }
            if (!class_exists('\AF_Bids_Sync')) {
                return 0;
            }
        }

        global $wpdb;
        $table = $wpdb->prefix . 'af_bid_events';

        // This runs on a public webhook: if the table is missing, an unguarded
        // SELECT raises MySQL 1146 and can leak an HTML notice into the JSON
        // response body. Create it once, up front, instead.
        if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table)) !== $table) {
            \AF_Bids_Sync::ensure_table();
        }

        $queued = 0;

        foreach ((array) $emails as $email) {
            if (!is_string($email)) {
                continue;
            }
            $email = strtolower(trim($email));
            if (!is_email($email)) {
                continue;
            }

            $exists = $wpdb->get_var($wpdb->prepare(
                "SELECT id FROM $table WHERE user_email = %s AND lot_post_id = %d LIMIT 1",
                $email,
                (int) $postId
            ));
            if ($exists) {
                continue;
            }

            // $amount is a required parameter with no default; these webhooks
            // carry bidder identity but never a bid value, so pass null.
            if (\AF_Bids_Sync::queue($email, $postId, null, 'GBP', false, null, $source)) {
                $queued++;
            }
        }

        return $queued;
    }

    private function logSave($user, $obj, $requestBody, $fbResponse, $response)
    {
        // Plural-user payloads (ITEM_LIVE_SOON) carry no singular `user`, which
        // previously left bidspirit_user_email empty on every such row while
        // the email array went into firebase_id. Fall back to the first address
        // so the column means what its name says. Hard-capped: the column is
        // varchar(55) and a long address would otherwise error under strict mode.
        $email = '';
        if (!empty($obj->user) && is_string($obj->user)) {
            $email = $obj->user;
        } elseif (!empty($obj->users)) {
            foreach ((array) $obj->users as $candidate) {
                if (is_string($candidate) && strpos($candidate, '@') !== false) {
                    $email = $candidate;
                    break;
                }
            }
        }

        $attr = array(
            'firebase_id' => $user,
            'bidspirit_user_email' => mb_substr($email, 0, 55),
            'bidspirit_lot_id' => (!empty($obj->itemIndex)) ? $obj->itemIndex : "",
            'request_from_bidspirit' => $requestBody,
            'request_to_firebase' => (!empty($fbResponse["request"])) ? $fbResponse["request"] : "",
            'response_from_firebase' => (!empty($fbResponse["response"])) ? $fbResponse["response"] : "",
            'response_to_bidspirit' => $response
        );

        $fireLog = new FirebaseLog(FirebaseLog::STATUS_SENT);
        $fireLog->loadAttributes($attr);
        $fireLog->save();
    }

    /**
     * @return \Kreait\Firebase\Contract\Messaging
     */
    private function getFactoryMessaging()
    {
        if (!defined('AUCTIONFORGE_SERVICE_PACK')) {
            define('AUCTIONFORGE_SERVICE_PACK', 'service');
        }

        $service = require_once __DIR__.'/../services/' . AUCTIONFORGE_SERVICE_PACK . '.php';
        $factoryInstance = new Factory();
        $factory = $factoryInstance->withServiceAccount($service);
        return $factory->createMessaging();
    }

    /**
     * @param $obj LeadingBidSurpassed|ItemLiveSoon
     * @return int|void
     */
    private function findPostId($obj)
    {
        if (PolylangSupport::isPolylangActive() && PolylangSupport::isFullSupport()) {
            $langCode = pll_default_language();
        } else {
            $langCode = '';
        }

        $posts = Lot::findLotByLotID($obj->itemId, 0, $langCode);
        if (!empty($posts) && isset($posts[0])) {
            return $posts[0]->ID;
        }
    }

    /**
     * @param $obj AuctionStartsSoon
     * @return int
     */
    private function findTermId($obj)
    {
        $auction = Auction::findAuctionById($obj->auctionId);
        if (!empty($auction->term_id)) {
            return $auction->term_id;
        } else {
            return 0;
        }
    }

    /**
     * @param $postId int
     * @return string|null
     */
    private function getFeatureImageByLotId($postId)
    {
        return LotHelper::getFeatureImageByID($postId);
    }

    /**
     * @param $obj AuctionStartsSoon
     * @param $termId int
     * @return string
     */
    private function getFeatureImageByAuctionId($obj, $termId)
    {
        $auctionDays = SettingsHelper::getTermOption($termId, 'auction_days');
        $dayIndex = (!empty($obj->dayIndex)) ? intval($obj->dayIndex) - 1 : 0;
        if (!empty($auctionDays[$dayIndex]->image)) {
            $featureImage = $auctionDays[$dayIndex]->image;
        } else {
            $featureImage = LotHelper::getPlaceholderImage();
        }
        return $featureImage;
    }

    private function auctionCatalogUpdated($obj)
    {
        if (!empty($obj->auctionId)) {
            $lotList = new LotList();
            $lotList->setPriority(2);
            // TODO: Implement Multilanguage for full delete lots
            $lotList->singleRun($obj->auctionId);
            if (!empty($lotList->getErrors())) {
                $errors = $lotList->getErrors();
                Debug::logData($errors, "lot-list-new");
            }
        }

        Auction::doClearCacheForAuctionPages();
    }

    private function auctionUpdated($obj)
    {
        $langCode = SettingsHelper::getOption("lang", 'en');
        $response = $obj->auctionsInfoByLang;
        $category = $response->{$langCode};
        $terms = [];

        if (isset($category->hidden) && $category->hidden == true) {
            return;
        }

        Auction::checkTrashTerms();

        $terms[$langCode] = $this->updateAuction($category, $langCode);

        if (PolylangSupport::isPolylangActive() && PolylangSupport::isFullSupport()) {
            $secondLangCode = MultiLanguageSupport::getSecondLangCode();
            $categorySecond = $response->{$secondLangCode};
            $terms[$secondLangCode] = $this->updateAuction($categorySecond, $secondLangCode);

            $otherLanguages = PolylangSupport::getSupportedLanguages();
            if (!empty($otherLanguages['other'])) {
                foreach ($otherLanguages['other'] as $otherLanguage) {
                    $terms[$otherLanguage] = $this->updateAuction($category, $otherLanguage);
                }
            }

            $fields = json_encode([
                "terms" => $terms,
                "defaultLang" => $langCode,
                "secondLang" => $secondLangCode,
                "other" => $otherLanguages
            ]);

            $this->translateRequest($fields);
        }

        Auction::doClearCacheForAuctionPages();
    }

    private function updateAuction($category, $mlPrefix)
    {
        $model = new Auction();
        $model->loadAttributes($category);
        $model->setDate($model->getDays());

        if (!PolylangSupport::isPolylangActive()) {
            $mlPrefix = false;
        }

        $auction = Auction::findAuctionByIdWithLang($model->getId(), $mlPrefix);
        if ($auction instanceof \WP_Term) {
            $model->setTermId($auction->term_id);
        }

        return $model->save($auction, $mlPrefix);
    }

    /**
     * @param $obj stdClass
     * @return void
     */
    private function itemsUpdated($obj)
    {
        if (!empty($obj->itemsByLanguage)) {
            $langCode = SettingsHelper::getOption("lang", 'en');
            $response = $obj->itemsByLanguage;
            $item = new stdClass();
            $itemSecond = new stdClass();

            if (PolylangSupport::isPolylangActive() && PolylangSupport::isFullSupport()) {
                $secondLangCode = MultiLanguageSupport::getSecondLangCode();
                $secondObj = (array)$response->{$secondLangCode};
                $itemSecond = $secondObj[0]->item;
            }

            if (!empty($response->{$langCode})) {
                $obj = (array)$response->{$langCode};
                $item = $obj[0]->item;

                if (!empty($obj[0]->leadingBid)) {
                    $item = $this->leadingBid($obj[0]->leadingBid, $item);
                }

                if (!empty($obj[0]->soldBid)) {
                    $item = $this->soldBid($obj[0]->soldBid, $item);
                }

                if (!empty($obj[0]->paddedIndex)) {
                    $item->paddedIndex = $obj[0]->paddedIndex;
                }
            }

            if (is_null($item)) {
                $this->setLoggedInfo(array(
                    "ITEMS_UPDATED" => array(
                        "item" => $item
                    )
                ));
                return;
            }

            $item = $this->buildItem($item, $itemSecond);

            $lot = new Lot();
            $lot->loadAttributes($item);
            $lot->setPriority(1);
            $lots[] = $lot;
            $result = Lot::bulkSave($lots);

            if ($result) {
                $this->setLoggedInfo(array(
                    "auction_id_" . $lot->getAuctionId() => array(
                        "ITEMS_UPDATED" => count($lots)
                    )
                ));
            }

            HummingbirdSupport::clearCacheByUrl(get_permalink($lot->getId()));
            Auction::doClearCacheForAuctionPages();
        }
    }

    /**
     * @param $obj stdClass
     * @return array
     */
    private function auctionPublished($obj)
    {
        $deviceTokens = FirebaseUser::deviceTokens();
        $data = array(
            'request' => array(),
            'response' => array(),
            'result' => true
        );
        $termId = $this->findTermId($obj);
        if (!empty($deviceTokens)) {
            $data["request"] = array(
                'notification' => array(
                    'title' => $obj->auctionNumber . " " . __("auction published", "auctionforge"),
                    'body' => $obj->auctionName,
                    'image' => $this->getFeatureImageByAuctionId($obj, $termId),
                    'imageUrl' => $this->getFeatureImageByAuctionId($obj, $termId)
                ),
                'data' => array(
                    'url' => get_permalink(SettingsHelper::getOption('auction_list', 0)),
                    'notificationId' => $obj->auctionId . rand(111, 999)
                )
            );

            $data = $this->sendMessage($data, $deviceTokens);
            Auction::doClearCacheForAuctionPages();
        }

        return $data;
    }

    /**
     * @param $obj
     * @return array
     */
    private function catalogPublished($obj)
    {
        $deviceTokens = FirebaseUser::deviceTokens();
        $data = array(
            'request' => array(),
            'response' => array(),
            'result' => true
        );
        $termId = $this->findTermId($obj);
        if (!empty($deviceTokens)) {
            $data["request"] = array(
                'notification' => array(
                    'title' => $obj->auctionNumber . " " . __("catalog published", "auctionforge"),
                    'body' => $obj->auctionName,
                    'image' => $this->getFeatureImageByAuctionId($obj, $termId),
                    'imageUrl' => $this->getFeatureImageByAuctionId($obj, $termId)
                ),
                'data' => array(
                    'url' => get_term_link($termId),
                    'notificationId' => $obj->auctionId . rand(111, 999)
                )
            );

            $data = $this->sendMessage($data, $deviceTokens);
            Auction::doClearCacheForAuctionPages();
        }

        return $data;
    }

    private function auctionDayEnded($obj)
    {
        $response = $obj;
        $auctionId = $response->auctionId;

        $langCode = SettingsHelper::getOption("lang", 'en');
        $term = BS_API::findAuctionByIdWithLang($auctionId, $langCode);
        Auction::updateAuctionInfo($term, $auctionId, $langCode);

        if (PolylangSupport::isPolylangActive() && PolylangSupport::isFullSupport()) {
            $secondLangCode = MultiLanguageSupport::getSecondLangCode();
            $term = BS_API::findAuctionByIdWithLang($auctionId, $secondLangCode);
            Auction::updateAuctionInfo($term, $auctionId, $secondLangCode);

            $otherLanguages = PolylangSupport::getSupportedLanguages();
            if (!empty($otherLanguages['other'])) {
                foreach ($otherLanguages['other'] as $otherLanguage) {
                    $term = BS_API::findAuctionByIdWithLang($auctionId, $otherLanguage);
                    Auction::updateAuctionInfo($term, $auctionId, $otherLanguage);
                }
            }
        }

        Auction::doClearCacheForAuctionPages();
    }

    private function auctionStateUpdated($obj)
    {
        $response = $obj;
        $auctionId = $response->auctionId;
        $state = $response->state;

        if ($auctionId == "" || $state == "") {
            return false;
        }

        $langCode = SettingsHelper::getOption("lang", 'en');
        $term = BS_API::findAuctionByIdWithLang($auctionId, $langCode);

        if (!($term instanceof \WP_Term)) {
            return false;
        }

        $prevValue = BS_API::getTermOption($term->term_id, 'auction_state');
        update_term_meta($term->term_id, 'auction_state', $state, $prevValue);

        if (PolylangSupport::isPolylangActive() && PolylangSupport::isFullSupport()) {
            $secondLangCode = MultiLanguageSupport::getSecondLangCode();
            $term = BS_API::findAuctionByIdWithLang($auctionId, $secondLangCode);
            update_term_meta($term->term_id, 'auction_state', $state, $prevValue);

            $otherLanguages = PolylangSupport::getSupportedLanguages();
            if (!empty($otherLanguages['other'])) {
                foreach ($otherLanguages['other'] as $otherLanguage) {
                    $term = BS_API::findAuctionByIdWithLang($auctionId, $otherLanguage);
                    update_term_meta($term->term_id, 'auction_state', $state, $prevValue);
                }
            }
        }

        Auction::doClearCacheForAuctionPages();

        return true;
    }

    private function announcement($obj)
    {
        $deviceTokens = FirebaseUser::deviceTokens();
        $data = [];
        if (!empty($deviceTokens)) {
            $data["request"] = array(
                'notification' => array(
                    'title' => "",
                    'body' => $obj->message,
                ),
                'data' => array(
                    'notificationId' => $obj->itemId . rand(111, 999)
                )
            );

            $data = $this->sendMessage($data, $deviceTokens);
        }
        return $data;
    }

    private function buildItem($item, $itemSecond)
    {
        $item->lotId = $item->id;
        $item->auctionSlug = $item->auctionId;
        $item->syncTimes = 0;
        $item->priority = 1;
        $item->createDatetime = date(Importer::DATE_FORMAT);

        if (isset($itemSecond->name)) {
            $item->nameL2 = $itemSecond->name;
        } else {
            $item->nameL2 = $item->name;
        }

        if (isset($itemSecond->description)) {
            $item->descriptionL2 = $itemSecond->description;
        } else {
            $item->descriptionL2 = $item->description;
        }

        if (isset($itemSecond->author)) {
            $item->authorL2 = $itemSecond->author;
        } else {
            $item->authorL2 = $item->author;
        }

        return $item;
    }

    /**
     * @param $item stdClass
     * @param $leadingBid stdClass
     * @return stdClass
     */
    private function leadingBid($leadingBid, $item)
    {
        if (!empty($leadingBid) && isset($leadingBid->price)) {
            $item->leadingBid = $leadingBid->price;
        } else {
            $item->leadingBid = 0;
        }

        return $item;
    }

    private function soldBid($soldBid, $item)
    {
        if (!empty($soldBid) && isset($soldBid->price)) {
            $item->soldBid = $soldBid->price;
        }
        return $item;
    }

    private function translateRequest($fields)
    {
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => get_option('siteurl') . '/wp-json/bidspirit/v1/translate',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $fields,
            CURLOPT_HTTPHEADER => array(
                'Bidspirit-User-Agent: Web2Application',
                'HTTP_X_BIDSPIRIT_SIGNATURE: update',
                'Content-Type: application/json'
            ),
        ));
        curl_exec($curl);
    }

    public function translate_action(WP_REST_Request $request)
    {
        if (!(isset($_SERVER['HTTP_BIDSPIRIT_USER_AGENT']) && $_SERVER['HTTP_BIDSPIRIT_USER_AGENT'] == "Web2Application")) {
            $error = new \WP_Error(500, "You shouldnt be here");
            echo $error->get_error_message();
            die;
        }

        $params = $request->get_json_params();
        pll_set_term_language($params["terms"][$params["defaultLang"]], $params["defaultLang"]);
        pll_set_term_language($params["terms"][$params["secondLang"]], $params["secondLang"]);

        if (!empty($params['other']['other'])) {
            $otherLanguages = $params['other']['other'];
            foreach ($otherLanguages as $item) {
                pll_set_term_language($params["terms"][$item], $item);
            }
        }

        pll_save_term_translations($params["terms"]);
    }
}
$instance = new SendAppNotification();
$instance->init();
