<?php declare(strict_types = 1);

namespace idoit\Module\SyneticsFlows\Model;

use idoit\Model\Dao\Base;
use idoit\Module\SyneticsFlows\Controller\SearchParams;
use idoit\Module\SyneticsFlows\Model\Dto\ObjectType;
use isys_application;
use isys_auth;
use isys_auth_cmdb_object_types;

class ObjectTypeDao extends Base
{
    public const SORTING_MAP = [
        'id' => 'id',
        'title' => 'title',
    ];

    /**
     * @param string|null $condition
     * @param SearchParams|null $params
     *
     * @return ObjectType[]
     *
     * @throws \isys_exception_database
     */
    public function getData(?string $condition = null, ?SearchParams $params = null): array
    {
        $recordStatusNormal = $this->convert_sql_int(C__RECORD_STATUS__NORMAL);
        $routeGenerator = isys_application::instance()->container->get('route_generator');
        $language = isys_application::instance()->container->get('language');
        $rightsCondition = " AND FALSE ";

        $allowedObjectTypes = isys_auth_cmdb_object_types::instance()->get_allowed_objecttypes(isys_auth::VIEW);

        if (is_array($allowedObjectTypes)) {
            if (!empty($allowedObjectTypes)) {
                $allowedObjectTypes = array_map(fn ($item) => $this->convert_sql_id($item), $allowedObjectTypes);
                $rightsCondition = " AND isys_obj_type__id IN (" . implode(',', $allowedObjectTypes) . ") ";
            }
        }

        $query = "SELECT
            isys_obj_type__id AS id,
            isys_obj_type__title AS title,
            isys_obj_type__const AS constant,
            isys_obj_type__color AS color
          FROM isys_obj_type
          INNER JOIN isys_obj_type_group ON isys_obj_type_group__id = isys_obj_type.isys_obj_type__isys_obj_type_group__id
          WHERE isys_obj_type__status = {$recordStatusNormal}
          AND isys_obj_type_group__status = {$recordStatusNormal}
          AND isys_obj_type__show_in_tree = 1 {$rightsCondition} ";

        if ($condition) {
            $query .= $condition;
        }

        $result = $this->retrieve($query . ';');
        $data = [];
        while ($row = $result->get_row()) {
            $typeId = $row['id'];
            $row['title'] = $language->get($row['title']);
            $row['icon'] = $routeGenerator->generate('cmdb.object-type.icon', ['objectTypeId' => (int)$typeId]);
            $data[] = $row;
        }

        if ($params) {
            $sortId = $params->getSort()?->getId() ?? null;
            if ($sortId && isset(self::SORTING_MAP[$sortId])) {
                $direction = $params->getSort()?->isDesc() ? SORT_DESC : SORT_ASC;
                isys_glob_sort_array_by_column($data, $sortId, $direction);
            }
            $data = array_slice($data, $params->getOffset(), $params->getPerPage());
        }
        return array_map(
            fn (array $entry) => new ObjectType($entry['id'], $entry['title'], $entry['icon'], $entry['constant'], $entry['color']),
            $data
        );
    }

    /**
     * @param string $id
     *
     * @return ObjectType|null
     * @throws \isys_exception_database
     */
    public function get(string $id): ?ObjectType
    {
        return $this->getData(' AND isys_obj_type__id = ' . $this->convert_sql_int($id))[0] ?? null;
    }

    /**
     * @param $condition
     *
     * @return int
     * @throws \isys_exception_database
     */
    public function getCount($condition = null): int
    {
        $data = $this->getData($condition);
        return count($data);
    }
}
