<?php

class KorwilAsetProgressController extends BaseController
{
    public function index()
    {
        $this->checkIsAuthenticated();

        $getParams = $this->request->get();

        $getParams['id_aset_target'] = array_key_exists('id_aset_target', $getParams) ? $getParams['id_aset_target'] : null;
        $getParams['limit'] = $this->getDefaultLimit($getParams);
        $getParams['offset'] = array_key_exists('offset', $getParams) ? $getParams['offset'] : 0;
        $getParams['keyword'] = array_key_exists('keyword', $getParams) ? $getParams['keyword'] : '';

        $params = $this->validate(
            $getParams,
            [
                'id_aset_target' => ['validators' => ['digit']],
                'limit' => ['validators' => ['digit']],
                'offset' => ['validators' => ['digit']],
                'keyword' => ['validators' => []],
            ]
        );

        if (empty($params['id_aset_target'])) {
            $korwilAsetProgressList = KorwilAsetProgress::find([
                'conditions' => 'sertifikasi ilike :keyword:',
                'bind' => [
                    'keyword' => '%' . $params['keyword'] . '%'
                ],
                'limit' => $params['limit'],
                'offset' => $params['offset']
            ]);
        } else {
            $cekAsetTarget = KorwilAsetTarget::findByIdInstansi($params['id_aset_target']);

            if (count($cekAsetTarget) == 0) {
                throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Aset tidak ditemukan');
            }

            foreach ($cekAsetTarget as $key => $cat) {
                $korwilAsetProgressList = KorwilAsetProgress::find([
                    'conditions' => 'sertifikasi ilike :keyword: AND id_aset_target=:id_aset_target: ',
                    'bind' => [
                        'keyword' => '%' . $params['keyword'] . '%',
                        'id_aset_target' => $cat->id
                    ],
                    'limit' => $params['limit'],
                    'offset' => $params['offset']
                ]);

                if (empty($korwilAsetProgressList)) {
                    throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Progress aset tidak ditemukan');
                }
            }
        }

        $total_record = KorwilAsetProgress::count();

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

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

        $korwilAsetProgressDetail = KorwilAsetProgress::findFirst($id);
        if (empty($korwilAsetProgressDetail)) :
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Korwil aset progress dengan id' . $id . 'tidak diketemukan');
        endif;

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

    public function submit()
    {
        $this->checkOneOfScopes(['korsupgah.answer', 'aset.answer']);

        $rawBody = $this->request->getJsonRawBody(true);
        $params = $this->validate(
            $rawBody,
            [
                'bulan' => ['validators' => ['required', 'digit']],
                'id_aset_target' => ['validators' => ['required', 'digit']],
                'sertifikasi' => ['validators' => ['required']],
                'belum_sertifikasi' => ['validators' => []],
                'keterangan' => ['validators' => []],
                'attachments' => ['validators' => []],
                'deleted_attachments' => ['validators' => []]
            ]
        );

        $korwilAsetTarget = KorwilAsetTarget::findFirst($params['id_aset_target']);

        if (empty($korwilAsetTarget)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Aset Target tidak ditemukan');
        }

        $currentInstansi = $this->shared->user->instansi;
        if (empty($currentInstansi)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'User tidak memiliki instansi');
        }

        $instansiId = $currentInstansi->id;
        $cekInstansi = KorwilAsetTarget::findFirstByIdInstansi($instansiId);
        if (empty($cekInstansi)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'User tidak memiliki target aset');
        }

        if (!empty($params['attachments']) && !is_array($params['attachments'])) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Format Attachments tidak valid');
        }

        if (!empty($params['deleted_attachments']) && !is_array($params['deleted_attachments'])) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Format Deleted Attachments tidak valid');
        }
        if ($params['bulan'] > 12) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Format Bulan tidak valid');
        }

        $date = date('Y-m-d H:i:s');

        $cekAsetProgress = KorwilAsetProgress::findFirst([
            'conditions' => 'bulan = :bulan: AND id_aset_target =:iat:',
            'bind' => [
                'bulan' => $params['bulan'],
                'iat' => $korwilAsetTarget->id
            ]
        ]);

        if (!empty($cekAsetProgress)) {
            if (!empty($cekAsetProgress->verified_by) && $cekAsetProgress->id_aset_target == $korwilAsetTarget->id) {
                throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Data sudah diverifikasi');
            }
        }


        if (empty($cekAsetProgress) || $cekAsetProgress->id_aset_target != $korwilAsetTarget->id) {
            // INSERT ROW BARU
            $setAsetProgress = new KorwilAsetProgress();
            $setAsetProgress->bulan = $params['bulan'];
            $setAsetProgress->id_aset_target = $params['id_aset_target'];
            $setAsetProgress->status = KorwilAsetProgress::STATUS_INIT;
            $setAsetProgress->sertifikasi = $params['sertifikasi'];
            $setAsetProgress->belum_sertifikasi = $params['belum_sertifikasi'];
            $setAsetProgress->keterangan = $params['keterangan'];
            $setAsetProgress->created_at = $date;
            $setAsetProgress->submitted_by = $this->shared->user->um_id;
            $status = $setAsetProgress->save();

            $cekAsetProgress = $setAsetProgress;
        } else {
            // UPDATE ROW YANG ADA
            $cekAsetProgress->bulan = $params['bulan'];
            $cekAsetProgress->id_aset_target = $params['id_aset_target'];
            $cekAsetProgress->status = KorwilAsetProgress::STATUS_INIT;
            $cekAsetProgress->sertifikasi = $params['sertifikasi'];
            $cekAsetProgress->belum_sertifikasi = $params['belum_sertifikasi'];
            $cekAsetProgress->keterangan = $params['keterangan'];
            $cekAsetProgress->created_at = $date;
            $cekAsetProgress->submitted_by = $this->shared->user->um_id;
            $status = $cekAsetProgress->save();
        }

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

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

            throw new ValidationsException($error_messages);
        }

        if (!empty($params['deleted_attachments'])) {
            foreach ($params['deleted_attachments'] as $uuid) {
                $attachment_record = Attachments::findFirstByUuid($uuid);

                if (!empty($attachment_record)) {
                    $korwil_attachment_record = KorwilAsetAttachment::findFirstByIdAttachment($attachment_record->id);

                    if (!empty($korwil_attachment_record) && $korwil_attachment_record->tipe == KorwilAsetAttachment::TIPE_SUBMIT) {
                        $korwil_attachment_record->delete();
                    }

                    AttachmentHelper::delete($attachment_record, true, $this->minio);
                }
            }
        }

        if (!empty($params['attachments'])) {
            foreach ($params['attachments'] as $key => $uuid) {
                $attachment_record = Attachments::findFirstByUuid($uuid);

                if (!empty($attachment_record) && empty($attachment_record->deleted_at)) {
                    $existing_korwil_attachments = KorwilAsetAttachment::find([
                        'conditions' => 'id_attachment=:id_attachment: AND id_progress=:id_progress:',
                        'bind' => [
                            'id_attachment' => $attachment_record->id,
                            'id_progress' => $cekAsetProgress->id
                        ]
                    ]);

                    if (count($existing_korwil_attachments) < 1) {
                        $korsupgah_attachment = new KorwilAsetAttachment();
                        $korsupgah_attachment->id_attachment = $attachment_record->id;
                        $korsupgah_attachment->id_progress = $cekAsetProgress->id;
                        $korsupgah_attachment->tipe = KorwilAsetAttachment::TIPE_SUBMIT;
                        $korsupgah_attachment->created_by = $this->shared->user->um_id;
                        $korsupgah_attachment->save();

                        $attachment_record->status = Attachments::STATUS_REFERRED_KORWIL;
                        $attachment_record->referer = Attachments::REFERER_KORWIL_ANSWER;
                        $attachment_record->save();
                    }
                }
            }
        }
        return new CollectionPaginatedResponse([$cekAsetProgress]);
    }


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

        $rawBody = $this->request->getJsonRawBody(true);
        $params = $this->validate(
            $rawBody,
            [
                'sertifikasi_verifikasi' => ['validators' => ['required']],
                'belum_sertifikasi_verifikasi' => ['validators' => []],
                'keterangan_verifikasi' => ['validators' => []],
                'attachments' => ['validators' => []],
                'deleted_attachments' => ['validators' => []]
            ]
        );

        $korwilAsetProgress = KorwilAsetProgress::findFirst($id);
        $date = date('Y-m-d H:i:s');

        if (empty($korwilAsetProgress)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Aset progress tidak ditemukan');
        }

        $target = $korwilAsetProgress->KorwilAsetTarget;

        if (empty($target)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Target aset tidak ditemukan');
        }

        if ($this->countRelatedTeam($this->shared->user->um_id, $target->id_instansi) < 1) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'User dan Instansi tidak 1 Korwil');
        }

        $korwilAsetProgress->status = KorwilAsetProgress::STATUS_VERIFIED;
        $korwilAsetProgress->sertifikasi_verifikasi = $params['sertifikasi_verifikasi'];
        $korwilAsetProgress->belum_sertifikasi_verifikasi = $params['belum_sertifikasi_verifikasi'];
        $korwilAsetProgress->keterangan_verifikasi = $params['keterangan_verifikasi'];
        $korwilAsetProgress->update_at = $date;
        $korwilAsetProgress->verified_by = $this->shared->user->um_id;

        $simpan = $korwilAsetProgress->save();

        if (!$simpan) {
            $errors = $korwilAsetProgress->getMessage();
            $error_messages = [];

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

            throw new ValidationsException($error_messages);
        }


        if (!empty($params['deleted_attachments'])) {
            foreach ($params['deleted_attachments'] as $uuid) {
                $attachment_record = Attachments::findFirstByUuid($uuid);

                if (!empty($attachment_record)) {
                    $korsupgah_attachment_record = KorwilAsetAttachment::findFirstByIdAttachment($attachment_record->id);

                    if (!empty($korsupgah_attachment_record) && $korsupgah_attachment_record->tipe == KorwilAsetAttachment::TIPE_VERIFIED) {
                        $korsupgah_attachment_record->delete();
                    }

                    AttachmentHelper::delete($attachment_record, true, $this->minio);
                }
            }
        }

        if (!empty($params['attachments'])) {
            foreach ($params['attachments'] as $key => $uuid) {
                $attachment_record = Attachments::findFirstByUuid($uuid);


                if (!empty($attachment_record) && empty($attachment_record->deleted_at)) {
                    $existing_korsupgah_attachments = KorwilAsetAttachment::find([
                        'conditions' => 'id_attachment=:id_attachment: AND id_progress=:id_progress:',
                        'bind' => [
                            'id_attachment' => $attachment_record->id,
                            'id_progress' =>  $korwilAsetProgress->id
                        ]
                    ]);

                    if (count($existing_korsupgah_attachments) < 1) {
                        $korsupgah_attachment = new KorwilAsetAttachment();
                        $korsupgah_attachment->id_attachment = $attachment_record->id;
                        $korsupgah_attachment->id_progress =  $korwilAsetProgress->id;
                        $korsupgah_attachment->tipe = KorwilAsetAttachment::TIPE_VERIFIED;
                        $korsupgah_attachment->created_by = $this->shared->user->um_id;
                        $korsupgah_attachment->save();

                        $attachment_record->status = Attachments::STATUS_REFERRED;
                        $attachment_record->referer = Attachments::REFERER_KORSUPGAH_ANSWER;
                        $attachment_record->save();
                    }
                }
            }
        }

        return new CollectionPaginatedResponse([$korwilAsetProgress]);
    }

    public function myProgressAset($tahun)
    {
        $this->checkOneOfScopes(['korsupgah.answer', 'aset.answer']);

        $current_instansi = $this->shared->user->instansi;

        if (empty($current_instansi)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'User tidak memiliki instansi');
        }

        if (!empty($current_instansi->deleted_at)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Instansi user telah dihapus/tidak aktif');
        }

        $id_instansi = $current_instansi->id;
        $cekAsetTarget = KorwilAsetTarget::findFirst([
            'conditions' => 'id_instansi = :id: AND tahun = :tahun: AND deleted_at is NULL',
            'bind' => [
                'id' => $id_instansi,
                'tahun' => $tahun
            ]
        ]);

        if (empty($cekAsetTarget)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Instansi tidak memiliki aset');
        }

        if (!empty($cekAsetTarget->deleted_at)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Aset instansi terkait sudah terhapus');
        }

        $activeProgress = KorwilAsetProgress::find([
            'conditions' => 'id_aset_target=:id_aset_target: AND deleted_at is NULL',
            'bind' => [
                'id_aset_target' => $cekAsetTarget->id
            ]
        ]);

        $result = [];

        foreach ($activeProgress as $key => $survey) {
            $result[] = $survey->toDetail();
        }
        return new CollectionPaginatedResponse($result);
    }

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

        $cekAsetTarget = KorwilAsetTarget::findByIdInstansi($id);

        if (empty($cekAsetTarget)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Instansi tidak memiliki target');
        }

        if (!empty($cekAsetTarget->deleted_at)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Target instansi sudah terhapus');
        }

        $result = [];

        foreach ($cekAsetTarget as $key => $cat) {
            $cekAsetProgress = KorwilAsetProgress::findFirstByIdAsetTarget($cat->id);

            if (!empty($cekAsetProgress)) {
                //     $cekProgressItem = KorwilPadProgressItem::findFirstByIdProgress($cekAsetProgress->id);
                //     if (!empty($cekProgressItem)) {
                $result[] = $cekAsetProgress->toArray();
                //     }
            }
        }

        return new CollectionPaginatedResponse($result);
    }

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

        $cekAsetTarget = KorwilAsetProgress::findByIdAsetTarget($id);

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

        if (!empty($cekAsetTarget->deleted_at)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Progress sudah terhapus');
        }

        $result = [];

        foreach ($cekAsetTarget as $key => $cat) {
            $result[] = $cat->toDetail();
        }


        return new CollectionPaginatedResponse($result);
    }
}
