<?php

class TopikDiskusiBansosController extends BaseController {
    public function index() {
        $this->checkScopes(['bansos.confirm_all']);
        $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'] : null;
        $params['type'] = array_key_exists('type', $params) ? $params['type'] : null;

        $validatedRequest = $this->validate(
            $params,
            [
                'limit' => [ 'validators' => ['digit'] ],
                'offset' => [ 'validators' => ['digit'] ],
                'keyword' => ['validators' => [[
                    'name' => 'max_string',
                    'params' => 100
                ]]],
                'type' => ['validators' => [[
                    'name' => 'max_string',
                    'params' => 10
                ]]]
            ]
        );

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

        if (!is_null($validatedRequest["keyword"])) {
            $strWhere .= " and lower(deskripsi) like :keyword:";
            $bind["keyword"] = '%' . mb_strtolower($validatedRequest["keyword"]) . '%';
        }

        if($params['type']) {
            $strWhere .=  " AND type = :type:";
            $bind['type'] = $params['type'];
        }

        $total = TopikDiskusiBansos::count(
            [
                $strWhere,
                "bind" => $bind,
            ]
        );

        $data = TopikDiskusiBansos::find(
            [
                $strWhere,
                "bind" => $bind,
                "limit" => $validatedRequest['limit'],
                "offset" => $validatedRequest['offset'],
                "order" => "view_order ASC, id"
            ]
        );

        return new PaginatedResponse($data, $total, $validatedRequest['limit'], $validatedRequest['offset']);
    }

    public function detail($id) {
        $this->checkScopes(['bansos.confirm_all']);
        $data = TopikDiskusiBansos::findFirst('id = ' . $id);
        if (!$data) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Topik diskusi dengan ID [" . $id . "] tidak ditemukan.");
        }

        return new SimpleResponse($data);
    }

    public function create() {
        $this->checkScopes(['bansos.confirm_all']);
        $rawBody = $this->request->getJsonRawBody(true);
        $params = $this->validate(
            $rawBody,
            [
                'deskripsi' => ['validators' => ['required', [
                    'name' => 'max_string',
                    'params' => 255
                ]]],
                'type' => ['validators' => ['required', [
                    'name' => 'max_string',
                    'params' => 10
                ]]],
                'view_order' => ['validators' => ['required', 'digit']]
            ]
        );
        $record = new TopikDiskusiBansos();
        $record->deskripsi = $params['deskripsi'];
        $record->type = $params['type'];
        $record->view_order = $params['view_order'];
        $success = $record->save();
        if (!$success) {
            $errors = $record->getMessages();
            $error_messages = [];

            foreach ($errors as $key => $error) {
                $error_messages[] = ["field" => $error->getField(), "message" => $error->getMessage()];
            }

            throw new ValidationException($error_messages);
        }

        $record = TopikDiskusiBansos::findOrFail($record->id);

        return new SimpleResponse($record);
    }

    public function update($id) {
        $this->checkScopes(['bansos.confirm_all']);
        $rawBody = $this->request->getJsonRawBody(true);
        $params = $this->validate(
            $rawBody,
            [
                'deskripsi' => ['validators' => ['required', [
                    'name' => 'max_string',
                    'params' => 255
                ]]],
                'type' => ['validators' => ['required', [
                    'name' => 'max_string',
                    'params' => 10
                ]]],
                'view_order' => ['validators' => ['required', 'digit']]
            ]
        );
        /**
         * @var TopikDiskusiBansos $record
         */
        $record = TopikDiskusiBansos::findOrFail($id);
        $record->deskripsi = $params['deskripsi'];
        $record->type = $params['type'];
        $record->view_order = $params['view_order'];
        $record->updated_at = 'now()';
        $success = $record->save();
        if (!$success) {
            $errors = $record->getMessages();
            $error_messages = [];

            foreach ($errors as $key => $error) {
                $error_messages[] = ["field" => $error->getField(), "message" => $error->getMessage()];
            }

            throw new ValidationException($error_messages);
        }
        $record = TopikDiskusiBansos::findOrFail($id);
        return new SimpleResponse($record);
    }

    public function delete($id) {
        $this->checkScopes(['bansos.confirm_all']);
        /**
         * @var TopikDiskusiBansos $record
         */
        $record = TopikDiskusiBansos::findFirst($id);
        if (!$record) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Topik diskusi dengan ID [" . $id . "] tidak ditemukan");
        }
        if ($record->deleted_at != null) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Topik diskusi dengan ID [" . $id . "] telah dihapus sebelumnya");
        }
        $record->deleted_at = 'now()';
        $success = $record->save();
        if (!$success) {
            $errors = $record->getMessages();
            $error_messages = [];

            foreach ($errors as $key => $error) {
                $error_messages[] = ["field" => $error->getField(), "message" => $error->getMessage()];
            }

            throw new ValidationException($error_messages);
        }
        $record = TopikDiskusiBansos::findFirst($id);
        return new SimpleResponse($record);
    }

    public function restore($id) {
        $this->checkScopes(['bansos.confirm_all']);
        /**
         * @var TopikDiskusiBansos $record
         */
        $record = TopikDiskusiBansos::findFirst($id);
        if (!$record) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Topik diskusi dengan ID [" . $id . "] tidak ditemukan");
        }
        if ($record->deleted_at == null) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Topik diskusi dengan ID [" . $id . "] belum dihapus sebelumnya");
        }
        $record->deleted_at = null;
        $success = $record->save();
        if (!$success) {
            $errors = $record->getMessages();
            $error_messages = [];

            foreach ($errors as $key => $error) {
                $error_messages[] = ["field" => $error->getField(), "message" => $error->getMessage()];
            }

            throw new ValidationException($error_messages);
        }
        $record = TopikDiskusiBansos::findFirst($id);
        return new SimpleResponse($record);
    }

    public function listType() {
        $result = $this->rawQuery('SELECT DISTINCT(type) FROM jaga.topik_diskusi_bansos;');
        return new CollectionPaginatedResponse($result);
    }

    public function confirmOptionsPelabuhan($idTopik) {
        $this->checkOneOfScopes(['bansos.confirm_all', 'bansos.confirm_assigned']);
        $topikKeluhan = TopikDiskusiBansos::findFirst(['id = :id:', 'bind' => ['id' => $idTopik]]);
        if (!$topikKeluhan) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Topik Keluhan tidak ditemukan");
        }

        $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'] : null;
        $params['type'] = array_key_exists('type', $params) ? $params['type'] : null;

        $validatedRequest = $this->validate(
            $params,
            [
                'id_instansi' => [ 'validators' => ['required','digit']],
            ]
        );
        $idInstansi = $validatedRequest['id_instansi'];
        /** @var Instansi $pelabuhan */
        $pelabuhan = Instansi::findFirst(["id = :id: and keluhan_type = 'PELABUHAN'", 'bind' => ['id' => $idInstansi]]);
        if (!$pelabuhan) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Pelabuhan tidak ditemukan");
        }

        $options = [];
        switch ($topikKeluhan->deskripsi) {
            case "Pelabuhan - Layanan Kapal":
            case "Pelabuhan - Layanan Transportasi Pelabuhan":
                if (in_array(trim($pelabuhan->nama), DiskusiBansos::PELABUHAN_HAS_KSU_KOPU)) {
                    $options = [
                        [
                            "label"=> 'Diteruskan ke KSU',
                            "value" => 30
                        ],
                        [
                            "label"=> 'Diteruskan ke KOPU',
                            "value" => 31
                        ],
                    ];
                }
                else if (in_array(trim($pelabuhan->nama), DiskusiBansos::PELABUHAN_HAS_KUPP)) {
                    $options = [
                        [
                            "label"=> 'Diteruskan ke Kantor UPP',
                            "value" => DiskusiBansos::CONFIRMED_TO_KUPP
                        ],
                    ];
                }
                else {
                    $options = [
                        [
                            "label"=> 'Diteruskan ke KSOP',
                            "value" => DiskusiBansos::CONFIRMED_TO_KSOP
                        ],
                    ];
                }
                $options = array_merge($options, [
                    [
                        "label" => 'Tidak Ada Respon Instansi',
                        "value" => 5
                    ],
                    [
                        "label" => 'Tidak Ada Respon Pelapor',
                        "value" => 6
                    ],
                    [
                        "label" => 'Selesai',
                        "value" => 40
                    ]
                ]);
                break;
            case "Pelabuhan - Layanan Barang":
                $options = [
                    [
                        "label" => 'Diteruskan ke Karantina Pertanian',
                        "value" => 33
                    ],
                    [
                        "label" => 'Diteruskan ke Karantina Perikanan',
                        "value" => 34
                    ],
                    [
                        "label" => 'Tidak Ada Respon Instansi',
                        "value" => 5
                    ],
                    [
                        "label" => 'Tidak Ada Respon Pelapor',
                        "value" => 6
                    ],
                    [
                        "label" => 'Selesai',
                        "value" => 40
                    ]
                ];
                break;
            case "Pelabuhan - Layanan Pembayaran":
            case "Pelabuhan - Layanan Ekspor/Impor":
            case "Pelabuhan - Layanan Pintu Keluar/Masuk":
            case "Pelabuhan - Layanan Pengeluaran Barang":
            case "Pelabuhan - Layanan Domestik":
            case "Pelabuhan - Layanan Tenaga Bongkar Muat":
                $options = [
                    [
                        "label" => 'Diteruskan ke Instansi Terkait',
                        "value" => 29
                    ],
                    [
                        "label" => 'Tidak Ada Respon Instansi',
                        "value" => 5
                    ],
                    [
                        "label" => 'Tidak Ada Respon Pelapor',
                        "value" => 6
                    ],
                    [
                        "label" => 'Selesai',
                        "value" => 40
                    ]
                ];
                break;
            default:
                break;
        }

        return new SimpleResponse($options);
    }
}
