<?php
class RumahSakitController extends BaseController
{
    public function listProvinsi()
    {
        $listProv = array_map(
            function ($v) {
                return $v['provinsi'];
            },
            Puskesmas::find(
                [
                    "columns" => "distinct(provinsi) as provinsi",
                    "order" => "provinsi asc"
                ]
            )
                ->toArray()
        );
        $totalCount = count($listProv);
        return new PaginatedResponse($listProv, $totalCount, $totalCount, 0);
    }

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

        $result = RumahSakit::find(
            [
                "conditions" => "kode_rs = :id:",
                "bind" => ["id" => $id],
                "columns" => "kode_rs as kode, nama, kab_kota, provinsi"
            ]
        );

        if ($this->shared) {
            $service = new ActivityService($this->shared, $this->logger);
            $service->createActivity(UserActivity::PRODUK_KESEHATAN, $id);
        }

        return new SingleResponse($result, "Rumah sakit");
    }

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

        $params['limit'] = $this->getDefaultLimit($params);
        $params['offset'] = array_key_exists('offset', $params) ? $params['offset'] : 0;
        $params['nama'] = array_key_exists('nama', $params) ? $params['nama'] : "";
        $params['provinsi'] = array_key_exists('provinsi', $params) ? $params['provinsi'] : "";
        $params['kota'] = array_key_exists('kota', $params) ? $params['kota'] : "";
        $params['order_by'] = array_key_exists('order_by', $params) ? $params['order_by'] : "nama";
        $params['order_direction'] = array_key_exists('order_direction', $params) ? $params['order_direction'] : "asc";

        $allowedOrder = ['nama'];
        $allowedDirection = ['asc', 'desc'];
        $mappedOrder = [
            'nama' => 'TRIM(LEADING FROM nama)'
        ];

        $validatedRequest = $this->validate(
            $params,
            [
                'limit' => ['validators' => ['digit']],
                'offset' => ['validators' => ['digit']],
                'order_by' => ['validators' => [
                    [
                        'name' => 'inclusion_in',
                        'params' => $allowedOrder
                    ]
                ]],
                'order_direction' => ['validators' => [
                    [
                        'name' => 'inclusion_in',
                        'params' => $allowedDirection
                    ]
                ]],
            ]
        );

        $strWhere = "nama is not null and nama <> ''";
        $bind = [];
        if (strlen($params["provinsi"]) > 0) {
            if (strlen($strWhere) > 0) {
                $strWhere .= " and ";
            }
            $strWhere .= "lower(provinsi) = :provinsi";
            $bind["provinsi"] = strtolower($params["provinsi"]);
        }

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

        if (strlen($params["nama"]) > 0) {
            if (strlen($strWhere) > 0) {
                $strWhere .= " and ";
            }
            $strWhere .= "lower(nama) like :nama";
            $bind["nama"] = CommonTools::getDummyFuzzyKeyword($params["nama"]);
        }

        $q = "select count(kode_rs) as total from jaga.rumah_sakit where $strWhere";
        $totalCount = $this->rawQuery($q, $bind)[0]['total'];

        $orderBy = $mappedOrder[$validatedRequest['order_by']] . " " . $validatedRequest['order_direction'];
        $limit = $validatedRequest['limit'];
        $offset = $validatedRequest['offset'];
        $q = "select kode_rs as kode, nama, kab_kota, provinsi from jaga.rumah_sakit where $strWhere order by $orderBy limit $limit offset $offset";
        $listRs = $this->rawQuery($q, $bind);

        return new PaginatedResponse($listRs, $totalCount, $params["limit"], $params["offset"]);
    }

    public function profile($nprs)
    {
        $profile = RumahSakit::find(
            [
                "columns" => "nama, direktur_rs as kepala,
                    (
                        coalesce(umum, 0)
                        + coalesce(drg, 0)
                        + coalesce(drg, 0)
                        + coalesce(drg_sp_karang_gigi, 0)
                        + coalesce(drg_sp_bedah_mulut, 0)
                        + drg_sp_anak + drg_sp_konservasi + drg_sp_gigi_tiruan + drg_sp_penyakit_mulut + drg_sp_periodonsia
                        + drg_sp_lainnya
                    ) as jml_dokter,
                    (
                        coalesce(ners, 0)
                        + coalesce(perawat_gigi, 0)
                        + coalesce(perawat_bedah, 0)
                        + coalesce(perawat_kes_jiwa, 0)
                        + coalesce(perawat_maternitas, 0)
                        + coalesce(perawat_anak, 0)
                        + coalesce(perawat_komunitas, 0)
                        + coalesce(perawat_lainnya, 0)
                    ) as jml_perawat,
                    (bidan_pendidik+bidan_klinik+bidan_lainnya) as jml_bidan,
                    jml_tenaga_medis, spa, spog, spd, spb, sprad, sprm, span, spjp, spm, sptht, spkj, sppk,
                    sps, spp, spokupasi, spu, spkl, sporthopedi, spf, sppsikiatri, spof, sppa,
                    tt_vvip as vvip, tt_vip as vip, tt_i as kelas_1, tt_ii as kelas_2, tt_iii as kelas_3, tt_icu as icu,
                    tt_picu as picu, tt_nicu as nicu, tt_hcu as hcu, tt_igd as igd, tt_bayi as bayi, tt_bersalin as bersalin,
                    tt_r_operasi as operasi, tt_r_isolasi as isolasi,
                    provinsi, kab_kota,
                    latitude, longitude, last_update,
                    kelas
                ",
                "kode_rs = :nprs:",
                "bind" => [
                    "nprs" => $nprs
                ]
            ]
        )
            ->toArray();
        return new PaginatedResponse($profile, count($profile), 1, 0);
    }

    public function liveProfile($nprs)
    {
        $rsClient = new RumahSakitClient($this->config["rs_prop"]);
        $rsClient->setLogger($this->logger);
        try {
            $result = $rsClient->profile($nprs);
            return new CollectionPaginatedResponse($result);
        } catch (\Exception $ex) {
            $api_params = "nprs=$nprs";
            $this->apiLog->log_error("Rumah Sakit - liveProfile", $api_params, $rsClient->getErrorBody());
            throw $ex;
        }
    }

    public function rsKetersediaanTempatTidur($nprs)
    {
        try {
            $result = [
                "latest_update" => null,
                "rawat_inap_total" => 0,
                "rawat_inap_tersedia" => 0,
                "ketersediaan" => [
                    "vvip" => [
                        "total" => 0,
                        "terpakai" => 0,
                        "kelas_perawatan" => "VVIP"
                    ],
                    "vip" => [
                        "total" => 0,
                        "terpakai" => 0,
                        "kelas_perawatan" => "VIP"
                    ],
                    "kelas_1" => [
                        "total" => 0,
                        "terpakai" => 0,
                        "kelas_perawatan" => "Kelas 1"
                    ],
                    "kelas_2" => [
                        "total" => 0,
                        "terpakai" => 0,
                        "kelas_perawatan" => "Kelas 2"
                    ],
                    "kelas_3" => [
                        "total" => 0,
                        "terpakai" => 0,
                        "kelas_perawatan" => "Kelas 3"
                    ],
                    "rawat_khusus" => [
                        "total" => 0,
                        "terpakai" => 0,
                        "kelas_perawatan" => "Rawat Khusus"
                    ]
                ]
            ];
            $client = new RumahSakitClient($this->config["rs_prop"]);
            $rsResult = null;
            $client->setLogger($this->logger);
            try {
                $rsResult = $client->getDetailKetersedianTempatTidur($nprs)[0];
            } catch (\Exception $ex) {
                $api_params = "nprs=$nprs";
                $this->apiLog->log_error("Rumah Sakit - rsKetersediaanTempatTidur", $api_params, $client->getErrorBody());
                throw $ex;
            }
            if (
                is_array($rsResult)
                && array_key_exists("kode", $rsResult)
                && $rsResult["kode"] == 200
            ) {
                $tempat_tidur_list = $rsResult["KetersediaanTT"];
                if (empty($tempat_tidur_list)) {
                    $tempat_tidur_list = [];
                }

                foreach ($tempat_tidur_list as $tempatTidur) {
                    $result["rawat_inap_total"] += $tempatTidur["JumlahTT"];
                    $result["rawat_inap_tersedia"] = $result["rawat_inap_total"] - $tempatTidur["TerisiMale"] - $tempatTidur["TerisiFemale"];
                    $key = str_replace(" ", "_", strtolower($tempatTidur["KelasPerawatan"]));
                    if (!array_key_exists($key, $result["ketersediaan"])) {
                        $result["ketersediaan"][$key]["kelas_perawatan"] = $tempatTidur["KelasPerawatan"];
                        $result["ketersediaan"][$key]["total"] = 0;
                        $result["ketersediaan"][$key]["terpakai"] = 0;
                    }
                    $result["ketersediaan"][$key]["total"] += $tempatTidur["JumlahTT"];
                    $result["ketersediaan"][$key]["terpakai"] += $tempatTidur["TerisiMale"] + $tempatTidur["TerisiFemale"];
                    $keyRuangPerawatan = str_replace(" ", "_", strtolower($tempatTidur["RuangPerawatan"]));
                    $result["ketersediaan"][$key]["ruang_perawatan"][$keyRuangPerawatan]["nama"] = $tempatTidur["RuangPerawatan"];
                    $result["ketersediaan"][$key]["ruang_perawatan"][$keyRuangPerawatan]["tersedia"] = $tempatTidur["JumlahTT"] - $tempatTidur["TerisiMale"] - $tempatTidur["TerisiFemale"];
                    $result["ketersediaan"][$key]["ruang_perawatan"][$keyRuangPerawatan]["terisi_male"] = $tempatTidur["TerisiMale"];
                    $result["ketersediaan"][$key]["ruang_perawatan"][$keyRuangPerawatan]["terisi_female"] = $tempatTidur["TerisiFemale"];
                    $result["ketersediaan"][$key]["ruang_perawatan"][$keyRuangPerawatan]["waktu_update"] = $tempatTidur["WaktuUpdate"];

                    if (empty($result["latest_update"]) || strcmp($result["latest_update"], $tempatTidur["WaktuUpdate"]) < 0) {
                        $result["latest_update"] = $tempatTidur["WaktuUpdate"];
                    }
                }
            } elseif (
                is_array($rsResult)
                && array_key_exists("kode", $rsResult)
                && $rsResult["kode"] == 404
            ) {
                throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, 'Rumah sakit not found', [
                    "nprs" => $nprs
                ]);
            } else {
                throw new CustomErrorException(BaseResponse::GUZZLE_ERROR, "Network Error: error fetching data", [
                    "nprs" => $nprs
                ]);
            }
        } catch (\CustomErrorException $e) {
            throw $e;
        } catch (\Exception $e) {
            throw new CustomErrorException(BaseResponse::GUZZLE_ERROR, "Network Error: " . $e->getMessage(), [
                "nprs" => $nprs
            ]);
        }

        return new PaginatedResponse($result, 1, 1, 0);
    }

    public function tenagaMedisNasional() {
        $rumahsakit = $this->rawQuery("
            SELECT
                sum(jml_dokter) as jml_dokter,
                sum(jml_perawat) as jml_perawat,
                sum(jml_bidan) as jml_bidan,
                sum(jml_tenaga_medis) as jml_tenaga_medis
            FROM (
                SELECT
                (
                        coalesce(umum, 0)
                        + coalesce(drg, 0)
                        + coalesce(drg_sp_karang_gigi, 0)
                        + coalesce(drg_sp_bedah_mulut, 0)
                        + drg_sp_anak + drg_sp_konservasi + drg_sp_gigi_tiruan + drg_sp_penyakit_mulut + drg_sp_periodonsia
                        + drg_sp_lainnya
                ) as jml_dokter,
                (
                        coalesce(ners, 0)
                        + coalesce(perawat_gigi, 0)
                        + coalesce(perawat_bedah, 0)
                        + coalesce(perawat_kes_jiwa, 0)
                        + coalesce(perawat_maternitas, 0)
                        + coalesce(perawat_anak, 0)
                        + coalesce(perawat_komunitas, 0)
                        + coalesce(perawat_lainnya, 0)
                ) as jml_perawat,
                (bidan_pendidik + bidan_klinik + bidan_lainnya) as jml_bidan,
                jml_tenaga_medis
                FROM
                jaga.rumah_sakit
                ) rs
                ;
        ");

        $puskesmas = $this->rawQuery("
        SELECT
            sum(jml_dokter) as jml_dokter,
            sum(jml_perawat) as jml_perawat,
            sum(jml_bidan) as jml_bidan,
            sum(jml_tenaga_medis) as jml_tenaga_medis
        FROM (
            SELECT
                ( jumlahdokter + jumlahdoktergigi ) AS jml_dokter,
                ( jumlahperawat ) AS jml_perawat,
                jumlahbidan AS jml_bidan,
                ( jumlahapoteker + jumlahasistenapoteker + jumlahahligizi ) AS jml_tenaga_medis 
            FROM
                jaga.bpjs_puskesmas
        ) puskesmas");

        $result = array();
        foreach ($rumahsakit[0] as $key => $value) {
            $result[$key] = $value + $puskesmas[0][$key];
        }

        return new SimpleResponse($result);
    }
}
