<?php

class KorwilPadProgressController extends BaseController
{
    public function list()
    {
        $this->checkScopes(['admin.view']);

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

        $getParams['id_instansi'] = array_key_exists('id_instansi', $getParams) ? $getParams['id_instansi'] : 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_instansi' => ['validators' => ['digit']],
                'limit' => ['validators' => ['digit']],
                'offset' => ['validators' => ['digit']],
                'keyword' => ['validators' => []]
            ]
        );

        if ($params['id_instansi']) {
            $padTarget = KorwilPadTarget::findFirstByIdInstansi($params['id_instansi']);
            if (empty($padTarget)) {
                throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Instansi tidak ditemukan');
            }

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

            $id = $padTarget->id;

            $progressList = KorwilPadProgress::find([
                'conditions' => 'id_pad_target = :id_pad_target:',
                'bind' => [
                    'id_pad_target' => $id
                ],
                'limit' => $params['limit'],
                'offset' => $params['offset']
            ]);

            $total_progress = KorwilPadProgress::count();
        } else {
            $progressList = KorwilPadProgress::find();

            $total_progress = KorwilPadProgress::count();
        }


        return new PaginatedResponse($progressList, $total_progress, $params['limit'], $params['offset']);
    }

    public function my($tahun)
    {
        $this->checkOneOfScopes(['korsupgah.answer', 'pad.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;
        $cekPadTarget = KorwilPadTarget::findFirst([
            'conditions' => 'id_instansi = :id: AND tahun = :tahun: AND deleted_at is NULL',
            'bind' => [
                'id' => $id_instansi,
                'tahun' => $tahun
            ]
        ]);

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

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

        $activeProgress = KorwilPadProgress::find([
            'conditions' => 'id_pad_target=:id_pad_target: AND deleted_at is NULL',
            'bind' => [
                'id_pad_target' => $cekPadTarget->id
            ]
            // 'order' => 'bulan ASC'
            // 'sort' => [
            //     'bulan' => 1
            // ]
        ]);

        $result = [];

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

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

        $cekPadProgress = KorwilPadProgress::findByIdPadTarget($id);

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

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

        $result = [];

        foreach ($cekPadProgress as $key => $cpp) {
            $result[] = $cpp->toArray();
        }


        return new CollectionPaginatedResponse($result);
    }

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

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

        $params = $this->validate(
            $postParams,
            [
                'bulan' => ['validators' => ['required', 'digit']],
                'id_pad_target' => ['validators' => ['required', 'digit']],
                'keterangan' => ['validators' => []],
                'items' => ['validators' => []],
                'attachments' => ['validators' => []],
                'deleted_attachments' => ['validators' => []]
            ]
        );


        $cekPadTarget = KorwilPadTarget::findFirstById($params['id_pad_target']);

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

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


        if (!is_array($params['items'])) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'item tidak valid');
        }

        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');

        $cekPadProgress = KorwilPadProgress::findFirst([
            'conditions' => 'bulan = :bulan: AND id_pad_target =:ipt:',
            'bind' => [
                'bulan' => $params['bulan'],
                'ipt' => $cekPadTarget->id
            ]
        ]);

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

        if (empty($cekPadProgress) || $cekPadProgress->id_pad_target != $cekPadTarget->id) {
            $progress = new KorwilPadProgress();
            $progress->bulan = $params['bulan'];
            $progress->id_pad_target = $params['id_pad_target'];
            $progress->keterangan = $params['keterangan'];
            $progress->created_at = $date;
            $progress->status = KorwilPadProgress::STATUS_INIT;
            $progress->submitted_by = $this->shared->user->um_id;
            $status = $progress->save();

            $cekPadProgress = $progress;
        } else {
            $cekPadProgress->bulan = $params['bulan'];
            $cekPadProgress->id_pad_target = $params['id_pad_target'];
            $cekPadProgress->keterangan = $params['keterangan'];
            $cekPadProgress->created_at = $date;
            $cekPadProgress->status = KorwilPadProgress::STATUS_INIT;
            $cekPadProgress->submitted_by = $this->shared->user->um_id;
            $status = $cekPadProgress->save();
        }

        if (!$status) {
            $errors = $progress->getMessage();
            $error_messages = [];

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

            throw new ValidationsException($error_messages);
        }

        foreach ($params['items'] as $key => $item) {
            $id_pad_kategori = $item['id_pad_kategori'];
            $nilai = $item['nilai'];

            $cekPadKategori = KorwilPadKategori::findFirstById($id_pad_kategori);
            if (empty($cekPadKategori)) {
                throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Kategori PAD tidak ditemukan');
            }

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

            $cekProgressItem = KorwilPadProgressItem::findFirst([
                'conditions' => 'id_pad_kategori = :id_pad_kategori: AND id_progress = :id_pad_progress:',
                'bind' => [
                    'id_pad_kategori' => $id_pad_kategori,
                    'id_pad_progress' => $cekPadProgress->id
                ]
            ]);

            if (empty($cekProgressItem)) {
                $cekProgressItem = new KorwilPadProgressItem();
                $cekProgressItem->id_progress = $cekPadProgress->id;
                $cekProgressItem->id_pad_kategori = $id_pad_kategori;
                $cekProgressItem->nilai = $nilai;
                $status = $cekProgressItem->save();

                if (!$status) {
                    $errors = $cekProgressItem->getMessage();
                    $error_messages = [];

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

                    throw new ValidationsException($error_messages);
                }
            } else {
                $cekProgressItem->nilai = $nilai;
                $status = $cekProgressItem->save();

                if (!$status) {
                    $errors = $cekProgressItem->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)) {
                    $korwil_attachment_record = KorwilPadProgressAttachment::findFirstByIdAttachment($attachment_record->id);

                    if (!empty($korwil_attachment_record) && $korwil_attachment_record->tipe == KorwilPadProgressAttachment::TIPE_JAWABAN) {
                        $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 = KorwilPadProgressAttachment::find([
                        'conditions' => 'id_attachment=:id_attachment: AND id_progress=:id_progress:',
                        'bind' => [
                            'id_attachment' => $attachment_record->id,
                            'id_progress' => $cekPadProgress->id
                        ]
                    ]);

                    if (count($existing_korwil_attachments) < 1) {
                        $korsupgah_attachment = new KorwilPadProgressAttachment();
                        $korsupgah_attachment->id_attachment = $attachment_record->id;
                        $korsupgah_attachment->id_progress = $cekPadProgress->id;
                        $korsupgah_attachment->tipe = KorwilPadProgressAttachment::TIPE_JAWABAN;
                        $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([$cekPadProgress]);
    }

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

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

        $params = $this->validate(
            $postParams,
            [
                'items' => ['validators' => []],
                'keterangan_verifikasi' => ['validators' => []],
                'attachments' => ['validators' => []],
                'deleted_attachments' => ['validators' => []]
            ]
        );

        $cekExistingProgressItem = KorwilPadProgressItem::findFirstByIdProgress($id);

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

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

        $cekProgress = KorwilPadProgress::findFirstById($id);

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

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

        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 (!is_array($params['items'])) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'item tidak valid');
        }

        $target = $cekProgress->KorwilPadTarget;

        if (empty($target)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Target PAD 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');
        }

        $date = date('Y-m-d H:i:s');
        $cekProgress->keterangan_verifikasi = $params['keterangan_verifikasi'];
        $cekProgress->updated_at = $date;
        $cekProgress->status = KorwilPadProgress::STATUS_VERIFIED;
        $cekProgress->verified_by = $this->shared->user->um_id;
        $status = $cekProgress->save();

        if (!$status) {
            $errors = $cekProgress->getMessage();
            $error_messages = [];

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

            throw new ValidationsException($error_messages);
        }

        $cekProgressItem = KorwilPadProgressItem::find([
            'conditions' => 'id_progress =:id_progress: AND deleted_at is NULL',
            'bind' => [
                'id_progress' => $id
            ]
        ]);

        if (!empty($cekProgressItem)) {
            foreach ($params['items'] as $requestItem) {
                foreach ($cekProgressItem as $key => $existingItem) {
                    if ($requestItem['id_pad_kategori'] == $existingItem->id_pad_kategori) {
                        $existingItem->nilai_verivikasi = $requestItem['nilai_verifikasi'];
                        $status = $existingItem->save();
                        break;
                    }
                }
            }
        }


        if (!$status) {
            $errors = $cekProgressItem->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)) {
                    $korwil_attachment_record = KorwilPadProgressAttachment::findFirstByIdAttachment($attachment_record->id);

                    if (!empty($korwil_attachment_record) && $korwil_attachment_record->tipe == KorwilPadProgressAttachment::TIPE_VERIFIKASI) {
                        $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 = KorwilPadProgressAttachment::find([
                        'conditions' => 'id_attachment=:id_attachment: AND id_progress=:id_progress:',
                        'bind' => [
                            'id_attachment' => $attachment_record->id,
                            'id_progress' => $cekProgress->id
                        ]
                    ]);

                    if (count($existing_korwil_attachments) < 1) {
                        $korsupgah_attachment = new KorwilPadProgressAttachment();
                        $korsupgah_attachment->id_attachment = $attachment_record->id;
                        $korsupgah_attachment->id_progress = $cekProgress->id;
                        $korsupgah_attachment->tipe = KorwilPadProgressAttachment::TIPE_VERIFIKASI;
                        $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([$cekProgress]);
    }

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

        $cekPadTarget = KorwilPadTarget::findByIdInstansi($id);

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

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

        $result = [];

        foreach ($cekPadTarget as $key => $cpt) {
            $cekPadProgress = KorwilPadProgress::findFirstByIdPadTarget($cpt->id);

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

        return new CollectionPaginatedResponse($result);
    }

    public function downloadAttachment($uuid)
    {
        $attachment = KorwilPadProgressAttachment::findFirst(
            [
                "uuid = :uuid: AND deleted_at is NULL",
                "bind" => [
                    "uuid" => $uuid
                ]
            ]
        );

        if (!empty($attachment)) {
            // if ($attachment->tipe == Attachments::TIPE_PRIVATE) {
            //     $this->checkIsAuthenticated();
            //     $this->checkScopes(['korsupgah.answer']) || $this->checkScopes(['korsupgah.verify']);
            // }

            // $filename = AttachmentHelper::getLocalPath($attachment);

            $attachment_folder = getenv("PRIVATE_FOLDER") . DIRECTORY_SEPARATOR . 'diskusi_attachment' . DIRECTORY_SEPARATOR . 'progress_pad' . DIRECTORY_SEPARATOR . $this->user->shared->instansi->nama;
            $filename = $attachment_folder . DIRECTORY_SEPARATOR . $uuid;

            if (!file_exists($filename)) {
                throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "File Not Found");
            }

            return MediaHelper::fileResponse($filename, $attachment->filename);
        } else {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "File Not Found or Not active");
        }
    }
}
