<?php

class KorsupgahSubIndikatorController extends BaseController
{
    public function list()
    {
        $getParams = $this->request->get();

        $getParams['limit'] = $this->getDefaultLimit($getParams);
        $getParams['offset'] = array_key_exists('offset', $getParams) ? $getParams['offset'] : 0;
        $getParams['keyword'] = array_key_exists('keyword', $getParams) ? $getParams['keyword'] : '';
        $getParams['keyword_area_intervensi'] = array_key_exists('keyword_area_intervensi', $getParams) ? $getParams['keyword_area_intervensi'] : '';
        $getParams['order_by'] = array_key_exists('order_by', $getParams) ? strtolower($getParams['order_by']) : 'id';
        $getParams['order_direction'] = array_key_exists('order_direction', $getParams) ? strtolower($getParams['order_direction']) : 'asc';

        $allowed_order = [
            'id',
            'id_indikator',
            'total_answered_question',
            'total_unverified_question',
            'total_aset_progress',
            'total_pad_progress',
            'percent_verification_pad',
            'percent_verification_aset',
            'percent_answered_question'
        ];
        $allowed_order_direction = ['asc', 'desc'];

        $params = $this->validate(
            $getParams,
            [
                'limit' => ['validators' => ['digit']],
                'offset' => ['validators' => ['digit']],
                'keyword' => ['validators' => []],
                'keyword_area_intervensi' => ['validators' => []],
                'order_by' => ['validators' =>  [[
                    'name' => 'inclusion_in',
                    'params' => $allowed_order
                ]]],
                'order_direction' => ['validators' =>  [[
                    'name' => 'inclusion_in',
                    'params' => $allowed_order_direction
                ]]]
            ]
        );

        $ksi = KorsupgahSubIndikator::query()
            ->columns(
                KorsupgahSubIndikator::class.".id,".KorsupgahSubIndikator::class.".nama,".KorsupgahSubIndikator::class.".info_nilai,".KorsupgahSubIndikator::class.".info_lampiran,".KorsupgahSubIndikator::class.".created_at,".KorsupgahSubIndikator::class.".updated_at,".KorsupgahSubIndikator::class.".deleted_at,".KorsupgahSubIndikator::class.".created_by,".KorsupgahSubIndikator::class.".updated_by,".KorsupgahSubIndikator::class.".presentase_bobot,".
                KorsupgahIndikator::class.".id as id_indikator,".KorsupgahIndikator::class.".nama as nama_indikator,".
                KorsupgahAreaIntervensi::class.".id as id_area_intervensi,".KorsupgahAreaIntervensi::class.".nama as nama_area_intervensi"
            )
            ->join(KorsupgahIndikator::class, KorsupgahIndikator::class.".id = ".KorsupgahSubIndikator::class.".id_indikator")
            ->join(KorsupgahAreaIntervensi::class, KorsupgahAreaIntervensi::class.".id = ".KorsupgahIndikator::class.".id_area_intervensi")
            ->where(KorsupgahSubIndikator::class.".nama ilike :keyword:")
            ->andWhere(KorsupgahAreaIntervensi::class.".nama ilike :keyword_area_intervensi: OR ".KorsupgahAreaIntervensi::class.".keterangan ilike :keyword_area_intervensi:")
            ->bind([
                'keyword' => '%' . $params['keyword'] . '%',
                'keyword_area_intervensi' => '%' . $params['keyword_area_intervensi'] . '%'
            ])
            ->limit($params['limit'], $params['offset'])
            ->orderBy(KorsupgahSubIndikator::class.".{$params['order_by']} {$params['order_direction']}")
            ->execute()->toArray();

        $total_record = $this->rawQuery("
            SELECT COUNT(*) FROM korsupgah_sub_indikator si 
            LEFT JOIN korsupgah_indikator i ON i.id = si.id_indikator 
            LEFT JOIN korsupgah_area_intervensi ai ON ai.id = i.id_area_intervensi
            WHERE si.nama ILIKE '%" . $params['keyword'] . "%' AND (ai.nama ILIKE '%" . $params['keyword_area_intervensi'] . "%' OR ai.keterangan ILIKE '%" . $params['keyword_area_intervensi'] . "%')
        ")[0]['count'];

        return new PaginatedResponse($ksi, $total_record, $params['limit'], $params['offset']);
    }

    public function create()
    {
        $this->checkScopes(['korsupgah.admin']);

        $rawBody = $this->request->getJsonRawBody(true);
        $params = $this->validate(
            $rawBody,
            [
                'id_indikator' => ['validators' => ['required', 'digit']],
                'nama' => ['validators' => ['required']],
                'info_nilai' => ['validators' => ['required']],
                'info_lampiran' => ['validators' => ['required']],
                'presentase_bobot' => ['validators' => ['required', 'digit']]
            ]
        );



        $indikator = KorsupgahIndikator::findFirst($params['id_indikator']);

        if (empty($indikator)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Indikator tidak ditemukan');
        }

        if (!empty($indikator->deleted_at)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Indikator tidak aktif');
        }

        if ($params['presentase_bobot'] > 100) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Nilai valid hanya 0-100');
        }

        $ksi = new KorsupgahSubIndikator();
        $ksi->id_indikator = $params['id_indikator'];
        $ksi->nama = $params['nama'];
        $ksi->info_nilai = $params['info_nilai'];
        $ksi->info_lampiran = $params['info_lampiran'];
        $ksi->presentase_bobot = $params['presentase_bobot'];
        $ksi->created_at = date('Y-m-d H:i:s');
        $ksi->created_by = $this->shared->user->um_id;
        $status = $ksi->save();
        if (!$status) {
            $errors = $ksi->getMessages();
            $error_messages = [];

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

            throw new ValidationException($error_messages);
        } else {
            return new CollectionPaginatedResponse([$ksi]);
        }
    }

    public function update($id)
    {
        $this->checkScopes(['korsupgah.admin']);
        $ksi = KorsupgahSubIndikator::findFirst($id);

        if (empty($ksi)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id' . $id . 'tidak ditemukan');
        endif;

        if (!empty($ksi->deleted_at)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id ' . $id  . 'mungkin sudah terhapus');
        endif;

        $rawBody = $this->request->getJsonRawBody(true);

        $params = $this->validate(
            $rawBody,
            [
                'id_indikator' => ['validators' => ['required', 'digit']],
                'nama' => ['validators' => ['required']],
                'info_nilai' => ['validators' => ['required']],
                'info_lampiran' => ['validators' => ['required']],
                'presentase_bobot' => ['validators' => ['required', 'digit']]
            ]
        );

        $indikator = KorsupgahIndikator::findFirst($params['id_indikator']);

        if (empty($indikator)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Indikator tidak ditemukan');
        }

        if (!empty($indikator->deleted_at)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Indikator tidak aktif');
        }

        if ($params['presentase_bobot'] > 100) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Nilai valid hanya 0-100');
        }


        $ksi->id_indikator = $params['id_indikator'];
        $ksi->nama = $params['nama'];
        $ksi->info_nilai = $params['info_nilai'];
        $ksi->info_lampiran = $params['info_lampiran'];
        $ksi->presentase_bobot = $params['presentase_bobot'];
        $ksi->updated_at = date('Y-m-d H:i:s');
        $ksi->created_by = $this->shared->user->um_id;;
        $status = $ksi->save();
        if (!$status) {
            $errors = $ksi->getMessages();
            $error_messages = [];

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

            throw new ValidationException($error_messages);
        } else {
            return new CollectionPaginatedResponse([$ksi]);
        }
    }

    public function remove($id)
    {
        $this->checkScopes(['korsupgah.admin']);
        $ksi = KorsupgahSubIndikator::findFirst($id);

        if (empty($ksi)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id' . $id . 'tidak ditemukan');
        endif;

        if (!empty($ksi->deleted_at)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id ' . $id  . 'mungkin sudah terhapus');
        endif;

        $date = date('Y-m-d H:i:s');
        $ksi->updated_at = $date;
        $ksi->deleted_at = $date;
        $ksi->updated_by = $this->shared->user->um_id;;
        $status = $ksi->save();
        if (!$status) {
            $errors = $ksi->getMessages();
            $error_messages = [];

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

            throw new ValidationException($error_messages);
        } else {
            return new CollectionPaginatedResponse([$ksi]);
        }
    }

    public function restore($id)
    {
        $this->checkScopes(['korsupgah.admin']);

        $ksi = KorsupgahSubIndikator::findFirst($id);
        if (empty($ksi)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id' . $id . 'tidak diketemukan');
        endif;

        if (empty($ksi->deleted_at)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id' . $id . 'sudah aktif');
        endif;

        $ksi->updated_at = date('Y-m-d H:i:s');
        $ksi->deleted_at = null;
        $ksi->updated_by = $this->shared->user->um_id;;
        $status = $ksi->save();

        if (!$status) {
            $errors = $ksi->getMessages();
            $error_messages = [];

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

            throw new ValidationException($error_messages);
        } else {
            return new CollectionPaginatedResponse([$ksi]);
        }
    }

    public function detail($id)
    {
        $this->checkIsAuthenticated();
        $ksi = KorsupgahSubIndikator::findFirst($id);
        if (empty($ksi)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'id' . $id . 'tidak diketemukan');
        endif;

        $result = $ksi->toDetail();
        return new CollectionPaginatedResponse([$result]);
    }
}
