<?php

class StranaspkTableauController extends BaseController {

    private $milestones = [];

    public function index() {

        $getParams = $this->request->get();
        $params = $this->validate(
            $getParams,
            [
                'id_periode' => ['validators' => ['required', 'digit']],
            ]
        );

        // ambil milestone
        $milestones = $this->getMilestones($params['id_periode']);
        $this->getLatestVerificationValuePerMilestone($milestones);
        $populatedMilestone = $this->populateMilestone($milestones);
        $output = $this->retrieveInstansi($populatedMilestone);
        return new SimpleResponse($output);
    }

    private function getMilestones($id_periode) {
        // dapatkan milestones yg bukan is_deleted
        $logframeStore = new SleekDbStore('logframe');
        $milestones = $logframeStore
            ->createQueryBuilder()
            ->select(['id_parent', 'weight', 'id_instansi', 'verifications'])
            ->where([
                ['id_periode', '=', intval($id_periode)],
                ['level', '=', 4],
                function($logframe) {
                    return !isset($logframe['is_deleted']);
                }
            ])
            ->getQuery()
            ->fetch();
        return $milestones;
    }

    private function getLatestVerificationValuePerMilestone(array &$milestones) {
        // mengambil nilai verifikasi TERAKHIR dari setiap milestone
        $verificationsStore = new SleekDbStore('verifications');
        foreach($milestones as $milestoneIndex => $milestone) {
            $tempIdTriwulan = 0;
            foreach($milestone['verifications'] as $verificationId) {
                $verification = $verificationsStore->findById($verificationId);
                if ($verification['id_triwulan'] <= $tempIdTriwulan) continue;
                if (is_null($verification['score'])) continue;
                if (!isset($verification['score']['value'])) continue;
                $tempIdTriwulan = $verification['id_triwulan'];
                $milestones[$milestoneIndex]['latest_score'] = $verification['score']['value'];
            }
            unset($milestones[$milestoneIndex]['verifications']);
            if (!isset($milestones[$milestoneIndex]['latest_score'])) {
                $milestones[$milestoneIndex]['latest_score'] = 0;
            }
        }
    }

    private function populateMilestone($milestones) {
        // populate milestone
        $logframeStore = new SleekDbStore('logframe');
        $populatedMilestone = [];
        foreach($milestones as $milestone) {
            foreach($milestone['id_instansi'] as $idInstansi) {

                // dapatkan bobot per milestone -> output -> aksi
                $output = $logframeStore->findById($milestone['id_parent']);
                $aksi = $logframeStore->findById($output['id_parent']);
                $weightPerInstansi = floatval($milestone['weight']) / 100 *
                    floatval($output['weight']) / 100 *
                    floatval($aksi['weight']) / 100 / sizeof($milestone['id_instansi']);
                $maxScore = 100 * $weightPerInstansi;
                $weighedScore = floatval($milestone['latest_score']) * 
                    $weightPerInstansi;
                if (isset($populatedMilestone[$idInstansi])) {
                    $populatedMilestone[$idInstansi]["max_score"] += $maxScore;
                    $populatedMilestone[$idInstansi]["score"] += $weighedScore;
                } else {
                    $populatedMilestone[$idInstansi] = [
                        "max_score" => $maxScore,
                        "score" => $weighedScore
                    ];
                }
            }
        }
        // hitung score tiap instansi pribadi berdasarkan
        // score : max_score
        foreach($populatedMilestone as $index => $milestone) {
            $populatedMilestone[$index]['score_nasional'] = $milestone['score'];
            $populatedMilestone[$index]['score_instansi'] = $milestone['score'] / $milestone['max_score'] * 100;
        }
        return $populatedMilestone;
    }

    private function retrieveInstansi($populatedMilestone) {
        // ambil nama instansi ke PostgreSQL
        $idInstansiList = [];
        foreach ($populatedMilestone as $idInstansi => $milestone) {
            $idInstansiList[] = $idInstansi;
        }
        
        $instansiList = Instansi::find([
            'conditions' => 'id in ({id:array})',
            'bind' => [
                'id' => $idInstansiList
            ]
        ])->toArray();

        // populate instansi list by id, get provinsi & kota_kabupaten
        $instansiListById = [];
        foreach($instansiList as $instansi) {
            // ambil data provinsi
            if (!is_null($instansi['id_provinsi'])) {
                $provinsi = MasterProvinsi::findFirst("provinsi_code = '".$instansi['id_provinsi']."'");
                $result = (!empty($provinsi)) ? $provinsi->toArray() : null;
                $instansi['provinsi'] = $result['provinsi_name'];
            } elseif (in_array($instansi['id_tipe'], [3,5])) {
                $instansi['provinsi'] = 'Dki Jakarta'; // untuk K/L
            } else {
                $instansi['provinsi'] = null;
            }

            // ambil data kota kabupaten
            if (!is_null($instansi['id_kota_kabupaten'])) {
                $kota_kabupaten = MasterKotaKabupaten::findFirst("kota_kabupaten_code = '".$instansi['id_kota_kabupaten']."'");
                $result = (!empty($kota_kabupaten)) ? $kota_kabupaten->toArray() : null;
                $instansi['kab_kota'] = $result['kota_kabupaten_name'];
            } else {
                $instansi['kab_kota'] = null;
            }
            
            $instansiListById[$instansi['id']] = [
                'nama' => $instansi['nama'],
                'provinsi' => $instansi['provinsi'],
                'kab_kota' => $instansi['kab_kota'],
            ];
        }
        unset($instansiList);

        $output = [];
        foreach ($populatedMilestone as $idInstansi => $milestone) {
            $output[] = [
                // 'id_instansi' => $idInstansi,
                'nama_instansi' => $instansiListById[$idInstansi]['nama'],
                'provinsi' => $instansiListById[$idInstansi]['provinsi'],
                'kab_kota' => $instansiListById[$idInstansi]['kab_kota'],
                'score_nasional' => $milestone['score_nasional'],
                // 'max_score_nasional' => $milestone['max_score'],
                'score_instansi' => $milestone['score_instansi']
            ];
        }
        return $output;
    }
}