<?php


namespace DetailTask;

use ApiTracker;
use BimaClient;
use LogHelper;
use RSOnlineClient;
use RumahSakitOnline;
use RumahSakitOnlineKetersediaantt;

/**
 * @property RSOnlineClient $client
 */
class RumahSakitOnlineTask extends AbstractTask
{
    #region Attributes
    private $page;
    private $limit;
    private $offset;
    private $totalPage;
    private $objectProcessed;
    /**
     * @var ApiTracker
     */
    private $apiTracker;
    #endregion

    public function init()
    {
        // $this->client = new BimaClient();
        // $this->client->login();
        $this->client = new RSOnlineClient($this->config["rs_online_config"]);
        $this->client->setLogger($this->logger);
        $this->page = 1;
        $this->limit = 100;
        $this->offset = 0;
        $this->totalPage = 1;
        $this->objectProcessed = 0;
    }

    #regionRumahSakit

    /**
     * @return void
     * Logging disimpan ke table api_errors
     */
    public function processRumahSakit()
    {
        $this->init();
        $this->apiTracker = $this->getTrackerList();
        $needToProcess = $this->apiTracker->lastProcessedOverDays(3) || !$this->apiTracker->last_processed_value->allSuccess;
        if ($needToProcess) {
            try {
                $this->processSinglePage();
                while($this->page < $this->totalPage) {
                    $this->page++;
                    $this->processSinglePage();
                }
                $this->updateTrackerList();
            } catch (\Exception $e) {
                $this->logError($e->getMessage());
                $this->updateTrackerList($e->getMessage());
            }
        }
    }

    private function processSinglePage()
    {
        $result = $this->client->rumahSakits([
            "page" => $this->page,
            "limit" => $this->limit
        ]);
        $this->totalPage = $result["pagination"]["total_number_of_pages"];
        $this->objectProcessed = 0;
        foreach ($result["data"] as $r) {
            RumahSakitOnline::rawToModel($r)->save();
            $this->objectProcessed++;
        }
        $this->logInfo();
    }

    private function getTrackerList()
    {
        $apiTracker = ApiTracker::findFirstByName(ApiTracker::RUMAH_SAKIT_ONLINE_LIST);
        if (!$apiTracker) {
            $apiTracker = new ApiTracker();
            $apiTracker->name = ApiTracker::RUMAH_SAKIT_ONLINE_LIST;
            $apiTracker->last_processed_value = (object) array("page" => $this->page, "allSuccess" => 0);
            $this->page = 1;
        } else {
            $apiTracker->last_processed_value = json_decode($apiTracker->last_processed_value);
            $this->page = $apiTracker->last_processed_value->page;
        }

        return $apiTracker;
    }

    private function updateTrackerList($lastError = null)
    {
        if ($this->apiTracker) {
            $this->apiTracker->last_update_date = date('Y-m-d H:i:s');
            $this->apiTracker->last_processed_value = json_encode([
                "page" => $this->page >= $this->totalPage ? 1 : $this->page,
                "allSuccess" => $this->page >= $this->totalPage && $this->totalPage > 1 ? 1 : 0
            ]);
            $this->apiTracker->last_error = $lastError;
            $this->apiTracker->save();
        }
    }
    #endregion

    #regionKetersediaanTT
    /**
     * @return void
     * Logging disimpan ke table api_errors
     */
    public function processKetersediaanTt()
    {
        $this->init();
        try {
            $this->apiTracker = $this->getTrackerKetersediaanTt();
            $kabKotaIds = $this->getKabKotaIds();
            foreach ($kabKotaIds as $kabKotaId) {
                $this->processSinglePemda($kabKotaId);
                $this->prepareForNextPemda();
            }
            $this->updateTrackerKetersediaanTt();
        } catch (\Exception $e) {
            $this->logError($e->getMessage());
            $this->updateTrackerKetersediaanTt($e->getMessage());
        }
    }

    private function getTrackerKetersediaanTt()
    {
        $apiTracker = ApiTracker::findFirstByName(ApiTracker::RUMAH_SAKIT_ONLINE_KETERSEDIAAN_TT);
        if (!$apiTracker) {
            $apiTracker = new ApiTracker();
            $apiTracker->name = ApiTracker::RUMAH_SAKIT_ONLINE_KETERSEDIAAN_TT;
            $apiTracker->last_processed_value = (object) array("offset" => $this->offset, "page" => $this->page);
            $this->page = 1;
        } else {
            $apiTracker->last_processed_value = json_decode($apiTracker->last_processed_value);
            $this->page = $apiTracker->last_processed_value->page;
            $this->offset = $apiTracker->last_processed_value->offset;
        }

        return $apiTracker;
    }

    private function updateTrackerKetersediaanTt($lastError = null)
    {
        if ($this->apiTracker) {
            $this->apiTracker->last_update_date = date('Y-m-d H:i:s');
            $this->apiTracker->last_processed_value = json_encode([
                "offset" => $this->offset,
                "page" => $this->page
            ]);
            $this->apiTracker->last_error = $lastError;
            $this->apiTracker->save();
        }
    }

    private function getKabKotaIds()
    {
        $kabKotas = \MasterKotaKabupaten::find([
            "columns" => "distinct kota_kabupaten_code",
            "limit" => 100,
            "offset" => $this->offset,
            "order" => "kota_kabupaten_code"
        ]);
        if (empty($kabKotas->toArray())) {
            $this->offset = 0;
            $kabKotas = \MasterKotaKabupaten::find([
                "columns" => "distinct kota_kabupaten_code",
                "limit" => 100,
                "offset" => $this->offset,
                "order" => "kota_kabupaten_code"
            ]);
        }

        return array_column($kabKotas->toArray(), "kota_kabupaten_code");
    }

    private function prepareForNextPemda()
    {
        $this->page = 1;
        $this->offset = $this->offset + 1;
    }

    private function processSinglePemda($kabKotaId)
    {
        $this->processSinglePagePemda($kabKotaId);
        while ($this->page < $this->totalPage) {
            $this->page++;
            $this->processSinglePagePemda($kabKotaId);
        }
    }

    private function processSinglePagePemda($kabKotaId)
    {
        $provinsiId = substr($kabKotaId, 0, 2);
        $result = $this->client->ketersediaanTempatTidur([
            "provinsiId" => $provinsiId,
            "kabKotaId" => $kabKotaId,
            "page" =>  $this->page,
            "limit" => 100
        ]);
        $this->totalPage = $result["pagination"]["total_number_of_pages"];
        $this->objectProcessed = 0;
        foreach ($result["data"] as $r) {
            RumahSakitOnlineKetersediaantt::saveRawData($r);
            $this->objectProcessed++;
        }
        $this->logInfo([
            "_offset" => $this->offset,
            "_kabKotaId" => $kabKotaId
        ]);
    }
    #endregion

    private function logInfo($additionalInfo = [])
    {
        $info = array_merge([
            "_objects_processed" => $this->objectProcessed,
            "_page" => $this->page,
            "_limit" => $this->limit
        ], $additionalInfo);
        LogHelper::logInfo(
            "Scheduled Task Process Rumah Sakit",
            $this->client->getStartTime(),
            $this->client->getEndTime(),
            $info,
            self::LOG_TYPE,
            $this->logger
        );
    }

    private function logError($message, $additionalParam = "")
    {
        $param = "page=".$this->page."&limit=".$this->limit.$additionalParam;
        $this->logApiError("ScheduledTaskProcessRumahSakit", $param, $message);
    }
}
