<?php
class SigClient extends BackgroundBaseClient
{
    const API_NAME_SIG = 'SIG';
    const PPG_URL_PREFIX = "api/api/integrasi-jaga/ppg/";
    private $token;
    protected $controller;

    public function __construct($prop, $controller)
    {
        parent::__construct($prop);
        $this->controller = $controller;
    }

    public function filterResponse($body, $result) {
        //NOTE: Logger harus diset dari controller, karena didapat dari DI.
        parent::filterResponse($body, $result);
        if($this->logger != null) {
            if (!empty($result)) {
                if(array_key_exists('message', $result)) {
                    if($result['status_code'] != 0) {
                        $this->logger->addItem("api_result_code", $result['status_code']);
                        if (array_key_exists('message', $result)) $this->logger->addItem("api_result_message", $result['message']);
                    }
                }
            }
        }
    }

    private function authAndSetToken() {
        $method = 'POST';
        $path = '/api/oauth/token';
        $params = [
            "headers" => [
                "Content-Type" => "application/json"
            ],
            "json" => [
                "grant_type" => AppConfig::getValueByKode('SIG_GRANT_TYPE'),
                "client_id" => AppConfig::getValueByKode('SIG_CLIENT_ID'),
                "client_secret" => AppConfig::getValueByKode('SIG_CLIENT_SECRET'),
            ]
        ];

        //region LOG Definition
        $this->setApiName("sig-oauth_token");
        $this->setLogParams($params['json']);
        //endregion

        $res = $this->execute($method, $path, $params);
        $this->token = $res['access_token'];
    }

    public function instansiWilayah($keyword, $src, $limit, $offset) {
        $method = "GET";
        $path = "/api/api/integrasi-jaga/instansi-wilayah";
        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => [
                "keyword" => $keyword,
                "src" => $src,
                "limit" => $limit,
                "offset" => $offset,
            ]
        ];

        //region LOG Definition
        $this->setApiName("sig-instansi_wilayah");
        $this->setLogParams($params['query']);
        //endregion

        try {
            $result = $this->execute($method, $path, $params, false);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    public function grafik($idInstansi, $kodeProvinsi, $kodeKotaKabupaten, $tahun) {
        $method = "GET";
        $path = "/api/api/integrasi-jaga/grafik";

        $q = [
            'tahun' => $tahun
        ];

        if($idInstansi > 0)$q['id_instansi'] = $idInstansi;
        if($kodeProvinsi > 0)$q['kode_provinsi'] = $kodeProvinsi;
        if($kodeKotaKabupaten != 0)$q['kode_kota_kabupaten'] = $kodeKotaKabupaten;

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $q
        ];

        //region LOG Definition
        $this->setApiName("sig-grafik");
        $this->setLogParams($params['query']);
        //endregion

        try {
            $result = $this->execute($method, $path, $params, false);
        }
        catch (\Exception $e) {
            $this->deleteToken();
            throw $e;
        }
        return $result;
    }

    public function tabel($idInstansi, $kodeProvinsi, $kodeKotaKabupaten, $tahun, $limit, $offset, $orderBy, $orderDirection) {
        $method = "GET";
        $path = "/api/api/integrasi-jaga/tabel";

        $q = [
            "tahun" => $tahun,
            "limit" => $limit,
            "offset" => $offset,
            "order_by" => $orderBy,
            "order_direction" => $orderDirection
        ];

        if($idInstansi > 0)$q['id_instansi'] = $idInstansi;
        if($kodeProvinsi > 0)$q['kode_provinsi'] = $kodeProvinsi;
        if($kodeKotaKabupaten != 0)$q['kode_kota_kabupaten'] = $kodeKotaKabupaten;

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $q
        ];

        //region LOG Definition
        $this->setApiName("sig-tabel");
        $this->setLogParams($params['query']);
        //endregion

        try {
            $result = $this->execute($method, $path, $params, false);
        }
        catch (Exception $e){
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    #region PPG
    public function tahunMonev() {
        $path = self::PPG_URL_PREFIX . "tahun-monev";
        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ]
        ];

        //region LOG Definition
        $this->setApiName("sig-tahun_monev");
        //endregion

        try {
            $result = $this->execute('GET', $path, $params, false);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    public function peringkatMonev(
        $limit, $offset, $src, $tahun, $status = "ALL", $instansi_id = 0, $kode_provinsi = 0, $kode_kota_kabupaten = 0
    ) {
        $path = self::PPG_URL_PREFIX . "peringkat-monev";
        $query = [
            "limit" => $limit,
            "offset" => $offset,
            "src" => $src,
            "tahun" => $tahun,
            "status" => $status
        ];

        if ($instansi_id > 0) $query["instansi_id"] = $instansi_id;
        if ($kode_provinsi > 0) $query["kode_provinsi"] = $kode_provinsi;
        if ($kode_kota_kabupaten > 0) $query["kode_kota_kabupaten"] = $kode_kota_kabupaten;

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $query
        ];

        //region LOG Definition
        $this->setApiName("sig-peringkat_monev");
        $this->setLogParams($query);
        //endregion

        try {
            $result = $this->execute('GET', $path, $params, false);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    public function exportPeringkatMonev(
        $src, $tahun, $status = "ALL", $instansi_id = 0, $kode_provinsi = 0, $kode_kota_kabupaten = 0
    ) {
        $path = self::PPG_URL_PREFIX . "export-peringkat-monev";
        $query = [
            "src" => $src,
            "tahun" => $tahun,
            "status" => $status
        ];

        if ($instansi_id > 0) $query["instansi_id"] = $instansi_id;
        if ($kode_provinsi > 0) $query["kode_provinsi"] = $kode_provinsi;
        if ($kode_kota_kabupaten > 0) $query["kode_kota_kabupaten"] = $kode_kota_kabupaten;

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $query,
            "stream" => true
        ];

        //region LOG Definition
        $this->setApiName("sig-export_peringkat_monev");
        $this->setLogParams($query);
        //endregion

        try {
            $client = new GuzzleHttp\Client([
                'base_uri' => $this->prop["server"],
                'verify' => false
            ]);

            $result = $client->get($path, $params);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    public function mapAvgMonevDaerah(
        $tahun, $status = "ALL", $level = "NASIONAL", $kode_wilayah = 0
    ) {
        $path = self::PPG_URL_PREFIX . "map-avg-monev-daerah";
        $query = [
            "tahun" => $tahun,
            "status" => $status,
            "level" => $level
        ];
        if ($kode_wilayah > 0) $query["kode_wilayah"] = $kode_wilayah;

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $query
        ];

        //region LOG Definition
        $this->setApiName("sig-map_avg_monev_daerah");
        $this->setLogParams($query);
        //endregion

        try {
            $result = $this->execute('GET', $path, $params, false);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    public function avgMonevDaerah(
        $tahun, $status = "ALL", $level = "NASIONAL", $kode_wilayah = 0
    ) {
        $path = self::PPG_URL_PREFIX . "avg-monev-daerah";
        $query = [
            "tahun" => $tahun,
            "status" => $status,
            "level" => $level
        ];
        if ($kode_wilayah > 0) $query["kode_wilayah"] = $kode_wilayah;

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $query
        ];

        //region LOG Definition
        $this->setApiName("sig-avg_monev_daerah");
        $this->setLogParams($query);
        //endregion

        try {
            $result = $this->execute('GET', $path, $params, false);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    public function avgMonevKL(
        $tahun, $status = "ALL", $instansi_id = null
    ) {
        $path = self::PPG_URL_PREFIX . "avg-monev-kl";
        $query = [
            "tahun" => $tahun,
            "status" => $status
        ];
        if (!empty($instansi_id)) {
            $query["instansi_id"] = $instansi_id;
        }

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $query
        ];

        //region LOG Definition
        $this->setApiName("sig-avg_monev_kl");
        $this->setLogParams($query);
        //endregion

        try {
            $result = $this->execute('GET', $path, $params, false);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }

    public function avgKomponenMonev(
        $src, $tahun, $status = "ALL", $instansi_id = 0, $kode_provinsi = 0, $kode_kota_kabupaten = 0
    ) {
        $path = self::PPG_URL_PREFIX . "avg-komponen-monev";
        $query = [
            "src" => $src,
            "tahun" => $tahun,
            "status" => $status
        ];
        if ($instansi_id > 0) $query["instansi_id"] = $instansi_id;
        if ($kode_provinsi > 0) $query["kode_provinsi"] = $kode_provinsi;
        if ($kode_kota_kabupaten > 0) $query["kode_kota_kabupaten"] = $kode_kota_kabupaten;

        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => $query
        ];

        //region LOG Definition
        $this->setApiName("sig-avg_komponen_monev");
        $this->setLogParams($query);
        //endregion

        try {
            $result = $this->execute('GET', $path, $params, false);
        }
        catch (Exception $e) {
            $this->deleteToken();
            throw $e;
        }

        return $result;
    }
    #endregion

    private function getExistingToken() {
        $q = "SELECT *, (NOW() - created_at > INTERVAL '360 days') AS is_expired FROM api_token WHERE api_name = 'SIG'";
        $tokenData = $this->controller->rawQuery($q);
        if(empty($tokenData)) {
            $this->getNewToken();
        }
        else {
            foreach ($tokenData as $tokenDatum) {
                date_default_timezone_set('Asia/Bangkok');
                if($tokenDatum['is_expired']) {
                    $dQuery = "DELETE FROM jaga.api_token WHERE api_name = 'SIG' AND token = '" .$tokenDatum['token'] . "'";
                    $this->controller->rawQuery($dQuery);
                }
                else {
                    $this->token = $tokenDatum['token'];
                }
            }
            if(empty($this->token)) {
                $this->getNewToken();
            }
        }
        return $this->token;
    }

    private function deleteToken() {
        $dQuery = "DELETE FROM jaga.api_token WHERE api_name = 'SIG'";
        $this->controller->rawQuery($dQuery);
    }

    private function getNewToken() {
        $this->authAndSetToken();
        $newData = new ApiToken();
        $newData->api_name = self::API_NAME_SIG;
        $newData->token = $this->token;
        $newData->save();
    }
}
