<?php

namespace DetailTask;

use ActivityService;
use ApiErrorsService;
use AppConfig;
use ElhkpnMartService;
use LogEmail;
use LogHelper;
use LogNotification;
use MailHelper;
use MeiliSearchService;
use NotificationHelper;

class LocalTask extends AbstractTask {
    private $startTime;
    private $processedObject;

    public function init()
    {
        $this->processedObject = 0;
        $this->startTime = microtime(true);
    }

    public function finished($isError = false, $errorMessage = null) {
        if (!$isError) {
            LogHelper::logInfo(
                $this->processName,
                $this->startTime,
                microtime(true),
                [
                    ":processed_object" => $this->processedObject
                ],
                self::LOG_TYPE,
                $this->logger
            );
        } else {
            LogHelper::logInfo(
                $this->processName . " ended with exception",
                $this->startTime,
                microtime(true),
                [
                    ":processed_object" => $this->processedObject,
                    ":message" => $errorMessage
                ],
                self::LOG_TYPE,
                $this->logger
            );
        }
    }

    /**
     * @return void
     * Logging disimpan ke file log
     */
    public function processLogEmail()
    {
        $this->init();
        $this->processName = "Process Log Email Task";
        try {
            $limit = AppConfig::getValueByKode("LIMIT_MAIL_BACKGROUND") ?? 10;
            $mails = LogEmail::find([
                'conditions' => 'status = :new: or status = :failed:',
                'limit' => $limit,
                'order' => 'created_at',
                'bind' => [
                    'new' => LogEmail::STATUS_NEW,
                    'failed' => LogEmail::STATUS_FAILED
                ],
            ]);

            $mailHelper = new MailHelper($this->config["mail_config"]);
            foreach ($mails as $mail) {
                /** @var $mail LogEmail */
                $mail->send($mailHelper);
                $this->processedObject++;
            }
            $this->finished();
        } catch (\Exception $e) {
            $this->finished(true, $e->getMessage());
        }
    }

    /**
     * @return void
     * Logging disimpan ke file log
     */
    public function processNotifQuota()
    {
        $this->init();
        $this->processName = "Process Notif Quota Diskusi Task";
        try {
            $result = $this->rawQuery("
            SELECT DISTINCT (user_id) as user_id FROM jaga.log_quota_errors WHERE CAST(:current_date AS date) - CAST(created_at AS date) = 8
        ", ['current_date' => date("Y-m-d")]);

            $body = $this->config["quota_notification_body"];
            $bodyEn = $this->config["quota_notification_body_en"];
            $senderUserId = "-1";
            $action = NotificationHelper::ACTION_DISKUSI;
            $actionId = "";
            $clickAction = "diskusi/kumpulan";
            foreach ($result as $res) {
                $userId = $res["user_id"];
                NotificationHelper::sendDirect($userId, $senderUserId, $body, $action, $actionId, $clickAction, NotificationHelper::CATEGORY_DISCUSSION, $bodyEn);
                $this->processedObject++;
            }
            $this->finished();
        } catch (\Exception $e) {
            $this->finished(true, $e->getMessage());
        }
    }

    /**
     * @return void
     * Logging disimpan ke file log
     */
    public function processRecommendation()
    {
        $this->init();
        $this->processName = "Process Activity Recommendation Task";
        try {
            // C:\xampp\php\php.exe cli\cli.php scheduled main process_recommendation
            $service = new ActivityService(0, $this->logger);
            $service->processRecomendation();
            $this->finished();
        } catch (\Exception $e) {
            $this->finished(true, $e->getMessage());
        }
    }

    /**
     * @return void
     * Logging disimpan ke file log
     */
    public function processLogApiError()
    {
        $this->init();
        $this->processName = "Process Log Api Error Task";
        try {
            $apiLog = new ApiErrorsService($this->config);
            $apiLog->process_notif();
            $this->finished();
        } catch (\Exception $e) {
            $this->finished(true, $e->getMessage());
        }
    }

    /**
     * @param $year
     * @return void
     * Logging disimpan ke file log
     */
    public function processElhkpnMart($year)
    {
        $this->init();
        $this->processName = "Process ELHKPN Mart Task";
        try {
            if (!$year) {
                throw new \Exception('ELHKPN Mart Years not set');
            }
            $service = new ElhkpnMartService($this);
            $service->syncData($year);
            $this->finished();
        } catch (\Exception $e) {
            $this->finished(true, $e->getMessage());
        }
    }

    /**
     * @return void
     * Logging disimpan ke file log
     */
    public function processMeilisearch() {
        $this->init();
        $this->processName = "Process Meilisearch Task";
        try {
            $meilisearchService = new MeiliSearchService($this);
            $meilisearchService->generateDataMeiliSearch();
            $this->processedObject = $meilisearchService->getObjectsProcessed();
            $this->finished();
        } catch (\Exception $e) {
            if (isset($meilisearchService)) {
                $this->processedObject = $meilisearchService->getObjectsProcessed();
            }
            $this->finished(true, $e->getMessage());
        }
    }

    /**
     * @return void
     * Logging disimpan ke file log
     */
    public function processLogNotification() {
        $this->init();
        $this->processName = "Process Log Notification Task";
        try {
            $limit = AppConfig::getValueByKode("LIMIT_NOTIF_BACKGROUND") ?? 30;
            $notifications = LogNotification::find([
                'conditions' => 'status = :new:',
                'limit' => $limit,
                'order' => 'created_at',
                'bind' => [
                    'new' => LogNotification::STATUS_NEW
                ],
            ]);

            foreach ($notifications as $notification) {
                /** @var $notification LogNotification */
                $notification->send();
                $this->processedObject++;
            }
            $this->finished();
        } catch (\Exception $e) {
            $this->finished(true, $e->getMessage());
        }
    }
}
