<?php declare(strict_types = 1);

namespace idoit\Module\SyneticsFlows\Automation\Action\PerformExecution;

use idoit\Module\SyneticsFlows\Automation\Action\ActionType\CmdbChange\CategoryChange;
use idoit\Module\SyneticsFlows\Automation\Action\ActionType\CmdbChange\CmdbChange;
use idoit\Module\SyneticsFlows\Model\CategoryDao;
use isys_cmdb_dao_category;
use isys_cmdb_dao_category_g_custom_fields;
use isys_component_database;
use Throwable;

abstract class AbstractCategoryChanges
{
    public function __construct(private ?CategoryDao $categoryDao, private isys_component_database $database)
    {
    }

    public function getCategoryDao(): ?CategoryDao
    {
        return $this->categoryDao;
    }

    public function getDatabase(): isys_component_database
    {
        return $this->database;
    }

    /**
     * @param CategoryChange $change
     *
     * @return isys_cmdb_dao_category|null
     */
    public function getDaoOfCategory(CategoryChange $change): ?isys_cmdb_dao_category
    {
        try {
            $categoryId = $change->getCategoryId();
            $categoryInfo = $this->getCategoryDao()
                ->get($categoryId);

            if (!defined($categoryId) || !$categoryInfo) {
                return null;
            }

            $categoryClass = $categoryInfo->getClassName();

            if (!class_exists($categoryClass)) {
                return null;
            }

            $dao = new $categoryClass($this->database);
            if (!$dao instanceof isys_cmdb_dao_category) {
                return null;
            }

            if ($dao instanceof isys_cmdb_dao_category_g_custom_fields) {
                $dao->set_catg_custom_id(constant($categoryId));
            }

            return $dao;
        } catch (Throwable $e) {
            return null;
        }
    }

    /**
     * @param CmdbChange[] $changes
     *
     * @return array
     */
    protected function preparePropertiesData(array $changes): array
    {
        $result = [];

        foreach ($changes as $change) {
            $property = $change->getAttribute();
            if (!is_string($property)) {
                continue;
            }
            $parts = explode('.', $property);
            $attribute = $parts[1] ?? null;
            if (!is_string($attribute)) {
                continue;
            }
            $result[$attribute] = [
                C__DATA__VALUE => $change->getValue(),
            ];
        }

        return $result;
    }
}
