<?php

class PipMadrasahClient extends BackgroundBaseClient {

    public $token;
    public $encryptedToken;
    protected $ciphering;
    protected $options;
    protected $iv;
    protected $key;
    protected $controller;

    const PATH_LOGIN = "/ws/login";
    const PATH_TRACKING = "/ws/tracking";

    public function __construct($prop, $controller)
    {
        parent::__construct($prop);
        $this->ciphering = "AES-128-CTR";
        $this->options = 0;
        $this->iv = '1234567891011121';
        $this->key = "PipMadrasahClient";
        $this->controller = $controller;
    }

    public function setEncryptedToken($token) {
        $this->encryptedToken = $token;
    }

    public function login() {
        $username = $this->prop['username'];
        $password = $this->prop['password'];
        $params = [
            "form_params" => [
                "username" => $username,
                "password" => $password
            ],
        ];

        //region LOG Definition
        $this->setApiName("pipmadrasah-login");
        $this->setLogParams([
            'username' => $username,
            'password' => $password
        ]);
        //endregion

        try {
            $result = $this->execute("POST", self::PATH_LOGIN, $params, false);
        } catch (\Exception $e) {
            throw new CustomErrorException(BaseResponse::INVALID_AUTHENTICATION_AUTHORIZATION, "Gagal melakukan login PIP Madrasah");
        }

        if ($result['status'] && array_key_exists('data', $result) && array_key_exists('access_token', $result['data'])) {
            $this->token = $result['data']['access_token'];
        } elseif (strpos((string) $this->getErrorBody(), 'Situsweb sedang dalam perbaikan') !== false) {
            throw new CustomErrorException(BaseResponse::SERVICE_UNAVAILABLE, "Service PIP Madrasah sedang dalam perbaikan");
        } else {
            throw new CustomErrorException(BaseResponse::INVALID_AUTHENTICATION_AUTHORIZATION, "Gagal melakukan login PIP Madrasah");
        }

        return $this->token;
    }

    public function tracking($level, $nisn)
    {
        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "form_params" => [
                "level" => $level,
                "nisn" => $nisn
            ]
        ];

        //region LOG Definition
        $this->setApiName("pipmadrasah-tracking");
        $this->setLogParams([
            'level' => $level,
            'nisn' => $nisn
        ]);
        //endregion

        try {
            $response = $this->execute("POST", self::PATH_TRACKING, $params, false);
            if ($response['status'] && array_key_exists('data', $response)) {
                $result = $response['data'];
            } elseif (strpos((string) $this->getErrorBody(), 'Situsweb sedang dalam perbaikan') !== false) {
                throw new CustomErrorException(BaseResponse::SERVICE_UNAVAILABLE, "Service PIP Madrasah sedang dalam perbaikan");
            } else {
                $result = [
                    "message" => "Data tidak ditemukan"
                ];
            }
        } catch (CustomErrorException $e) {
            $result = [
                "message" => $e->getStatusCode() == 462 ? "Data tidak ditemukan." : $e->getMessages()
            ];
        } catch (\Exception $e) {
            $message = $e->getMessage();
            if ($e->getCode() == 401) {
                $message = "Belum berhasil terhubung. Mohon coba beberapa saat lagi.";
            } else if ($e->getCode() == 462) {
                $message = "Data tidak ditemukan.";
            }
            $result = [
                "message" => $message
            ];
        }

        return $result;
    }

    public function encryptToken() {
        $this->encryptedToken = openssl_encrypt($this->token, $this->ciphering, $this->key, $this->options, $this->iv);
    }

    public function decryptToken() {
        $this->token = openssl_decrypt($this->encryptedToken, $this->ciphering, $this->key, $this->options, $this->iv);
    }

    public function distribusiByJenjang($tahun, $level = null) {
        $method = "GET";
        $path = "/ws/distribusiJenjang";
        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => [
                "tahun" => $tahun,
            ]
        ];

        if($level != null)
            $params["query"]["level"] = $level;

        $this->setApiName("pipmadrasah-distribusiByJenjang");
        return $this->execute($method, $path, $params, false, true);
    }

    public function distribusiWilayah($tahun, $province, $city) {
        $method = "GET";
        $path = "/ws/distribusiWilayah";
        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => [
                "tahun" => $tahun,
                "province" => $province,
                "city" => $city,
            ]
        ];

        $this->setApiName("pipmadrasah-distribusiWilayah");
        return $this->execute($method, $path, $params, false);
    }

    public function distribusiNasional($tahun, $province = null) {
        $method = "GET";
        $path = "/ws/distribusiNasional";
        $params = [
            "headers" => [
                "Authorization" => "Bearer " . $this->getExistingToken()
            ],
            "query" => [
                "tahun" => $tahun
            ]
        ];

        if($province != null)
            $params["query"]["province"] = $province;

        $this->setApiName("pipmadrasah-distribusiNasional");
        sleep(1);
        return $this->execute($method, $path, $params, false, true);
    }

    private function getExistingToken(): string
    {
        $this->token = ApiToken::findTokenOrCreateOne("PIP_MADRASAH", "1 hour", array($this, "login"));
        return $this->token;
    }
}

