<?php

class MasterGlosariumController extends BaseController {
    public function view() {
        $request = $this->request->get();
        $validatedRequest = $this->validate($request, [
            'abbr_start' => [
                'validators' => [
                   [
                       'name' => 'max_string',
                       'params' => 1
                   ]
                ]
            ],
            'kategori' => ['validators' => []],
            'subkategori' => ['validators' => []],
            'limit' => ['validators' => ['required', 'digit']],
            'offset' => ['validators' => ['required', 'digit']]
        ]);
        $validatedRequest['limit'] = $this->getDefaultLimit($validatedRequest);
        $params = [
            'limit' => $validatedRequest['limit'],
            'offset' => $validatedRequest['offset'],
            'order' => 'lower(abbr)',
            'bind' => []
        ];
        $conditions = [];
        if (!empty($validatedRequest['abbr_start'])) {
            array_push($conditions, 'abbr ILIKE :abbr_start:');
            $params['bind']['abbr_start'] = $validatedRequest['abbr_start'].'%';
        }
        if (!empty($validatedRequest['kategori'])) {
            array_push($conditions, 'kategori ILIKE :kategori:');
            $params['bind']['kategori'] = $validatedRequest['kategori'];
        }
        if (!empty($validatedRequest['subkategori'])) {
            array_push($conditions, 'subkategori ILIKE :subkategori:');
            $params['bind']['subkategori'] = $validatedRequest['subkategori'];
        }
        if (!empty($conditions)) {
            $params['conditions'] = join(" and ", $conditions);
        }

        $rows = MasterGlosarium::find($params);
        unset($params['limit']);
        unset($params['offset']);
        unset($params['order']);
        $total = MasterGlosarium::count($params);

        return new PaginatedResponse($rows->toArray(), $total, $validatedRequest['limit'], $validatedRequest['offset']);
    }

    public function list() {
        $this->checkScopes(['admin.view']);
        $request = $this->request->get();
        $request['limit'] = $this->getDefaultLimit($request);
        $request['offset'] = array_key_exists('offset', $request) ? $request['offset'] : 0;
        $request['order'] = array_key_exists('order', $request) ? $request['order'] : 'abbr';
        $request['direction'] = array_key_exists('direction', $request) ? $request['direction'] : 'asc';

        $allowedOrder = ['abbr', 'kategori', 'subkategori'];
        $allowedDirection = ['asc', 'desc'];

        $params = $this->validate($request, [
            'limit' => ['validators' => ['required', 'digit']],
            'offset' => ['validators' => ['required', 'digit']],
            'kategori' => ['validators' => []],
            'subkategori' => ['validators' => []],
            'keyword' => ['validators' => []],
            'order' => ['validators' => [
                [
                    'name' => 'inclusion_in',
                    'params' => $allowedOrder
                ]
            ]],
            'direction' => ['validators' => [
                [
                    'name' => 'inclusion_in',
                    'params' => $allowedDirection
                ]
            ]],
        ]);

        $conditions = [];
        $bind = [];
        if (!empty($params['kategori'])) {
            array_push($conditions, "kategori = :kategori:");
            $bind["kategori"] = $params['kategori'];
        }
        if (!empty($params['subkategori'])) {
            array_push($conditions, "subkategori = :subkategori:");
            $bind['subkategori'] = $params['subkategori'];
        }
        if (!empty($params['keyword'])) {
            array_push($conditions, "(abbr ILIKE :keyword: OR deskripsi ILIKE :keyword:)");
            $bind['keyword'] = "%" . $params['keyword'] . "%";
        }

        $result = MasterGlosarium::find([
            "conditions" => join(" AND ", $conditions),
            "bind" => $bind,
            "limit" => $params['limit'],
            "offset" => $params['offset'],
            "order" => "lower (" . $params['order'] . ") " . $params['direction']
        ]);
        $total = MasterGlosarium::count([
            "conditions" => join(" AND ", $conditions),
            "bind" => $bind
        ]);

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

    public function detail($id) {
        $this->checkScopes(['admin.view']);
        $row = MasterGlosarium::findByIdOrFail($id);
        return new SimpleResponse($row);
    }

    public function create() {
        $this->checkScopes(['admin.view']);
        $request = $this->request->getJsonRawBody(true);
        $params = $this->validate($request, [
            'kategori' => ['validators' => ['required', ['name' => 'max_string', 'params' => 100]]],
            'subkategori' => ['validators' => ['required', ['name' => 'max_string', 'params' => 100]]],
            'abbr' => ['validators' => ['required', ['name' => 'max_string', 'params' => 50]]],
            'deskripsi' => ['validators' => ['required', ['name' => 'max_string', 'params' => 255]]]
        ]);
        $row = new MasterGlosarium();
        $row->kategori = $params['kategori'];
        $row->subkategori = $params['subkategori'];
        $row->abbr = $params['abbr'];
        $row->deskripsi = $params['deskripsi'];
        if (!$row->save()) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Data gagal disimpan");
        }

        return new SimpleResponse($row);
    }

    public function update($id) {
        $this->checkScopes(['admin.view']);
        $request = $this->request->getJsonRawBody(true);
        $params = $this->validate($request, [
            'kategori' => ['validators' => ['required', ['name' => 'max_string', 'params' => 100]]],
            'subkategori' => ['validators' => ['required', ['name' => 'max_string', 'params' => 100]]],
            'abbr' => ['validators' => ['required', ['name' => 'max_string', 'params' => 50]]],
            'deskripsi' => ['validators' => ['required', ['name' => 'max_string', 'params' => 255]]]
        ]);
        $row = MasterGlosarium::findByIdOrFail($id);
        $row->kategori = $params['kategori'];
        $row->subkategori = $params['subkategori'];
        $row->abbr = $params['abbr'];
        $row->deskripsi = $params['deskripsi'];
        if (!$row->save()) {
            throw new CustomErrorException(BaseResponse::INVALID_REQUEST, "Data gagal disimpan");
        }

        return new SimpleResponse($row);
    }

    public function delete($id) {
        $this->checkScopes(['admin.view']);
        $row = MasterGlosarium::findByIdOrFail($id);
        $row->delete();

        return new SimpleResponse($row->id);
    }

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

        $request = $this->request->get();
        $params = $this->validate($request, [
            'keyword' => ['validators' => []]
        ]);
        $conditions = [];
        $bind = [];

        if (!empty($params['keyword'])) {
            array_push($conditions, "kategori ILIKE :keyword:");
            $bind["keyword"] = "%" . $params['keyword'] . "%";
        }

        $rows = MasterGlosarium::find([
            "columns" => "distinct (kategori) as kategori",
            "conditions" => join(" and ", $conditions),
            "bind" => $bind,
            "group" => "kategori",
            "order" => "kategori asc"
        ]);

        return new CollectionPaginatedResponse($rows);
    }

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

        $request = $this->request->get();
        $params = $this->validate($request, [
            'kategori' => ['validators' => ['required']],
            'keyword' => ['validators' => []],
        ]);
        $conditions = [
            "kategori ILIKE :kategori:"
        ];
        $bind = [
            "kategori" => $params["kategori"]
        ];

        if (!empty($params['keyword'])) {
            array_push($conditions, "subkategori ILIKE :keyword:");
            $bind["keyword"] = "%" . $params['keyword'] . "%";
        }

        $rows = MasterGlosarium::find([
            "columns" => "distinct (subkategori) as subkategori",
            "conditions" => join(" and ", $conditions),
            "bind" => $bind,
            "group" => "subkategori",
            "order" => "subkategori asc"
        ]);

        return new CollectionPaginatedResponse($rows);
    }
}
