<?php
class Kip2Client extends BackgroundBaseClient
{
    private $token;

    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('status', $result)) {
                    if($result['status'] != 0) {
                        $this->logger->addItem("api_result_code", $result['status']);
                        if (array_key_exists('message', $result)) $this->logger->addItem("api_result_message", $result['message']);
                    }
                }
            }
        }
    }

    private function hashPassword() {
        return hash("sha512", $this->prop['secret']);
    }

    private function auth() {
        $method = "POST";
        $path = "/h2h/auth/token";
        $params = [
            "headers" => [
                "Content-Type" => "application/x-www-form-urlencoded"
            ],
            "form_params" => [
                "app_id" => $this->prop["app_id"],
                "p" => $this->hashPassword()
            ]
        ];

        //region LOG Definition
        $this->setApiName("kip2-get_token");
        $this->setLogParams($params['form_params']);
        //endregion

        $res = $this->execute($method, $path, $params, false);
        $this->token = $res["data"]["token"];
    }

    public function getProfileSiswa($tahun, $jenjang, $nisn) {
        $this->auth();

        $method = "GET";
        $path = "/h2h/check/nisn";
        $params = [
            "headers" => [
                "app" => $this->prop["app_id"],
                "token" => $this->token
            ],
            "query" => [
                "y" => $tahun,
                "l" => $jenjang,
                'nisn' => $nisn
            ]
        ];

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

        return $this->execute($method, $path, $params, false);
    }

    /**
     * @param $nisn
     * @return stdClass
     * @throws CustomErrorException
     */
    public function pipSiswa($nisn) {
        $this->auth();

        $method = "GET";
        $path = "/h2h/siswa/nisn/all";
        $params = [
            "headers" => [
                "app" => $this->prop["app_id"],
                "token" => $this->token
            ],
            "query" => [
                'nisn' => $nisn
            ]
        ];

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

        $response = $this->execute($method, $path, $params, false);
        return $this->handleResponsePipSiswa($response, $nisn);
    }

    private function handleResponsePipSiswa($response, $nisn) {
        $result = new stdClass();
        $result->nisn = $nisn;
        $result->kelas = "";
        $result->sekolah = "";
        $result->nama = "";
        $result->bank = "";
        $result->pengusul = "";
        $result->tahun_nominasi = "";
        $result->no_sk_nominasi = "";
        $result->no_sk = "-";
        $result->tanggal_aktivasi = "";
        $result->tanggal_cair = "";
        $result->keterangan = "apabila ada ketidaksesuaian pada data di atas, silakan gunakan fitur live chat di kanan bawah.";

        if ((int)$response['status'] == 0 && array_key_exists('data', $response)) {
            $data = $response['data'];
            $pemberianKey = 'pemberian';
            $nominasiKey = 'nominasi';
            if (array_key_exists($pemberianKey, $data) && !empty($data[$pemberianKey])) {
                $keys = array_keys($data[$pemberianKey]);
                $latestKey = max($keys);
                $pemberian = $data[$pemberianKey][$latestKey];
                $result->kelas = $pemberian["kelas"] ?? "-";
                $result->sekolah = $pemberian["sekolah"] ?? "-";
                $result->nama = $pemberian["nama"] ?? "-";
                $result->bank = $pemberian["bank"] ?? "-";
                $result->no_sk = $pemberian["no_sk"] ?? "-";
                try {
                    if (!empty($pemberian["tanggal_cair"])) {
                        $date = new DateTime($pemberian["tanggal_cair"]);
                        $result->tanggal_cair = DateHelper::formatFromDate($date->format('Y'), $date->format('m'), $date->format('d'));
                    } else {
                        $result->tanggal_cair = "-";
                    }
                } catch (\Exception $e) {
                    $result->tanggal_cair = $pemberian["tanggal_cair"] ?? "-";
                }
            } else {
                $this->createApiLogError("Data pemberian tidak tersedia");
            }
            if (array_key_exists($nominasiKey, $data) && !empty($data[$nominasiKey])) {
                $keys = array_keys($data[$nominasiKey]);
                $latestKey = max($keys);
                $nominasi = $data[$nominasiKey][$latestKey];
                $result->pengusul = $nominasi["pengusul"] ?? "-";
                $result->pengusul = explode("_", $result->pengusul)[0];
                $result->tahun_nominasi = $nominasi["tahun"] ?? "-";
                $result->no_sk_nominasi = $nominasi["no_sk"] ?? "-";

                $result->kelas = empty($result->kelas) ? ($nominasi["kelas"] ?? "-") : $result->kelas;
                $result->sekolah = empty($result->sekolah) ? ($nominasi["sekolah"] ?? "-") : $result->sekolah;
                $result->nama = empty($result->nama) ? ($nominasi["nama"] ?? "-") : $result->nama;
                $result->bank = empty($result->bank) ? ($nominasi["bank"] ?? "-") : $result->bank;
                try {
                    if (!empty($nominasi["tanggal_aktivasi"])) {
                        $date = new DateTime($nominasi["tanggal_aktivasi"]);
                        $result->tanggal_aktivasi = DateHelper::formatFromDate($date->format('Y'), $date->format('m'), $date->format('d'));
                    } else {
                        $result->tanggal_aktivasi = "-";
                    }
                } catch(\Exception $e) {
                    $result->tanggal_aktivasi = $nominasi["tanggal_aktivasi"] ?? "-";
                }
            } else {
                $this->createApiLogError("Data nominasi tidak tersedia");
            }
        } else {
            $api_params = http_build_query($this->logParams ?? $params['query'] ?? []);
            LogHelper::apiLogError($this->apiName ?? get_called_class(), $api_params, "Unexpected response: " . http_build_query($response));

            if ((int)$response['status'] == 15 && array_key_exists('message', $response)) {
                throw new CustomErrorException(BaseResponse::DATA_NOT_AVAILABLE, $response['message']);
            }
        }

        return $result;
    }

    public function getRekapAktivasiRekening($tahun, $npsn) {
        $this->auth();

        $method = "GET";
        $path = "/h2h/sekolah/aktivasi";
        $params = [
            "headers" => [
                "app" => $this->prop["app_id"],
                "token" => $this->token
            ],
            "query" => [
                "tahun" => $tahun,
                'npsn' => $npsn
            ]
        ];

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

        return $this->execute($method, $path, $params, false);
    }

    public function getDataSekolah($tahun, $npsn) {
        $this->auth();

        $method = "GET";
        $path = "/h2h/sekolah/npsn";
        $params = [
            "headers" => [
                "app" => $this->prop["app_id"],
                "token" => $this->token
            ],
            "query" => [
                "tahun" => $tahun,
                'npsn' => $npsn
            ]
        ];

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

        return $this->execute($method, $path, $params, false);
    }

    public function getAlokasi($tahun) {
        $this->auth();

        $method = "GET";
        $path = "/h2h/alokasi";
        $params = [
            "headers" => [
                "app" => $this->prop["app_id"],
                "token" => $this->token
            ],
            "query" => [
                "tahun" => $tahun
            ]
        ];

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

        return $this->execute($method, $path, $params, false);
    }

    public function getRekap($tahun) {
        $this->auth();

        $method = "GET";
        $path = "/h2h/rekap";
        $params = [
            "headers" => [
                "app" => $this->prop["app_id"],
                "token" => $this->token
            ],
            "query" => [
                "tahun" => $tahun,
                "tipe" => 'pemberian' //NOTE: Hardcoded 'pemberian' karena hanya perlu yg pemberian saja, sudah ditentukan pada meet 7 Agustus 2023 (bisa 'nominasi'/'pemberian')
            ]
        ];

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

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

    private function createApiLogError($log) {
        $api_params = http_build_query($this->logParams ?? $params['query'] ?? []);
        LogHelper::apiLogError($this->apiName ?? get_called_class(), $api_params, $log);
    }
}
