<?php

class RistekdiktiController extends BaseController
{
    public function list_pt()
    {
        $getParams = $this->request->get();

        $getParams['limit'] = $this->getDefaultLimit($getParams);
        $getParams['offset'] = array_key_exists('offset', $getParams) ? $getParams['offset'] : 0;
        $getParams['keyword'] = array_key_exists('keyword', $getParams) ? $getParams['keyword'] : '';

        $params = $this->validate(
            $getParams,
            [
                'limit' => ['validators' => ['digit']],
                'offset' => ['validators' => ['digit']],
                'keyword' => ['validators' => []]
            ]
        );

        $ki_list = PerguruanTinggi::find([
            'conditions' => 'nama ilike :keyword:',
            'bind' => [
                'keyword' => '%' . $params['keyword'] . '%'
            ],
            'limit' => $params['limit'],
            'offset' => $params['offset']
        ]);

        $total_record = PerguruanTinggi::count();

        return new PaginatedResponse($ki_list, $total_record, $params['limit'], $params['offset']);
    }
    public function detail($id_pt)
    {
        $pt = PerguruanTinggi::findFirstByKode($id_pt);
        if (empty($pt)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id' . $id_pt . 'tidak diketemukan');
        endif;

        $result = $pt->toDetail();
        return new CollectionPaginatedResponse([$result]);
    }

    public function detailFromLocal($id_pt)
    {
        $pt = PerguruanTinggi::query()
            ->where('id_pt = :id_pt:')
            ->bind([
                'id_pt' => $id_pt
            ])
            ->execute()
            ->toArray();

        $pt_anggaran = PerguruanTinggi::query()
            ->columns(
                'PtInfoAnggaran.nama, PtOutputAnggaran.anggaran_boptn, PtInfoAnggaran.tahun, PtOutputAnggaran.anggaran_pnbp, PtOutputAnggaran.anggaran_bpptnbh'
            )
            ->join('PtOutputAnggaran', 'PtOutputAnggaran.id_pt = PerguruanTinggi.id_pt')
            ->join('PtInfoAnggaran', 'PtInfoAnggaran.id = PtOutputAnggaran.id_info_anggaran')
            ->where('PerguruanTinggi.id_pt = :id:')
            ->bind([
                'id' => $id_pt
            ])
            ->execute();

        $pt[0]['info_anggaran'] = $pt_anggaran;
        if (empty($pt)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id' . $id_pt . 'tidak diketemukan');
        endif;
        $result = $pt;
        return new CollectionPaginatedResponse($result);
    }
    public function liveProfile()
    {
        $ristekdiktiClient = new RistekdiktiClient($this->config["ristekdikti_prop"]);
        $params = $this->validate(
            $this->request->get(),
            [
                "kode" => ['validators' => []],
                "nama" => ['validators' => []],
            ]
        );

        $ristekdiktiClient->setLogger($this->logger);
        try {
            $result = $ristekdiktiClient->getPtbyName($params['nama']);

            return new CollectionPaginatedResponse($result);
        } catch (\Exception $ex) {
            $api_params = http_build_query($params);
            $this->apiLog->log_error("Ristekdikti - getPtbyName", $api_params, $ristekdiktiClient->getErrorBody());
            throw $ex;
        }
    }
    public function list_dosen_by_prodi()
    {
        $params = $this->validate(
            $this->request->get(),
            [
                "id_pt" => ['validators' => ['required', 'digit']],
                "id_prodi" => ['validators' => ['required', 'digit']]
            ]
        );

        $ristekdiktiClient = new RistekdiktiClient($this->config["ristekdikti_prop"]);
        $ristekdiktiClient->setLogger($this->logger);
        try {
            $result = $ristekdiktiClient->getDosenByProdi($params['id_pt'], $params['id_prodi']);

            return new CollectionPaginatedResponse($result);
        } catch (\Exception $ex) {
            $api_params = http_build_query($params);
            $this->apiLog->log_error("Ristekdikti - list_dosen_by_prodi", $api_params, $ristekdiktiClient->getErrorBody());
            throw $ex;
        }
    }

    public function list_prodi_by_pt($kode)
    {
        $ristekdiktiClient = new RistekdiktiClient($this->config["ristekdikti_prop"]);
        $ristekdiktiClient->setLogger($this->logger);
        try {
            $result = $ristekdiktiClient->getProdibyPt($kode);
            return new CollectionPaginatedResponse($result);
        } catch (\Exception $ex) {
            $api_params = "kode=$kode";
            $this->apiLog->log_error("Ristekdikti - list_prodi_by_pt", $api_params, $ristekdiktiClient->getErrorBody());
            throw $ex;
        }
    }

    public function search()
    {
        $params = $this->request->get();

        $params['limit'] = $this->getDefaultLimit($params);
        $params['offset'] = array_key_exists('offset', $params) ? $params['offset'] : 0;
        $params['keyword'] = array_key_exists('keyword', $params) ? $params['keyword'] : "";

        $this->validate(
            $params,
            [
                'limit' => ['validators' => ['digit']],
                'offset' => ['validators' => ['digit']]
            ]
        );

        $strWhere = "";
        $bind = [];

        if (strlen($params["keyword"]) > 0) {
            if (strlen($strWhere) > 0) {
                $strWhere .= " and ";
            }
            $strWhere .= "lower(nama) like :name:";
            $bind["name"] = '%' . strtolower($params["keyword"]) . '%';
        }

        $totalCount = PerguruanTinggi::count(
            [
                $strWhere,
                "bind" => $bind
            ]
        );

        $listPt = PerguruanTinggi::find(
            [
                $strWhere,
                "bind" => $bind,
                "limit" => $params["limit"],
                "offset" => $params["offset"]
            ]
        );

        return new PaginatedResponse($listPt, $totalCount, $params["limit"], $params["offset"]);
    }
    public function listJenjangDosen()
    {
        $params = $this->validate(
            $this->request->get(),
            [
                "id_pt" => ['validators' => ['required', 'digit']],
                "mulai_tahun" => ['validators' => ['required', 'digit']],
                "akhir_tahun" => ['validators' => ['required', 'digit']],
                "updated_after" => ['validators' => ['required', 'date']]
            ]
        );

        $ristekdiktiClient = new RistekdiktiClient($this->config["ristekdikti_prop"]);
        $ristekdiktiClient->setLogger($this->logger);
        try {
            $result = $ristekdiktiClient->getDosenJenjang($params['id_pt'], $params['mulai_tahun'], $params['akhir_tahun'], $params['updated_after']);
            return new CollectionPaginatedResponse($result);
        } catch (\Exception $ex) {
            $api_params = http_build_query($params);
            $this->apiLog->log_error("Ristekdikti - listJenjangDosen", $api_params, $ristekdiktiClient->getErrorBody());
            throw $ex;
        }
    }
    public function jumlahMahasiswa()
    {
        $params = $this->validate(
            $this->request->get(),
            [
                "id_pt" => ['validators' => ['required', 'digit']],
                "mulai_tahun" => ['validators' => ['required', 'digit']],
                "akhir_tahun" => ['validators' => ['required', 'digit']],
                "updated_after" => ['validators' => ['required', 'date']]
            ]
        );

        $ristekdiktiClient = new RistekdiktiClient($this->config["ristekdikti_prop"]);
        $ristekdiktiClient->setLogger($this->logger);
        try {
            $result = $ristekdiktiClient->getJumlahMahasiswa($params['id_pt'], $params['mulai_tahun'], $params['akhir_tahun'], $params['updated_after']);
            return new CollectionPaginatedResponse($result);
        } catch (\Exception $ex) {
            $api_params = http_build_query($params);
            $this->apiLog->log_error("Ristekdikti - jumlahMahasiswa", $api_params, $ristekdiktiClient->getErrorBody());
            throw $ex;
        }
    }
}
