<?php
/***********************************************************************************
 * The contents of this file are subject to the Extension License Agreement
 * ("Agreement") which can be viewed at
 * https://www.espocrm.com/extension-license-agreement/.
 * By copying, installing downloading, or using this file, You have unconditionally
 * agreed to the terms and conditions of the Agreement, and You may not use this
 * file except in compliance with the Agreement. Under the terms of the Agreement,
 * You shall not license, sublicense, sell, resell, rent, lease, lend, distribute,
 * redistribute, market, publish, commercialize, or otherwise transfer rights or
 * usage to the software or any modified version or derivative work of the software
 * created by or for you.
 *
 * Copyright (C) 2024-2025 Letrium Ltd.
 *
 * License ID: f27e70ce6801a13265271f5669c8bc5c
 ************************************************************************************/

namespace Espo\Modules\Project\Tools\Project;

use Espo\Core\ORM\Repository\Option\SaveOption;
use Espo\Modules\Project\Entities\Project;
use Espo\Modules\Project\Entities\ProjectGroup;
use Espo\ORM\EntityManager;
use Traversable;

class GroupReorderService
{
    public function __construct(
        private EntityManager $entityManager,
    ) {}

    /**
     * @param string[] $ids
     */
    public function reorder(Project $project, array $ids): void
    {
        $groups = $this->getGroups($project);

        usort($groups, function (ProjectGroup $a, ProjectGroup $b) use ($ids) {
            $aIndex = array_search($a->getId(), $ids);
            $bIndex = array_search($b->getId(), $ids);

            if (!is_int($aIndex) || !is_int($bIndex)) {
                return 0;
            }

            return $aIndex - $bIndex;
        });

        $this->entityManager->getTransactionManager()->start();

        foreach ($groups as $i => $group) {
            $group->setOrder($i);

            $this->entityManager->saveEntity($group, [SaveOption::SILENT => true]);
        }

        $this->entityManager->getTransactionManager()->commit();
    }

    /**
     * @return ProjectGroup[]
     */
    private function getGroups(Project $project): array
    {
        /** @var Traversable<ProjectGroup> $groups */
        $groups = $this->entityManager
            ->getRDBRepositoryByClass(ProjectGroup::class)
            ->where(['projectId' => $project->getId()])
            ->order('order')
            ->find();

        return iterator_to_array($groups);
    }
}
