<?php

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

        $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'] : '';

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

        $survey_template_list = StranasSurveyTemplate::find([
            'conditions' => 'nama ilike :keyword: OR keterangan ilike :keyword:',
            'bind' => [
                'keyword' => '%' . $params['keyword'] . '%'
            ],
            'limit' => $params['limit'],
            'offset' => $params['offset'],
        ]);

        $total_record = StranasSurveyTemplate::count();

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

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

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

        $params = $this->validate(
            $rawBody,
            [
                'nama' => ['validators' => ['required']],
                'keterangan' => ['validators' => []]
            ]
        );

        $survey_template = new StranasSurveyTemplate();
        $survey_template->nama = $params['nama'];
        $survey_template->keterangan = $params['keterangan'];
        $survey_template->created_by = $this->shared->user->um_id;
        $status = $survey_template->save();

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

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

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

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

        $survey_template = StranasSurveyTemplate::findFirst($id);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey Template tidak ditemukan');
        }

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

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

        $params = $this->validate(
            $rawBody,
            [
                'nama' => ['validators' => ['required']],
                'keterangan' => ['validators' => []]
            ]
        );

        $survey_template->nama = $params['nama'];
        $survey_template->keterangan = $params['keterangan'];
        $survey_template->updated_at = date('Y-m-d H:i:s');
        $survey_template->updated_by = $this->shared->user->um_id;
        $status = $survey_template->save();

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

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

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

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

        $survey_template = StranasSurveyTemplate::findFirst($id);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey Template tidak ditemukan');
        }

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

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

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

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

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

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

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

        $params = $this->validate(
            $rawBody,
            [
                'id' => ['validators' => ['required']],
                'id_target' => ['validators' => ['required']]
            ]
        );

        $survey_template = StranasSurveyTemplate::findFirst($params['id']);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey Template tidak ditemukan');
        }

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

        $target = StranasTarget::findFirst($params['id_target']);

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

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

        $records = StranasSurveyTemplateQuestion::find([
            'conditions' => 'id_survey_template=:id_survey_template: AND id_target=:id_target:',
            'bind' => [
                'id_survey_template' => $params['id'],
                'id_target' => $params['id_target']
            ]
        ]);

        if (count($records) > 0) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Target dengan ID " . $params['id'] . " sudah aktif dan terdaftar di Survey template ini");
        }

        $survey_template_question = new StranasSurveyTemplateQuestion();
        $survey_template_question->id_survey_template = $params['id'];
        $survey_template_question->id_target = $params['id_target'];
        $survey_template_question->created_by = $this->shared->user->um_id;
        $status = $survey_template_question->save();

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

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

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

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

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

        $params = $this->validate(
            $rawBody,
            [
                'id' => ['validators' => ['required']],
                'id_target_list' => ['validators' => ['required']]
            ]
        );

        if (!is_array($params['id_target_list'])) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Format ID Target List tidak valid');
        }
        $id_target_list = array_unique(array_values($params['id_target_list']));

        $survey_template = StranasSurveyTemplate::findFirst($params['id']);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey Template tidak ditemukan');
        }

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

        $target_list = StranasTarget::find([
            'conditions' => 'id in ({ids:array}) AND deleted_at is NULL',
            'bind' => [
                'ids' => array_values($id_target_list)
            ]
        ]);

        // Check Expected target List exists in master data

        $target_master_data_ids = [];

        foreach ($target_list as $key => $target) {
            $target_master_data_ids[] = $target->id;
        }

        $not_exist_ids = array_diff($id_target_list, $target_master_data_ids);

        if (!empty($not_exist_ids)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Target dengan ID ' . implode(",", $not_exist_ids) . ' tidak aktif/terdaftar');
        }

        $registered_questions = StranasSurveyTemplateQuestion::find([
            'conditions' => 'id_survey_template=:id_survey_template: AND deleted_at is NULL',
            'bind' => [
                'id_survey_template' => $params['id']
            ]
        ]);

        $registered_question_ids = [];

        foreach ($registered_questions as $key => $registered_question) {
            $registered_question_ids[] = $registered_question->id_target;
        }

        // Otherwise, Register new question to this survey template
        foreach ($target_master_data_ids as $key => $target_id) {
            if (!in_array($target_id, $registered_question_ids)) {
                $survey_template_question = new StranasSurveyTemplateQuestion();
                $survey_template_question->id_survey_template = $params['id'];
                $survey_template_question->id_target = $target_id;
                $survey_template_question->created_by = $this->shared->user->um_id;
                $status = $survey_template_question->save();
            }
        }

        return new CollectionPaginatedResponse([]);
    }

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

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

        $params = $this->validate(
            $rawBody,
            [
                'id' => ['validators' => ['required']],
                'id_target' => ['validators' => ['required']]
            ]
        );

        $survey_template = StranasSurveyTemplate::findFirst($params['id']);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey Template tidak ditemukan');
        }

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

        $target = StranasTarget::findFirst($params['id_target']);

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

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

        $records = StranasSurveyTemplateQuestion::find([
            'conditions' => 'id_survey_template=:id_survey_template: AND id_target=:id_target:',
            'bind' => [
                'id_survey_template' => $params['id'],
                'id_target' => $params['id_target']
            ]
        ]);

        if (count($records) < 1) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Pertanyaan dengan Target ID " . $params['id'] . " tidak terdaftar di Survey template ini");
        }

        $survey_template_question = $records[0];
        $status = $survey_template_question->delete();

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

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

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

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

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

        $params = $this->validate(
            $rawBody,
            [
                'id' => ['validators' => ['required']],
                'id_target_list' => ['validators' => ['required']]
            ]
        );

        if (!is_array($params['id_target_list'])) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Format ID Target List tidak valid');
        }
        $id_target_list = array_unique(array_values($params['id_target_list']));

        $survey_template = StranasSurveyTemplate::findFirst($params['id']);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey Template tidak ditemukan');
        }

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

        $target_list = StranasTarget::find([
            'conditions' => 'id in ({ids:array}) AND deleted_at is NULL',
            'bind' => [
                'ids' => array_values($id_target_list)
            ]
        ]);

        // Check Expected target List exists in master data

        $target_master_data_ids = [];

        foreach ($target_list as $key => $target) {
            $target_master_data_ids[] = $target->id;
        }

        $not_exist_ids = array_diff($id_target_list, $target_master_data_ids);

        if (!empty($not_exist_ids)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Target dengan ID ' . implode(",", $not_exist_ids) . ' tidak aktif/terdaftar');
        }

        $registered_questions = StranasSurveyTemplateQuestion::find([
            'conditions' => 'id_survey_template=:id_survey_template: AND deleted_at is NULL',
            'bind' => [
                'id_survey_template' => $params['id']
            ]
        ]);

        $registered_question_ids = [];

        // Delete all registered question that doesn't exist in params
        foreach ($registered_questions as $key => $registered_question) {
            $registered_question_ids[] = $registered_question->id_target;
            if (!in_array($registered_question->id_target, $target_master_data_ids)) {
                $status = $registered_question->delete();
            }
        }

        // Otherwise, Register new question to this survey template
        foreach ($target_master_data_ids as $key => $target_id) {
            if (!in_array($target_id, $registered_question_ids)) {
                $survey_template_question = new StranasSurveyTemplateQuestion();
                $survey_template_question->id_survey_template = $params['id'];
                $survey_template_question->id_target = $target_id;
                $survey_template_question->created_by = $this->shared->user->um_id;
                $status = $survey_template_question->save();
            }
        }

        return new CollectionPaginatedResponse([]);
    }

    public function detail($id)
    {
        $this->checkIsAuthenticated();

        $survey_template = StranasSurveyTemplate::findFirst($id);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey Template tidak ditemukan');
        }

        $detail = $survey_template->getDetail();

        return new CollectionPaginatedResponse([$detail]);
    }

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

        $survey_template = StranasSurveyTemplate::findFirst($id);

        if (empty($survey_template)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey template tidak ditemukan');
        }

        if (empty($survey_template->deleted_at)) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, 'Survey template sudah aktif');
        }

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

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

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

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