<?php

namespace DetailTask;

use DateHelper;
use KemendesBumdesCount;
use KemendesClient;
use KemendesIdmKabupaten;
use KemendesIdmProvinsi;
use LogHelper;

/**
 * @property KemendesClient $client
 */
class KemendesaTask extends AbstractTask {

    #region Attributes
    private $expectedProvinsi;
    private $actualProvinsi;
    private $expectedKabupaten;
    private $actualKabupaten;
    #endregion

    #region Main
    public function init()
    {
        $this->client = new KemendesClient($this->config["kemendes_prop"]["idm"]);
        $this->client->setLogger($this->logger);
        $this->expectedProvinsi = $this->actualProvinsi = $this->expectedKabupaten = $this->actualKabupaten = 0;
    }

    public function initBumdes()
    {
        $this->client = new KemendesClient($this->config["kemendes_prop"]["bumdes"]);
        $this->client->setLogger($this->logger);
        $this->expectedProvinsi = $this->actualProvinsi = $this->expectedKabupaten = $this->actualKabupaten = 0;
    }

    /**
     * @return void
     * Logging disimpan ke table api_errors
     */
    public function processIdm() {
        try {
            $this->init();
            $startTime = microtime(true);
            $this->processIdmProvinsi();
            $this->processIdmKabupaten();
            LogHelper::logInfo(
                "Process Kemendesa IDM",
                $startTime,
                microtime(true),
                [
                    ":expectedProvinsi" => $this->expectedProvinsi,
                    ":actualProvinsi" => $this->actualProvinsi,
                    ":expectedKabupaten" => $this->expectedKabupaten,
                    ":actualKabupaten" => $this->actualKabupaten,
                ],
                self::LOG_TYPE,
                $this->logger
            );
        } catch (\Exception $e) {
            // skip
        }
    }

    public function processBumdes() {
        try {
            $this->initBumdes();
            $startTime = microtime(true);
            $this->processBumdesKabupaten();
            $this->processBumdesCountKabupaten();
            LogHelper::logInfo(
                "Process Kemendesa BUMDes Kabupaten",
                $startTime,
                microtime(true),
                [],
                self::LOG_TYPE,
                $this->logger
            );
        } catch (\Exception $e) {
            // skip
            print_r($e->getMessage());
        }
    }
    #endregion

    #region Helper
    private function processIdmProvinsi() {
        $response = $this->client->idmDatatablesProvinsi();
        if (array_key_exists('aaData', $response) && is_array($response['aaData'])) {
            $this->expectedProvinsi = $response['iTotalRecords'];
            foreach ($response['aaData'] as $res) {
                $status = $res['STATUS_CURRENT_YEAR'];
                if ($status && is_string($status)) {
                    // expected format: "2022|0.4418|SANGAT TERTINGGAL|0.2781|0.5970|0.4503|109"
                    $explode = explode("|", $status);
                    if (count($explode) > 0 && is_numeric($explode[0]) && strlen($explode[0]) === 4) {
                        $tahun = $explode[0];
                        $provinsi = KemendesIdmProvinsi::firstOrCreate(['conditions' => 'id_prov = :id: AND tahun = :tahun:', 'bind' => ['id' => $res['ID'], 'tahun' => $tahun]]);
                        $provinsi->id_prov = $res['ID'];
                        $provinsi->nama = $res['NAMA'];
                        $provinsi->total_desa = $res['TOTAL_DESA'];
                        $provinsi->ranking = $res['RANKING'];
                        $provinsi->tahun = $tahun;
                        $provinsi->status_current_year = $res['STATUS_CURRENT_YEAR'];
                        $provinsi->status_last_year = $res['STATUS_LAST_YEAR'];
                        $provinsi->updated_at = DateHelper::getNowTimezoned();
                        if ($provinsi->save()) {
                            $this->actualProvinsi++;
                        }
                    }
                }
            }
        }
    }

    private function processIdmKabupaten() {
        $response = $this->client->idmDatatablesKabupaten();
        if (array_key_exists('aaData', $response) && is_array($response['aaData'])) {
            $this->expectedKabupaten = $response['iTotalRecords'];
            foreach ($response['aaData'] as $res) {
                $status = $res['STATUS_CURRENT_YEAR'];
                if ($status && is_string($status)) {
                    // expected format: "2022|0.9215|MANDIRI|0.9185|0.9210|0.9249|27"
                    $explode = explode("|", $status);
                    if (count($explode) > 0 && is_numeric($explode[0]) && strlen($explode[0]) === 4) {
                        $tahun = $explode[0];
                        $kabupaten = KemendesIdmKabupaten::firstOrCreate(['conditions' => 'id_kab = :id: AND tahun = :tahun:', 'bind' => ['id' => $res['ID_KAB'], 'tahun' => $tahun]]);
                        $kabupaten->id_prov = $res['ID_PROV'];
                        $kabupaten->nama_prov = $res['NAMA_PROV'];
                        $kabupaten->id_kab = $res['ID_KAB'];
                        $kabupaten->nama = $res['NAMA_KAB'];
                        $kabupaten->ranking = $res['RANKING'];
                        $kabupaten->status = $res['STATUS'];
                        $kabupaten->total_desa = $res['TOTAL_DESA'];
                        $kabupaten->total_verified = $res['TOTAL_VERIFIED'];
                        $kabupaten->tahun = $tahun;
                        $kabupaten->status_current_year = $res['STATUS_CURRENT_YEAR'];
                        $kabupaten->status_last_year = $res['STATUS_LAST_YEAR'];
                        $kabupaten->updated_at = DateHelper::getNowTimezoned();
                        if ($kabupaten->save()) {
                            $this->actualKabupaten++;
                        }
                    }
                }
            }
        }
    }

    private function processBumdesKabupaten() {
        $kabupatens = $this->rawQuery("
            SELECT provinsi_code, kota_kabupaten_code 
            FROM jaga.master_kota_kabupaten 
            WHERE kota_kabupaten_code::INTEGER NOT IN (
                SELECT DISTINCT id_kabupaten 
                FROM jaga.kemendes_bumdes_pemda 
                WHERE last_updated_bumdes > NOW() - INTERVAL '3 months'
            )
            AND deleted_at IS NULL 
            ORDER BY kota_kabupaten_code
            LIMIT 100;
        ");
        foreach ($kabupatens as $kabupaten) {
            $now = date('Y-m-d H:i:s');
            try {
                $response = $this->client->bumdesByKab($kabupaten["kota_kabupaten_code"]);
                if (is_array($response)) {
                    foreach ($response as $res) {
                        $model = \KemendesBumdes::findFirst(['conditions' => "bumdes_id = '" . $res["bumdes_id"] . "'"]);
                        if (!$model) {
                            $model = new \KemendesBumdes();
                            $model->created_at = $now;
                        }
                        $model->bumdes_id = $res["bumdes_id"];
                        $model->type_bumdes = $res["type_bumdes"];
                        $model->nama_bumdes = $res["nama_bumdes"];
                        $model->nama_full_bumdes = $res["nama_full_bumdes"];
                        $model->id_provinsi = $res["id_provinsi"];
                        $model->name_provinsi = $res["name_provinsi"];
                        $model->id_kabupaten = $res["id_kabupaten"];
                        $model->name_kabupaten = $res["name_kabupaten"];
                        $model->id_kecamatan = $res["id_kecamatan"];
                        $model->name_kecamatan = $res["name_kecamatan"];
                        $model->id_desa = $res["id_desa"];
                        $model->name_desa = $res["name_desa"];
                        $model->alamat_lengkap = $res["alamat_lengkap"];
                        $model->email = $res["email"];
                        $model->no_hp_kepala_desa = $res["no_hp_kepala_desa"];
                        $model->website = $res["website"];
                        $model->status = $res["status"];
                        $model->updated_at = $now;

                        if (array_key_exists("jenis_usaha", $res) && is_array($res["jenis_usaha"]) && !empty($res["jenis_usaha"])) {
                            $model->jenis_usaha = json_encode($res["jenis_usaha"]);
                        }

                        $model->save();
                    }
                }
                $pemda = \KemendesBumdesPemda::findOrNewByIdKabupaten($kabupaten["kota_kabupaten_code"]);
                $pemda->id_provinsi = $kabupaten["provinsi_code"];
                $pemda->last_updated_bumdes = $now;
                $pemda->save();
            } catch (\Exception $e) {
                print_r($e->getMessage());
            }
        }
    }
    private function processBumdesCountKabupaten() {
        $kabupatens = $this->rawQuery("
            SELECT mp.provinsi_code, mp.provinsi_name, mkk.kota_kabupaten_code, mkk.kota_kabupaten_name
            FROM jaga.master_kota_kabupaten mkk
            LEFT JOIN jaga.master_provinsi mp ON mp.provinsi_code = mkk.provinsi_code
            WHERE kota_kabupaten_code::INTEGER NOT IN (
                SELECT DISTINCT id_kabupaten 
                FROM jaga.kemendes_bumdes_pemda 
                WHERE last_updated_bumdes_count > NOW() - INTERVAL '3 months'
            )
            AND mkk.deleted_at IS NULL 
            ORDER BY mkk.kota_kabupaten_code
            LIMIT 100;
        ");
        foreach ($kabupatens as $kabupaten) {
            $now = date('Y-m-d H:i:s');;
            try {
                $response = $this->client->bumdesCountKab($kabupaten["kota_kabupaten_code"]);
                if (
                    is_array($response)
                    && array_key_exists("bumdes", $response) && is_array($response["bumdes"])
                    && array_key_exists("bumdesma", $response) && is_array($response["bumdesma"])
                ) {
                    $bumdes = $response["bumdes"];
                    $bumdesma = $response["bumdesma"];
                    $model = \KemendesBumdesCount::findFirst([
                        'conditions' => "id_kabupaten = :id_kabupaten:",
                        'bind' => [
                            "id_kabupaten" => $kabupaten["kota_kabupaten_code"],
                        ]
                    ]);
                    if (!$model) {
                        $model = new \KemendesBumdesCount();
                        $model->created_at = $now;
                    }
                    $model->id_provinsi = $kabupaten["provinsi_code"];
                    $model->name_provinsi = $kabupaten["provinsi_name"];
                    $model->id_kabupaten = $kabupaten["kota_kabupaten_code"];
                    $model->name_kabupaten = $kabupaten["kota_kabupaten_name"];
                    $model->bumdes_mendaftar_nama = $bumdes["bumdes_mendaftar_nama"];
                    $model->bumdes_perbaikan_nama = $bumdes["bumdes_perbaikan_nama"];
                    $model->bumdes_verifikasi_nama = $bumdes["bumdes_verifikasi_nama"];
                    $model->bumdes_mendaftar_badan_hukum = $bumdes["bumdes_mendaftar_badan_hukum"];
                    $model->bumdes_perbaikan_badan_hukum = $bumdes["bumdes_perbaikan_badan_hukum"];
                    $model->bumdes_verifikasi_badan_hukum = $bumdes["bumdes_verifikasi_badan_hukum"];
                    $model->bumdesma_mendaftar_nama = $bumdesma["bumdesma_mendaftar_nama"];
                    $model->bumdesma_perbaikan_nama = $bumdesma["bumdesma_perbaikan_nama"];
                    $model->bumdesma_verifikasi_nama = $bumdesma["bumdesma_verifikasi_nama"];
                    $model->bumdesma_mendaftar_badan_hukum = $bumdesma["bumdesma_mendaftar_badan_hukum"];
                    $model->bumdesma_perbaikan_badan_hukum = $bumdesma["bumdesma_perbaikan_badan_hukum"];
                    $model->bumdesma_verifikasi_badan_hukum = $bumdesma["bumdesma_verifikasi_badan_hukum"];
                    $model->updated_at = $now;

                    $model->save();

                    $pemda = \KemendesBumdesPemda::findOrNewByIdKabupaten($kabupaten["kota_kabupaten_code"]);
                    $pemda->id_provinsi = $kabupaten["provinsi_code"];
                    $pemda->last_updated_bumdes_count = $now;
                    $pemda->save();
                }
            } catch (\Exception $e) {
                print_r($e->getMessage());
            }
        }
    }
    #endregion
}
