<?php

class ScopesInstansiTopikController extends BaseController {
    public function index() {
        $this->checkScopes(['bansos.confirm_all']);
        $params = $this->request->get();
        $params['limit'] = $this->getDefaultLimit($params);
        $params['offset'] = array_key_exists('offset', $params) ? $params['offset'] : 0;

        $this->validate(
            $params,
            [
                'limit' => ['validators' => ['required', 'digit']],
                'offset' => ['validators' => ['required', 'digit']],
                'topik_id' => ['validators' => ['digit']],
                'instansi_id' => ['validators' => ['digit']],
                'keluhan_type' => ['validators' => []]
            ]
        );

        $conditions = '1 = 1';
        $bind = [];
        if (!empty($params['topik_id'])) {
            $conditions .= " and topik_id = :topik_id:";
            $bind['topik_id'] = $params['topik_id'];
        }
        if (!empty($params['instansi_id'])) {
            $conditions .= " and instansi_id = :instansi_id";
            $bind['instansi_id'] = $params['instansi_id'];
        }
        if (!empty($params['keluhan_type'])) {
            $topiks = TopikDiskusiBansos::find([
                'type = :type:',
                'bind' => [
                    'type' => $params['keluhan_type']
                ]
            ]);
            $topikIds = array_column($topiks->toArray(), 'id');
            if (!empty($topikIds)) {
                $conditions .= " and topik_id in ({topik_ids:array})";
                $bind['topik_ids'] = $topikIds;
            }
        }

        $rows = ScopesInstansiTopik::find([
            'conditions' => $conditions,
            'bind' => $bind,
            'limit' => $params['limit'],
            'offset' => $params['offset'],
            'order' => 'id asc'
        ]);
        $result = [];
        foreach ($rows as $row) {
            /** @var ScopesInstansiTopik $row */
            array_push($result, $row->toDetail());
        }

        $total = ScopesInstansiTopik::count([
            'conditions' => $conditions,
            'bind' => $bind
        ]);

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

    public function detail($id) {
        $this->checkScopes(['bansos.confirm_all']);
        $result = ScopesInstansiTopik::findFirst($id);
        if (!$result) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Data tidak ditemukan");
        }

        return new SimpleResponse($result->toDetail());
    }

    public function create() {
        $this->checkScopes(['bansos.confirm_all']);
        $payload = $this->validatePayload($this->request->getJsonRawBody(true));

        $result = new ScopesInstansiTopik();
        $result->assign($payload);
        $result->created_at = DateHelper::getNowTimezoned();
        $result->save();

        return new SimpleResponse($result->toDetail());
    }

    public function update($id) {
        $this->checkScopes(['bansos.confirm_all']);
        $payload = $this->validatePayload($this->request->getJsonRawBody(true));

        /** @var  $result ScopesInstansiTopik */
        $result = ScopesInstansiTopik::findFirst($id);
        if (!$result) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Data tidak ditemukan");
        }
        $result->assign($payload);
        $result->updated_at = DateHelper::getNowTimezoned();
        $result->save();

        return new SimpleResponse($result->toDetail());
    }

    public function delete($id) {
        $this->checkScopes(['bansos.confirm_all']);
        /** @var  $result ScopesInstansiTopik */
        $result = ScopesInstansiTopik::findFirst($id);
        if (!$result) {
            throw new CustomErrorException(BaseResponse::DATA_NOT_FOUND, "Data tidak ditemukan");
        }
        $result->deleted_at = DateHelper::getNowTimezoned();
        $result->save();

        return new SimpleResponse($result->toDetail());
    }

    private function validatePayload($payload) {
        $result = $this->validate(
            $payload,
            [
                'scopes_name' => ['validators' => ['required']],
                'instansi_id' => ['validators' => ['required', 'digit']],
                'topik_id' => ['validators' => ['required', 'digit']],
            ]
        );

        $scopes = Scopes::findFirst(['name = :name:', 'bind' => ['name' => $payload['scopes_name']]]);
        if (!$scopes) {
            throw new ValidationException([
                "field" => "scopes_name",
                "message" => "Scopes tidak ditemukan"
            ]);
        }

        $instansi = Instansi::findFirst($payload['instansi_id']);
        if (!$instansi) {
            throw new ValidationException([
                "field" => "instansi_id",
                "message" => "Instansi tidak ditemukan"
            ]);
        }

        $topik = TopikDiskusiBansos::findFirst($payload['topik_id']);
        if (!$topik) {
            throw new ValidationException([
                "field" => "topik_id",
                "message" => "Topik tidak ditemukan"
            ]);
        }

        return $result;
    }
}
