<?php

namespace auctionforge\inc\controllers;

use stdClass;
use auctionforge\inc\abs\BidspiritWebhooks;
use auctionforge\inc\abs\Importer;
use auctionforge\inc\Debug;
use auctionforge\inc\helpers\SettingsHelper;
use auctionforge\inc\import\LotList;
use auctionforge\inc\model\Auction;
use auctionforge\inc\model\Lot;
use auctionforge\inc\traits\LoggerInfo;
use WP_REST_Request;

class WebhooksSync extends BidspiritWebhooks
{
    use LoggerInfo;

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

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

        $namespace = self::API_NAMESPACE;

        $rout = '/sync';

        $rout_params = array(
            'methods' => 'POST',
            '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');

        if (md5(AUCTIONFORGE_API_TOKEN . "_" . $requestBody) == $signature) {
            $obj = json_decode($requestBody);
            switch ($obj->notificationType) {
                case "AUCTION_CATALOG_UPDATED":
                    $this->auctionCatalogUpdated($obj);
                    break;
                case "AUCTION_UPDATED":
                    $this->auctionUpdated($obj);
                    break;
                case "ITEMS_UPDATED":
                    $this->itemsUpdated($obj);
                    break;
                case "TEST":
                    $this->test($obj);
                    break;
            }

            $response->success = true;
        } else {
            $response->success = false;
            $response->notify = false;
            $response->error = "Bad signature";
        }

        echo json_encode($response);
    }

    private function auctionCatalogUpdated($obj)
    {
        if (!empty($obj->auctionId)) {
            $lotList = new LotList();
            $lotList->setPriority(2);
            $lotList->singleRun($obj->auctionId);
            if (!empty($lotList->getErrors())) {
                $errors = $lotList->getErrors();
                var_dump($errors);
                Debug::logData($errors, "lot-list-new");
            }
        }

        Auction::doClearCacheForAuctionPages();
    }

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

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

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

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

            $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;
//            Debug::dumpFile("test1");
        } else {
//            Debug::dumpFile("pll active");
        }

        $auction = Auction::findAuctionByIdWithLang($model->getId(), $mlPrefix);
        if ($auction instanceof \WP_Term) {
            $model->setTermId($auction->term_id);
//            Debug::dumpFile(["test2", $auction]);
        }

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

    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_X_BIDSPIRIT_SIGNATURE'])) {
            $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"]);
        pll_save_term_translations($params["terms"]);
    }

    /**
     * @param $obj stdClass
     * @return array
     */
    private function test($obj)
    {
        //
        return array();
    }
}
$instance = new WebhooksSync();
$instance->init();
