<?php

class LitbangKajianPengajuanDiskusiController extends BaseController {
    public function list($pengajuanId) {
        $this->checkScopes(['litbang.access']);
        $params = $this->request->get();
        $params['limit'] = $this->getDefaultLimit($params);
        $params['offset'] = array_key_exists('offset', $params) ? $params['offset'] : 0;
        $params['order_by'] = array_key_exists('order_by', $params) ? strtolower($params['order_by']) : 'id';
        $params['order_direction'] = array_key_exists('order_direction', $params) ? strtolower($params['order_direction']) : 'desc';

        $allowed_order = [
            'id',
            'kajian_pengajuan_id',
            'created_at',
        ];
        $bind_order = [
            'id' => 'LitbangKajianPengajuanDiskusi.id',
            'kajian_pengajuan_id' => 'LitbangKajianPengajuanDiskusi.kajian_pengajuan_id',
            'created_at' => 'LitbangKajianPengajuanDiskusi.created_at',
        ];
        $allowed_order_direction = ['asc', 'desc'];

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

        if ($this->hasOneOfRoles(['anggota_litbang', 'kasatgas_litbang'])) {
            /** @var $litbangUser LitbangUser */
            $litbangUser = LitbangUser::findOrFail("um_id = " . $this->userID);

            /** @var $kajianPengajuan LitbangKajianPengajuan */
            $kajianPengajuan = LitbangKajianPengajuan::findOrFail("id = " . $pengajuanId);

            if ($litbangUser->satgas_id != $kajianPengajuan->satgas_id) {
                throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "User tidak berhak melakukan aksi ini");
            }
        }

        $query = LitbangKajianPengajuanDiskusi::query()
            ->columns("
                LitbangKajianPengajuanDiskusi.id,
                UmUser.um_id,
                UmUser.um_user_name,
                LitbangKajianPengajuanDiskusi.pesan,
                LitbangKajianPengajuanDiskusi.created_at,
                Attachments.id as attachment_id,
                Attachments.uuid as attachment_uuid,
                Attachments.filename as attachment_filename
            ")
            ->leftJoin('UmUser', 'LitbangKajianPengajuanDiskusi.created_by = UmUser.um_id')
            ->leftJoin('Attachments', 'LitbangKajianPengajuanDiskusi.attachment_id = Attachments.id')
            ->where(
                "LitbangKajianPengajuanDiskusi.kajian_pengajuan_id = :kajian_pengajuan_id:
            ")
            ->bind([
                "kajian_pengajuan_id" => $pengajuanId
            ])
            ->orderBy($bind_order[$params['order_by']] . " " . $params['order_direction']);

        $result = $query
            ->limit($params['limit'], $params['offset'])
            ->execute()
            ->toArray();
        $total = $query->execute()->count();

        return new PaginatedResponse($result, $total, $params['limit'], $params['offset']);
    }

    public function create() {
        $this->checkScopes(['litbang.access']);
        $rawParams = $this->request->getPost();
        $params = [];

        $this->db->begin();
        try {
            if ($this->request->hasFiles()) {
                $attachments = LitbangService::uploadDocument(
                    $this->shared,
                    $this->minio,
                    $this->request,
                    LitbangKajianPengajuanDiskusi::DOCUMENT_DIR,
                    $this->config["allowed_mime_types"]
                );

                $params['attachment_id'] = $attachments[0]->id;
            }

            $validations = [
                "kajian_pengajuan_id" => ['validators' => ['required', 'digit']]
            ];
            if (array_key_exists('attachment_id', $params)) {
                $validations = array_merge($validations, [
                    "pesan" => ['validators' => [
                        [
                            'name' => 'max_string',
                            'params' => 255
                        ]
                    ]]
                ]);
            } else {
                $validations = array_merge($validations, [
                    "pesan" => ['validators' => [
                        [
                            'name' => 'max_string',
                            'params' => 255
                        ],
                        [
                            'name' => 'min_string',
                            'params' => 1
                        ]
                    ]]
                ]);
            }
            $params = array_merge($params, $this->validate(
                $rawParams,
                $validations
            ));

            /** @var $pengajuan LitbangKajianPengajuan */
            $pengajuan = LitbangKajianPengajuan::findFirst("id = " . $params['kajian_pengajuan_id']);
            if (!$pengajuan) {
                throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Kajian Pengajuan tidak ditemukan");
            }

            $satgas_id = null;
            if ($this->hasOneOfRoles(['anggota_litbang', 'kasatgas_litbang'])) {
                /** @var $litbangUser LitbangUser */
                $litbangUser = LitbangUser::findOrFail("um_id = " . $this->userID);

                $satgas_id = $litbangUser->satgas_id;

                if ($litbangUser->satgas_id != $pengajuan->satgas_id) {
                    throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "User tidak berhak melakukan aksi ini");
                }
            }

            $model = new LitbangKajianPengajuanDiskusi();
            $model->satgas_id = $satgas_id;
            $model->kajian_pengajuan_id = $pengajuan->id;
            $model->created_by = $this->userID;
            $model->pesan = $params['pesan'];
            if (array_key_exists('attachment_id', $params)) {
                $model->attachment_id = $params['attachment_id'];
            }
            if (!$model->save()) {
                $errors = $model->getMessages();
                $error_messages = [];

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

                throw new ValidationException($error_messages);
            }

            $query = LitbangKajianPengajuanDiskusi::query()
                ->columns("
                LitbangKajianPengajuanDiskusi.id,
                UmUser.um_id,
                UmUser.um_user_name,
                LitbangKajianPengajuanDiskusi.pesan,
                LitbangKajianPengajuanDiskusi.created_at,
                Attachments.id as attachment_id,
                Attachments.uuid as attachment_uuid,
                Attachments.filename as attachment_filename
            ")
                ->leftJoin('UmUser', 'LitbangKajianPengajuanDiskusi.created_by = UmUser.um_id')
                ->leftJoin('Attachments', 'LitbangKajianPengajuanDiskusi.attachment_id = Attachments.id')
                ->where(
                    "LitbangKajianPengajuanDiskusi.id = :id:
            ")
                ->bind([
                    "id" => $model->id
                ]);

            $models = $query
                ->execute()
                ->toArray();
            $response = $models[0];

            $this->db->commit();
            return new SimpleResponse($response);
        } catch(\ValidationException $e) {
            $this->db->rollback();
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Diskusi tidak valid! Pesan tanpa lampiran minimal memiliki panjang 1 karakter dan maksimal 255 karakter", [$e->getMessages()]);
        } catch(\Exception $e) {
            $this->db->rollback();
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Proses pengiriman diskusi gagal", [$e->getMessage()]);
        }
    }

    public function download($uuid) {
        $this->checkScopes(['litbang.access']);
        return LitbangService::downloadAttachment(
            $this->shared,
            $this->minio,
            LitbangKajianPengajuanDiskusi::DOCUMENT_DIR,
            $uuid
        );
    }
}
