<?php

namespace idoit\Module\SyneticsFlows\Controller;

use idoit\Module\SyneticsFlows\Auth;
use idoit\Module\SyneticsFlows\Controller\Response\ArrayResponse;
use idoit\Module\SyneticsFlows\Controller\Response\NotFoundResponse;
use idoit\Module\SyneticsFlows\Filter\CategoryFilter;
use idoit\Module\SyneticsFlows\Model\CategoryDao;
use idoit\Module\SyneticsFlows\Model\Dto\ObjectType;
use idoit\Module\SyneticsFlows\Model\ObjectTypeDao;
use idoit\Module\SyneticsFlows\Serialization\Serializer;
use isys_auth;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class CategoryController
{
    /**
     * @var CategoryDao|null
     */
    private ?CategoryDao $categoryDao = null;
    private ?ObjectTypeDao $objectTypeDao = null;

    /**
     * @return CategoryDao
     * @throws \Exception
     */
    public function getDao(): CategoryDao
    {
        if (!$this->categoryDao) {
            $this->categoryDao = \isys_application::instance()->container->get('idoit.flows.category.dao');
        }
        return $this->categoryDao;
    }

    /**
     * @return ObjectTypeDao
     * @throws \Exception
     */
    public function getObjectTypeDao(): ObjectTypeDao
    {
        if (!$this->objectTypeDao) {
            $this->objectTypeDao = \isys_application::instance()->container->get('idoit.flows.object-type.dao');
        }
        return $this->objectTypeDao;
    }

    /**
     * @param Request $request
     *
     * @return Response
     * @throws \Exception
     */
    public function find(Request $request): Response
    {
        if (!Auth::instance()->manageFlows(isys_auth::VIEW)) {
            return JSONResponseFactory::accessDenied();
        }

        $search = SearchParams::fromParams($request->get('params'));
        $params = json_decode($request->get('params'), true);
        $filter = Serializer::fromJson(CategoryFilter::class, $params['filter'] ?? []);
        if ($filter instanceof CategoryFilter) {
            $objectTypeIds = $filter->getObjectTypeIds();

            if (!empty($objectTypeIds) && empty($filter->getObjectTypes())) {
                $condition = "AND isys_obj_type__id IN ('" . implode("','", $objectTypeIds) . "')";
                $types = array_map(fn (ObjectType $objectType) => $objectType->getConstant(), $this->getObjectTypeDao()->getData($condition));
                $filter->setObjectTypes($types);
            }
        }
        return new ArrayResponse(
            $this->getDao()->getData($filter, $search),
            $this->getDao()->getCount($filter),
        );
    }

    /**
     * @param string $id
     *
     * @return Response
     * @throws \Exception
     */
    public function get(string $id): Response
    {
        if (!Auth::instance()->manageFlows(isys_auth::VIEW)) {
            return JSONResponseFactory::accessDenied();
        }

        $result = $this->getDao()->get($id);
        if ($result === null) {
            return new NotFoundResponse('Category');
        }
        return new JsonResponse($result);
    }
}
