<?php

use Phalcon\Mvc\Model\Transaction\Failed as TxFailed;
use Carbon\Carbon;

class BansosService
{
    const SCOPE_FOLLOWUP_BANSOS = 'bansos.follow_up';
    const SCOPE_FOLLOWUP_COVID = 'covid.dinkes_pemda';
    const SCOPE_FOLLOWUP_IKN = 'keluhan.ikn.follow_up';
    const SCOPE_FOLLOWUP_DESA = 'keluhan.desa.follow_up';
    const SCOPE_FOLLOWUP_KAMPUS = 'keluhan.kampus.follow_up';
    const SCOPE_FOLLOWUP_PELABUHAN = 'keluhan.pelabuhan.follow_up';
    const SCOPE_FOLLOWUP_BPJS_KESEHATAN = 'keluhan.bpjs.follow_up';
    const SCOPE_FOLLOWUP_PENDIDIKAN = 'keluhan.pendidikan.follow_up';
    private $controller;

    /**
     * @var MailHelper
     */
    private $mailHelper;

    /**
     * @var Diskusi
     */
    public $diskusi;

    /**
     * @var DiskusiBansos
     */
    public $keluhan;

    /**
     * @var DiskusiComment
     */
    public $komentar;

    /**
     * @var TopikDiskusiBansos
     */
    public $topik;

    public function __construct($controller)
    {
        $this->controller = $controller;
    }

    public function setMailHelper(MailHelper $mailHelper) {
        $this->mailHelper = $mailHelper;
    }

    public function handleActivity($validatedRequest, DiskusiComment $komentar)
    {
        $diskusiBansos = DiskusiBansos::findFirst(
            [
                "id_diskusi = :id_diskusi: and deleted_at is null",
                "bind" => [
                    "id_diskusi" => $komentar->diskusi_id
                ]
            ]
        );

        if (empty($diskusiBansos)) {
            return;
        }

        if (array_key_exists('confirm_all_status', $validatedRequest) && !empty($validatedRequest['confirm_all_status']) && $validatedRequest['confirm_all_status'] != 'null') {
            $validatedRequest['status'] = $validatedRequest['confirm_all_status'];
            $this->handleConfirmAll($validatedRequest, $komentar, $diskusiBansos);
        } elseif (array_key_exists('confirm_assigned_status', $validatedRequest) && !empty($validatedRequest['confirm_assigned_status']) && $validatedRequest['confirm_assigned_status'] != 'null') {
            $validatedRequest['status'] = $validatedRequest['confirm_assigned_status'];
            $this->handleConfirmAssigned($validatedRequest, $komentar, $diskusiBansos);
        } elseif (array_key_exists('follow_up_status', $validatedRequest) && !empty($validatedRequest['follow_up_status']) && $validatedRequest['follow_up_status'] != 'null') {
            $validatedRequest['status'] = $validatedRequest['follow_up_status'];
            $this->handleFollowUp($validatedRequest, $komentar, $diskusiBansos);
        }
    }

    private function handleConfirmAll($params, $komentar, $diskusiBansos)
    {
        if (!$this->controller->hasScopes(['bansos.confirm_all'])) {
            return;
        }

        $service = new DiskusiService($this->controller->config, $this->controller->shared, $this->controller->request, $this->controller->minio);

        $idInstansi = $diskusiBansos->id_instansi;
        if (
            $params['status'] == DiskusiBansos::CONFIRMED_TO_PEMDA ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMSOS ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_DUMASKPK ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENKOPUKM ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_IRJENKEMKES ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_BIROKOMYANMAS ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_PDDT ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDAGRI ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_ITJENDIKBUD ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_ITJENMENAG ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KSU ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KOPU ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KSOP ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KUPP ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERTANIAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERIKANAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI_PELABUHAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_BAWASLU ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_DKPP ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_BPJS_KESEHATAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDIKDASMEN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENAG ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI
        ) {
            $diskusiBansos->status = DiskusiBansos::CONFIRMED;
            $namaInstansi = '';

            if ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMSOS) {
                $namaInstansi = DiskusiBansos::KEMSOS_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_DUMASKPK) {
                $namaInstansi = DiskusiBansos::KPK_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENKOPUKM) {
                $namaInstansi = DiskusiBansos::KEMENKOPUKM_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_IRJENKEMKES) {
                $namaInstansi = DiskusiBansos::IRJENKEMKES_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_BIROKOMYANMAS) {
                $namaInstansi = DiskusiBansos::BIROKOMYANMAS_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_PDDT) { // keluhan DESA
                $namaInstansi = DiskusiBansos::PDDT_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDAGRI) { // keluhan DESA
                $namaInstansi = DiskusiBansos::KEMENDAGRI_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_ITJENDIKBUD) { // keluhan KAMPUS
                $namaInstansi = DiskusiBansos::IRJENKEMDIKBUD_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_ITJENMENAG) { // keluhan KAMPUS
                $namaInstansi = DiskusiBansos::IRJENKEMENAG_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KSU) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KSU_NAME.' ('.trim($instansiOrigin->nama). ')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KOPU) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KOPU_NAME.' ('.trim($instansiOrigin->nama). ')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KSOP) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KSOP_NAME.' ('.trim($instansiOrigin->nama).')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KUPP) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KUPP_NAME.' ('.trim($instansiOrigin->nama).')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERTANIAN) { // keluhan PELABUHAN
                $namaInstansi = DiskusiBansos::KEMENTAN_NAME;
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERIKANAN) { // keluhan PELABUHAN
                $namaInstansi = DiskusiBansos::KKP_NAME;
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI_PELABUHAN) { // keluhan PELABUHAN
                $topikKeluhan = TopikDiskusiBansos::findFirst($diskusiBansos->id_topik);
                if(empty($topikKeluhan)) throw new Exception("Topik tidak ditemukan!");
                switch ($topikKeluhan->deskripsi) {
                    case "Pelabuhan - Layanan Ekspor/Impor":
                    case "Pelabuhan - Layanan Pembayaran":
                        $namaInstansi = DiskusiBansos::LNSW_NAME;
                        break;
                    case "Pelabuhan - Layanan Domestik":
                        $namaInstansi = DiskusiBansos::KEMENDAG_NAME;
                        break;
                    case "Pelabuhan - Layanan Pintu Keluar/Masuk":
                    case "Pelabuhan - Layanan Pengeluaran Barang":
                        $namaInstansi = DiskusiBansos::PTPELABUHAN_NAME;
                        break;
                    case "Pelabuhan - Layanan Tenaga Bongkar Muat":
                        $namaInstansi = DiskusiBansos::KEMNAKER_NAME;
                        break;
                    default:
                        throw new ValidationException([
                            [
                                'field' => 'status',
                                'message' => 'Instansi tujuan tindak lanjut untuk topik keluhan ini tidak dapat ditemukan',
                            ],
                        ]);
                }
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_BAWASLU) { // Keluhan Pemilu
                $namaInstansi = DiskusiBansos::BAWASLU_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_DKPP) {// Keluhan Pemilu
                $namaInstansi = DiskusiBansos::DKPP_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_BPJS_KESEHATAN) { // keluhan BPJS KESEHATAN
                $namaInstansi = DiskusiBansos::BPJS_KESEHATAN_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDIKDASMEN) { // keluhan Pendidikan
                $namaInstansi = DiskusiBansos::KEMENDIKDASMEN;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENAG) { // keluhan Pendidikan
                $namaInstansi = DiskusiBansos::KEMENAG_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI) { // keluhan Pendidikan
                if (!array_key_exists('id_instansi', $params)) {
                    throw new ValidationException([
                        [
                            'field' => 'status',
                            'message' => 'Instansi tujuan tindak lanjut tidak dapat ditemukan',
                        ],
                    ]);
                }
                $idInstansi = $params['id_instansi'];
            }

            if ($namaInstansi != '') {
                $instansi = Instansi::findFirst(
                    [
                        "lower(nama) ILIKE :nama_instansi:",
                        "bind" => [
                            "nama_instansi" => $namaInstansi
                        ]
                    ]
                );

                if (empty($instansi)) {
                    throw new ValidationException([
                        [
                            'field' => 'status',
                            'message' => 'Instansi tujuan tindak lanjut tidak dapat ditemukan',
                        ],
                    ]);
                }

                $idInstansi = $instansi->id;
            }

            $diskusiBansos->id_instansi = $idInstansi;
        } elseif ($params['status'] == DiskusiBansos::DONE_BY_VERIFIKATOR) {
            $diskusiBansos->status = DiskusiBansos::DONE;
            $namaInstansi = DiskusiBansos::KPK_NAME;

            $instansi = Instansi::findFirst(
                [
                    "lower(nama) = :nama_instansi:",
                    "bind" => [
                        "nama_instansi" => $namaInstansi
                    ]
                ]
            );

            if (empty($instansi)) {
                throw new ValidationException([
                    [
                        'field' => 'status',
                        'message' => 'Instansi tujuan tindak lanjut tidak dapat ditemukan',
                    ],
                ]);
            }

            $idInstansi = $instansi->id;
            $diskusiBansos->id_instansi = $idInstansi;
        } else {
            $diskusiBansos->status = $params['status'];
        }
        $resultDiskusi = $diskusiBansos->save();

        $diskusiBansosHistory = new DiskusiBansosHistory();
        $diskusiBansosHistory->id_diskusi_bansos = $diskusiBansos->id;
        $diskusiBansosHistory->keterangan = '-';
        $diskusiBansosHistory->id_komentar = $komentar->id;
        $diskusiBansosHistory->id_instansi = $idInstansi;
        $diskusiBansosHistory->id_user = $this->controller->shared->user->um_id;
        $diskusiBansosHistory->status = $diskusiBansos->status;
        $resultHistory = $diskusiBansosHistory->create();

        if ($resultDiskusi && $resultHistory) {
            $service->notifyKorwilPemdaUser($diskusiBansos, DiskusiService::BANSOS_NOTIFICATION_CONFIRMATION);
            // todo uncomment di branch issue #1124
            // $this->mailToStakeholder($diskusiBansos, $komentar);

            //otomatis merubah menjadi done apabila ke dumasKPK
            if ($params['status'] == DiskusiBansos::CONFIRMED_TO_DUMASKPK) {
                $diskusiBansos = DiskusiBansos::findFirst($diskusiBansos->id);

                $diskusiBansos->status = DiskusiBansos::DONE;
                $resultDiskusi = $diskusiBansos->save();

                $diskusiBansosHistory = new DiskusiBansosHistory();
                $diskusiBansosHistory->id_diskusi_bansos = $diskusiBansos->id;
                $diskusiBansosHistory->keterangan = 'Diselesaikan oleh DuMas KPK';
                $diskusiBansosHistory->id_komentar = $komentar->id;
                $diskusiBansosHistory->id_instansi = $idInstansi;
                $diskusiBansosHistory->id_user = $this->controller->shared->user->um_id;
                $diskusiBansosHistory->status = $diskusiBansos->status;
                $resultHistory = $diskusiBansosHistory->create();

                if ($resultDiskusi && $resultHistory) {
                    $service->notifyKorwilPemdaUser($diskusiBansos, DiskusiService::BANSOS_NOTIFICATION_CONFIRMATION);
                } else {
                    throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Save Diskusi Bansos Error");
                }
            }
        }
    }

    private function handleConfirmAssigned($params, $komentar, $diskusiBansos)
    {
        if (!$this->controller->hasScopes(['bansos.confirm_assigned'])) {
            return;
        }

        $service = new DiskusiService($this->controller->config, $this->controller->shared, $this->controller->request, $this->controller->minio);

        //check Assigned
        $userID = $this->controller->shared->user->um_id;

        //NOTE: Jangan dihapus dulu
        /*$allowedInstansi = KorwilTeamInstansi::findFirst(
            [
                "team_id in (SELECT x.team_id FROM KorwilTeamUser x WHERE x.user_id = :user_id:)
                    and (instansi_id = :instansi_id: OR instansi_id = :instansi_id_origin:)",
                "bind" => [
                    "user_id" => $userID,
                    "instansi_id" => $diskusiBansos->id_instansi,
                    "instansi_id_origin" => $diskusiBansos->id_instansi_origin
                ]
            ]
        );

        if (empty($allowedInstansi)) {
            return;
        }*/

        //update diskusi bansos
        $idInstansi = $diskusiBansos->id_instansi;
        if (
            $params['status'] == DiskusiBansos::CONFIRMED_TO_PEMDA ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMSOS ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_DUMASKPK ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENKOPUKM ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_IRJENKEMKES ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_BIROKOMYANMAS ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_PDDT ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDAGRI ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KSU ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KOPU ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KSOP ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KUPP ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERTANIAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERIKANAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI_PELABUHAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_BAWASLU ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_DKPP ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_BPJS_KESEHATAN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDIKDASMEN ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENAG ||
            $params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI
        ) {
            $diskusiBansos->status = DiskusiBansos::CONFIRMED;
            $namaInstansi = '';

            if ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMSOS) {
                $namaInstansi = DiskusiBansos::KEMSOS_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_DUMASKPK) {
                $namaInstansi = DiskusiBansos::KPK_NAME;
            } else if ($params['status'] == DiskusiBansos::CONFIRMED_TO_PEMDA) {
                $idInstansi = $diskusiBansos->id_instansi_origin;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENKOPUKM) {
                $namaInstansi = DiskusiBansos::KEMENKOPUKM_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_IRJENKEMKES) {
                $namaInstansi = DiskusiBansos::IRJENKEMKES_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_BIROKOMYANMAS) {
                $namaInstansi = DiskusiBansos::BIROKOMYANMAS_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_PDDT) { // keluhan DESA
                $namaInstansi = DiskusiBansos::PDDT_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDAGRI) { // keluhan DESA
                $namaInstansi = DiskusiBansos::KEMENDAGRI_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KSU) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KSU_NAME.' ('.trim($instansiOrigin->nama). ')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KOPU) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KOPU_NAME.' ('.trim($instansiOrigin->nama). ')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KSOP) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KSOP_NAME.' ('.trim($instansiOrigin->nama).')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KUPP) { // keluhan PELABUHAN
                $instansiOrigin = $this->findInstansiOrigin($diskusiBansos);
                $namaInstansi = DiskusiBansos::KUPP_NAME.' ('.trim($instansiOrigin->nama).')';
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERTANIAN) { // keluhan PELABUHAN
                $namaInstansi = DiskusiBansos::KEMENTAN_NAME;
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KARANTINA_PERIKANAN) { // keluhan PELABUHAN
                $namaInstansi = DiskusiBansos::KKP_NAME;
                $idInstansi = $this->findInstansiByNama($namaInstansi)->id;
                $diskusiBansos->id_instansi = $idInstansi;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI_PELABUHAN) { // keluhan PELABUHAN
                $topikKeluhan = TopikDiskusiBansos::findFirst($diskusiBansos->id_topik);
                if (empty($topikKeluhan)) throw new Exception("Topik tidak ditemukan!");
                switch ($topikKeluhan->deskripsi) {
                    case "Pelabuhan - Layanan Ekspor/Impor":
                    case "Pelabuhan - Layanan Pembayaran":
                        $namaInstansi = DiskusiBansos::LNSW_NAME;
                        break;
                    case "Pelabuhan - Layanan Domestik":
                        $namaInstansi = DiskusiBansos::KEMENDAG_NAME;
                        break;
                    case "Pelabuhan - Layanan Pintu Keluar/Masuk":
                    case "Pelabuhan - Layanan Pengeluaran Barang":
                        $namaInstansi = DiskusiBansos::PTPELABUHAN_NAME;
                        break;
                    case "Pelabuhan - Layanan Tenaga Bongkar Muat":
                        $namaInstansi = DiskusiBansos::KEMNAKER_NAME;
                        break;
                    default:
                        throw new ValidationException([
                            [
                                'field' => 'status',
                                'message' => 'Instansi tujuan tindak lanjut untuk topik keluhan ini tidak dapat ditemukan',
                            ],
                        ]);
                }
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_BAWASLU) { // Keluhan Pemilu
                $namaInstansi = DiskusiBansos::BAWASLU_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_DKPP) {// Keluhan Pemilu
                $namaInstansi = DiskusiBansos::DKPP_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_BPJS_KESEHATAN) { // keluhan BPJS KESEHATAN
                $namaInstansi = DiskusiBansos::BPJS_KESEHATAN_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENDIKDASMEN) { // keluhan Pendidikan
                $namaInstansi = DiskusiBansos::KEMENDIKDASMEN;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_KEMENAG) { // keluhan Pendidikan
                $namaInstansi = DiskusiBansos::KEMENAG_NAME;
            } elseif ($params['status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI) { // keluhan Pendidikan
                if (!array_key_exists('id_instansi', $params)) {
                    throw new ValidationException([
                        [
                            'field' => 'status',
                            'message' => 'Instansi tujuan tindak lanjut tidak dapat ditemukan',
                        ],
                    ]);
                }
                $idInstansi = $params['id_instansi'];
            }

            if ($namaInstansi != '') {
                $instansi = Instansi::findFirst(
                    [
                        "lower(nama) ILIKE :nama_instansi:",
                        "bind" => [
                            "nama_instansi" => $namaInstansi
                        ]
                    ]
                );

                if (empty($instansi)) {
                    throw new ValidationException([
                        [
                            'field' => 'status',
                            'message' => 'Instansi tujuan tindak lanjut tidak dapat ditemukan',
                        ],
                    ]);
                }

                $idInstansi = $instansi->id;
            }

            $diskusiBansos->id_instansi = $idInstansi;
        } elseif ($params['status'] == DiskusiBansos::DONE_BY_VERIFIKATOR) {
            $diskusiBansos->status = DiskusiBansos::DONE;
            $namaInstansi = DiskusiBansos::KPK_NAME;

            $instansi = Instansi::findFirst(
                [
                    "lower(nama) = :nama_instansi:",
                    "bind" => [
                        "nama_instansi" => $namaInstansi
                    ]
                ]
            );

            if (empty($instansi)) {
                throw new ValidationException([
                    [
                        'field' => 'status',
                        'message' => 'Instansi tujuan tindak lanjut tidak dapat ditemukan',
                    ],
                ]);
            }

            $idInstansi = $instansi->id;
            $diskusiBansos->id_instansi = $idInstansi;
        } else {
            $diskusiBansos->status = $params['status'];
        }
        $resultDiskusi = $diskusiBansos->save();

        $diskusiBansosHistory = new DiskusiBansosHistory();
        $diskusiBansosHistory->id_diskusi_bansos = $diskusiBansos->id;
        $diskusiBansosHistory->keterangan = '-';
        $diskusiBansosHistory->id_komentar = $komentar->id;
        $diskusiBansosHistory->id_instansi = $idInstansi;
        $diskusiBansosHistory->id_user = $this->controller->shared->user->um_id;
        $diskusiBansosHistory->status = $diskusiBansos->status;
        $resultHistory = $diskusiBansosHistory->create();

        if ($resultDiskusi && $resultHistory) {
            $service->notifyKorwilPemdaUser($diskusiBansos, DiskusiService::BANSOS_NOTIFICATION_CONFIRMATION);
            // todo uncomment di branch issue #1124
            // $this->mailToStakeholder($diskusiBansos, $komentar);

            //otomatis merubah menjadi done apabila ke dumasKPK
            if ($params['status'] == DiskusiBansos::CONFIRMED_TO_DUMASKPK) {
                $diskusiBansos = DiskusiBansos::findFirst($diskusiBansos->id);

                $diskusiBansos->status = DiskusiBansos::DONE;
                $resultDiskusi = $diskusiBansos->save();

                $diskusiBansosHistory = new DiskusiBansosHistory();
                $diskusiBansosHistory->id_diskusi_bansos = $diskusiBansos->id;
                $diskusiBansosHistory->keterangan = 'Diselesaikan oleh DuMas KPK';
                $diskusiBansosHistory->id_komentar = $komentar->id;
                $diskusiBansosHistory->id_instansi = $idInstansi;
                $diskusiBansosHistory->id_user = $this->controller->shared->user->um_id;
                $diskusiBansosHistory->status = $diskusiBansos->status;
                $resultHistory = $diskusiBansosHistory->create();

                if ($resultDiskusi && $resultHistory) {
                    $service->notifyKorwilPemdaUser($diskusiBansos, DiskusiService::BANSOS_NOTIFICATION_CONFIRMATION);
                } else {
                    throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Save Diskusi Bansos Error");
                }
            }
        }
    }

    private function handleFollowUp($params, $komentar, $diskusiBansos)
    {
        $detailTopik = TopikDiskusiBansos::findFirst([
            'conditions' => 'id = ?0',
            'bind' => [
                $diskusiBansos->id_topik
            ]
        ]);
        $tipeTopik = $detailTopik->type;

        if (
            ($tipeTopik == TopikDiskusiBansos::TYPE_BANSOS && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_BANSOS]))
            || ($tipeTopik == TopikDiskusiBansos::TYPE_COVID && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_COVID]))
            || ($tipeTopik == TopikDiskusiBansos::TYPE_IKN && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_IKN]))
            || ($tipeTopik == TopikDiskusiBansos::TYPE_DESA && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_DESA]))
            || ($tipeTopik == TopikDiskusiBansos::TYPE_KAMPUS && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_KAMPUS]))
            || ($tipeTopik == TopikDiskusiBansos::TYPE_PELABUHAN && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_PELABUHAN]))
            || ($tipeTopik == TopikDiskusiBansos::TYPE_BPJS_KESEHATAN && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_BPJS_KESEHATAN]))
            || ($tipeTopik == TopikDiskusiBansos::TYPE_PENDIDIKAN && !$this->controller->hasScopes([self::SCOPE_FOLLOWUP_PENDIDIKAN]))
        ) {
            return;
        }

        //echo($params['status']);
        if ($params['status'] != DiskusiBansos::ON_PROGRESS && $params['status'] != DiskusiBansos::DONE) {
            return;
        }

        $service = new DiskusiService($this->controller->config, $this->controller->shared, $this->controller->request, $this->controller->minio);

        $userInstansi = $this->controller->shared->user->id_instansi;
        //echo($userInstansi);

        if ($diskusiBansos->id_instansi != $userInstansi) {
            return;
        }

        $diskusiBansos->status = $params['status'];
        $resultDiskusi = $diskusiBansos->save();

        $diskusiBansosHistory = new DiskusiBansosHistory();
        $diskusiBansosHistory->id_diskusi_bansos = $diskusiBansos->id;
        $diskusiBansosHistory->keterangan = '-';
        $diskusiBansosHistory->id_komentar = $komentar->id;
        $diskusiBansosHistory->id_user = $this->controller->shared->user->um_id;
        $diskusiBansosHistory->status = $params['status'];
        $diskusiBansosHistory->id_instansi = $diskusiBansos->id_instansi;
        $resultHistory = $diskusiBansosHistory->create();

        if ($resultDiskusi && $resultHistory) {
            $service->notifyKorwilPemdaUser($diskusiBansos, DiskusiService::BANSOS_NOTIFICATION_FOLLOWUP);
            // todo uncomment di branch issue #1124
            // $this->mailToStakeholder($diskusiBansos, $komentar);
        }
    }

    private function findInstansiOrigin(DiskusiBansos  $diskusiBansos) {
        $instansi = Instansi::findFirst(['id = :id:', 'bind' => ['id' => $diskusiBansos->id_instansi_origin]]);
        if (!$instansi) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Instansi asal tidak ditemukan");
        }

        return $instansi;
    }

    /**
     * @param $nama
     * @return Instansi
     * @throws ValidationException
     */
    private function findInstansiByNama($nama) {
        $instansi = Instansi::findFirst(
            [
                "lower(nama) ILIKE :nama_instansi:",
                "bind" => [
                    "nama_instansi" => $nama
                ]
            ]
        );

        if (empty($instansi)) {
            throw new ValidationException([
                [
                    'field' => 'status',
                    'message' => 'Instansi tujuan tindak lanjut tidak dapat ditemukan',
                ],
            ]);
        }

        return $instansi;
    }

    private function mailToStakeholder(DiskusiBansos $diskusiBansos, DiskusiComment $diskusiComment) {
        if (!$this->mailHelper) {
            throw new CustomErrorException(BaseResponse::UNEXPECTED_ERROR, "Mail Helper belum di konfigurasi!");
        }
        switch ($diskusiBansos->status) {
            case DiskusiBansos::CONFIRMED:
                $this->mailConfirmedToStakeholder($diskusiBansos, $diskusiComment);
                break;
            case DiskusiBansos::ON_PROGRESS:
                $this->mailFollowupToStakeholder($diskusiBansos, $diskusiComment);
                break;
            case DiskusiBansos::DONE:
                $this->mailDoneToStakeholder($diskusiBansos, $diskusiComment);
                break;
            default:
                break;
        }
    }

    private function mailConfirmedToStakeholder(DiskusiBansos $diskusiBansos, DiskusiComment $diskusiComment) {
        $stakeholders = array_merge($this->findUserFollowUp($diskusiBansos), $this->findUserCreator($diskusiBansos));
        foreach ($stakeholders as $stakeholder) {
            $this->mailHelper->queue(
                $stakeholder['email'],
                "[JAGA] Keluhan Telah Diteruskan",
                "$diskusiComment->comment",
                true
            );
        }
    }

    private function mailFollowupToStakeholder(DiskusiBansos $diskusiBansos, DiskusiComment $diskusiComment) {
        $stakeholders = $this->findUserCreator($diskusiBansos);
        foreach ($stakeholders as $stakeholder) {
            $this->mailHelper->queue(
                $stakeholder['email'],
                "[JAGA] Keluhan Sedang Ditindaklanjuti",
                "$diskusiComment->comment",
                true
            );
        }
    }

    private function mailDoneToStakeholder(DiskusiBansos $diskusiBansos, DiskusiComment $diskusiComment) {
        $stakeholders = $this->findUserCreator($diskusiBansos);
        foreach ($stakeholders as $stakeholder) {
            $this->mailHelper->queue(
                $stakeholder['email'],
                "[JAGA] Keluhan Telah Selesai Ditindaklanjuti",
                "$diskusiComment->comment"
            );
        }
    }

    private function findUserFollowUp(DiskusiBansos $diskusiBansos) {
        $followUpScope = "bansos.follow_up";
        switch ($diskusiBansos->TopikDiskusiBansos->type) {
            case TopikDiskusiBansos::TYPE_DESA:
                $followUpScope = self::SCOPE_FOLLOWUP_DESA;
                break;
            case TopikDiskusiBansos::TYPE_PELABUHAN:
                $followUpScope = self::SCOPE_FOLLOWUP_PELABUHAN;
                break;
            case TopikDiskusiBansos::TYPE_IKN:
                $followUpScope = self::SCOPE_FOLLOWUP_IKN;
                break;
            case TopikDiskusiBansos::TYPE_KAMPUS:
                $followUpScope = self::SCOPE_FOLLOWUP_KAMPUS;
                break;
            case TopikDiskusiBansos::TYPE_BPJS_KESEHATAN:
                $followUpScope = self::SCOPE_FOLLOWUP_BPJS_KESEHATAN;
                break;
            case TopikDiskusiBansos::TYPE_PENDIDIKAN:
                $followUpScope = self::SCOPE_FOLLOWUP_PENDIDIKAN;
                break;
        }

        return UmUser::query()
            ->columns('um_id, email')
            ->join('UsersRoles', 'UsersRoles.user_id = UmUser.um_id')
            ->join('RolesScopes', 'RolesScopes.role_id = UsersRoles.role_id')
            ->join('Scopes', 'Scopes.id = RolesScopes.scope_id')
            ->where("Scopes.name ilike :nama_scope: and UmUser.id_instansi = :id_instansi:")
            ->bind(
                [
                    "nama_scope" => $followUpScope,
                    "id_instansi" => $diskusiBansos->id_instansi
                ]
            )
            ->execute()
            ->toArray();
    }

    private function findUserCreator(DiskusiBansos $diskusiBansos) {
        return UmUser::query()
            ->columns('um_id, email')
            ->where("um_id = :um_id: ")
            ->bind(
                [
                    "um_id" => $diskusiBansos->Diskusi->user_id
                ]
            )
            ->execute()
            ->toArray();
    }

    public function validateUpdateStatus($params) {
        if ($this->controller->hasScopes(['bansos.confirm_all'])) {
            $validatedParams = $this->validateUpdateStatusConfirmAll($params);
        } elseif ($this->controller->hasScopes(['bansos.confirm_assigned'])) {
            $validatedParams = $this->validateUpdateStatusConfirmAssigned($params);
        } else {
            $validatedParams = $this->validateUpdateStatusFollowUp($params);
        }

        $diskusi_id = $validatedParams["diskusi_id"];
        $this->diskusi = Diskusi::findFirst(
            [
                "id = :id:",
                "bind" => [
                    "id" => $diskusi_id
                ]
            ]
        );
        if (!$this->diskusi) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, 'Komentar gagal disimpan. Diskusi tidak ditemukan');
        }
        if ($this->diskusi->isDeleted()) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, 'Komentar gagal disimpan. Diskusi telah dikunci');
        }
        if (!empty($this->diskusi->report())) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Komentar gagal disimpan. Diskusi telah dilaporkan');
        }

        $this->keluhan = DiskusiBansos::findFirst(
            [
                "deleted_at is null and id_diskusi = :id_diskusi:",
                "bind" => [
                    "id_diskusi" => $this->diskusi->id
                ]
            ]
        );
        if (!$this->keluhan) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, 'Komentar gagal disimpan. Keluhan tidak ditemukan');
        }

        return $validatedParams;
    }

    private function validateUpdateStatusConfirmAll($params) {
        $rules = [
            'diskusi_id' => ['validators' => ['required', 'digit']],
            'komentar' => ['validators' => ['required']],
            'confirm_all_status' => ['validators' => ['required']]
        ];

        if (array_key_exists('confirm_all_status', $params) && $params['confirm_all_status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI) {
            $rules['id_instansi'] = ['validators' => ['required', 'digit']];
        }

        return $this->controller->validate(
            $params,
            $rules
        );
    }

    private function validateUpdateStatusConfirmAssigned($params) {
        $rules = [
            'diskusi_id' => ['validators' => ['required', 'digit']],
            'komentar' => ['validators' => ['required']],
            'confirm_assigned_status' => ['validators' => ['required']]
        ];

        if (array_key_exists('confirm_assigned_status', $params) && $params['confirm_assigned_status'] == DiskusiBansos::CONFIRMED_TO_INSTANSI) {
            $rules['id_instansi'] = ['validators' => ['required', 'digit']];
        }

        return $this->controller->validate(
            $params,
            $rules
        );
    }

    private function validateUpdateStatusFollowUp($params) {
//        todo cari alternatif untuk memastikan user instansi TL mengubah status keluhan sebelum membuat komentar
//        $topik = TopikDiskusiBansos::findFirst([
//            'conditions' => 'deleted_at IS NULL and id = ?0',
//            'bind' => [
//                $this->keluhan->id_topik
//            ]
//        ]);
//        $topik_type = empty($topik) ? TopikDiskusiBansos::TYPE_BANSOS : $topik->type;
//        if(
//            ( ($this->controller->hasScopes(['bansos.follow_up']) && $topik_type == TopikDiskusiBansos::TYPE_BANSOS) ||
//                ($this->controller->hasScopes(['covid.dinkes_pemda']) && $topik_type == TopikDiskusiBansos::TYPE_COVID) ||
//                ($this->controller->hasScopes(['keluhan.ikn.follow_up']) && $topik_type == TopikDiskusiBansos::TYPE_IKN) ||
//                ($this->controller->hasScopes(['keluhan.desa.follow_up']) && $topik_type == TopikDiskusiBansos::TYPE_DESA) ||
//                ($this->controller->hasScopes(['keluhan.kampus.follow_up']) && $topik_type == TopikDiskusiBansos::TYPE_KAMPUS) ||
//                ($this->controller->hasScopes(['keluhan.pelabuhan.follow_up']) && $topik_type == TopikDiskusiBansos::TYPE_PELABUHAN) ||
//                ($this->controller->hasScopes(['keluhan.bpjs.follow_up']) && $topik_type == TopikDiskusiBansos::TYPE_BPJS_KESEHATAN)
//            )
//            && $this->keluhan->status == DiskusiBansos::CONFIRMED
//        ) {
//            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Komentar gagal disimpan. Silakan ubah status keluhan terlebih dahulu.');
//        }

        return $this->controller->validate(
            $params,
            [
                'diskusi_id' => ['validators' => ['required', 'digit']],
                'komentar' => ['validators' => ['required']],
                'follow_up_status' => ['validators' => ['required']]
            ]
        );
    }

    public function handleUpdateStatusKeluhanPemilu() {
        $topik = TopikDiskusiBansos::findFirst([
            'conditions' => 'deleted_at IS NULL and id = ?0',
            'bind' => [
                $this->keluhan->id_topik
            ]
        ]);

        $topik_type = empty($topik) ? TopikDiskusiBansos::TYPE_BANSOS : $topik->type;
        if($this->controller->hasScopes(['keluhan.pemilu.monitoring']) && $topik_type == TopikDiskusiBansos::TYPE_PEMILU) {
            if($this->keluhan->id_instansi == $this->controller->shared->user->id_instansi) {
                if($this->keluhan->status != DiskusiBansos::DONE) {
                    $keluhanPemilu = DiskusiKeluhanPemilu::findFirst([
                        'id_diskusi = ?0 AND id_diskusi_bansos = ?1',
                        'bind' => [
                            $this->keluhan->id_diskusi,
                            $this->keluhan->id,
                        ]
                    ]);
                    $keluhanPemilu->isresponded = 1;
                    $keluhanPemilu->updated_at = date('Y-m-d H:i:s');
                    $keluhanPemilu->respond_at = date('Y-m-d H:i:s');
                    $keluhanPemilu->save();

                    $this->keluhan->status = DiskusiBansos::DONE;
                    $this->keluhan->save();

                    $bansosHistory = new DiskusiBansosHistory();
                    $bansosHistory->id_diskusi_bansos = $this->keluhan->id;
                    $bansosHistory->keterangan = '-';
                    $bansosHistory->id_komentar = $this->komentar->id;
                    $bansosHistory->id_instansi = $this->keluhan->id_instansi;
                    $bansosHistory->id_user = $this->controller->shared->user->um_id;
                    $bansosHistory->status = DiskusiBansos::DONE;
                    $bansosHistory->save();
                }
            }
        }
    }
}
