<?php declare(strict_types = 1);

namespace idoit\Module\Cmdb\Component\AttributeDataCollector\CollectorTypes;

use idoit\Component\Property\Property;
use idoit\Module\Cmdb\Component\AttributeDataCollector\Formatter\BrowserObjectFormatter;
use idoit\Module\Cmdb\Controller\Browse;
use isys_application;
use isys_cmdb_dao;
use isys_exception_database;
use isys_popup_browser_object_ng;

class BrowserObject extends AbstractCollector
{
    /**
     * @param Property $property
     *
     * @return bool
     */
    public function isApplicable(Property $property): bool
    {
        $ignoreObjectBrowserWithCallback = [
            'cable_connection'
        ];
    
        $callback = $property->getFormat()->getCallback();
        $callbackFunc = !empty($callback) ? $callback[1] : '';
        $params = $property->getUi()->getParams();
    
        return $property->getInfo()->getType() === Property::C__PROPERTY__INFO__TYPE__OBJECT_BROWSER &&
            $params['p_strPopupType'] === 'browser_object_ng' &&
            !!$params[isys_popup_browser_object_ng::C__SECOND_SELECTION] === false &&
            !in_array($callbackFunc, $ignoreObjectBrowserWithCallback);
    }

    /**
     * @param Property $property
     * @param bool     $reformat
     *
     * @return array
     * @throws isys_exception_database
     */
    protected function fetchData(Property $property, bool $reformat): array
    {
        $params = $property->getUi()->getParams();
        $categoryFilter = $params[isys_popup_browser_object_ng::C__CAT_FILTER];
        $objectTypeBlacklist = $params[isys_popup_browser_object_ng::C__TYPE_BLACK_LIST];
        $objectTypeFilter = $params[isys_popup_browser_object_ng::C__TYPE_FILTER];

        return $this->getDataForObjectBrowser($property->getUi()->getId(), $reformat, $categoryFilter, $objectTypeFilter, $objectTypeBlacklist);
    }

    /**
     * @param string|null $categoryFilter
     * @param string|null $objectTypeFilter
     * @param string|null $objectTypeBlacklist
     *
     * @return array
     * @throws isys_exception_database
     */
    private function getOnlyObjectData(
        ?string $categoryFilter = null,
        ?string $objectTypeFilter = null,
        ?string $objectTypeBlacklist = null
    ) {
        if ($objectTypeFilter !== null) {
            $objectTypeFilter = array_filter(array_map(function ($item) {
                return defined_or_default($item);
            }, explode(';', $objectTypeFilter)));
        }
        
        $dao = isys_cmdb_dao::instance(isys_application::instance()->container->get('database'));
        $result = $dao->search_objects(
            '',
            $objectTypeFilter,
            null,
            '',
            false,
            false,
            'isys_obj__title ASC',
            false,
            C__RECORD_STATUS__NORMAL,
            $objectTypeBlacklist,
            $categoryFilter
        );
        $data = [];
        while ($row = $result->get_row()) {
            $data[] = [
                'id' => $row['isys_obj__id'],
                'title' => $row['isys_obj__title'],
                'sysid' => $row['isys_obj__sysid'],
                'type-title' => isys_application::instance()->container->get('language')
                    ->get($row['isys_obj_type__title']),
                'type-id' => $row['isys_obj_type__id']
            ];
        }
        
        return $data;
    }
    
    /**
     * Experiment to retrieve data with Browse controller
     *
     * @param string $uiId
     * @param bool $reformat
     * @param string|null $categoryFilter
     * @param string|null $objectTypeFilter
     * @param string|null $objectTypeBlacklist
     *
     * @return mixed
     * @throws isys_exception_database
     */
    private function getDataForObjectBrowser(
        string $uiId,
        bool $reformat = false,
        ?string $categoryFilter = null,
        ?string $objectTypeFilter = null,
        ?string $objectTypeBlacklist = null
    ) {
        $globalCategories = $specificCategories = [];
        
        if ($categoryFilter !== null) {
            $categoryFilter = explode(';', $categoryFilter);
            
            $globalCategories = array_filter($categoryFilter, function ($categoryConstant) {
                return strpos($categoryConstant, '_CATG_') !== false;
            });
            $specificCategories = array_filter($categoryFilter, function ($categoryConstant) {
                return strpos($categoryConstant, '_CATS_') !== false;
            });
        }
        
        $browser = new Browse(new \isys_module_cmdb());
    
        $register = new \isys_register();
        $register->set('POST', [
            'objects' => [],
            'output' => 'objects',
            'key' => $uiId,
            'filter' => \isys_format_json::encode([
                Browse::BROWSE_FILTER_GLOBAL_CATEGORY => $globalCategories,
                Browse::BROWSE_FILTER_OBJECT_TYPE => $objectTypeFilter,
                Browse::BROWSE_FILTER_OBJECT_TYPE_EXCLUDE => $objectTypeBlacklist,
                Browse::BROWSE_FILTER_SPECIFIC_CATEGORY => $specificCategories,
            ])
        ]);
    
        $browser->objectType($register);
        $response = $browser->getResponse();

        return $reformat ? BrowserObjectFormatter::reformat($response['data']): $response['data'];
    }
}
