<?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\ProjectTask;

use Espo\Core\Field\LinkMultiple;
use Espo\Core\Field\LinkMultipleItem;
use Espo\Modules\Project\Entities\ProjectTask;
use Espo\ORM\Collection;
use Espo\ORM\EntityManager;
use Espo\ORM\Query\Part\Condition;
use Espo\ORM\Query\Part\Expression;
use Espo\ORM\Query\Part\Join;
use Espo\ORM\Query\Select;
use Espo\ORM\Query\SelectBuilder;

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

    /**
     * @param Collection<ProjectTask> $tasks
     */
    public function load(Collection $tasks, Select $baseQuery): void
    {
        /** @noinspection PhpRedundantOptionalArgumentInspection */
        $subQuery = SelectBuilder::create()
            ->clone($baseQuery)
            ->select(['id'])
            ->limit(null, null)
            ->order([])
            ->build();

        $query = SelectBuilder::create()
            ->from(ProjectTask::RELATIONSHIP_PROJECT_TASK_PROJECT_TASK)
            ->select([
                'fromId',
                'toId',
                'type',
                ['from.name', 'fromName'],
                ['from.status', 'fromStatus'],
            ])
            ->join(
                Join::create(ProjectTask::ENTITY_TYPE, 'from')
                    ->withConditions(
                        Condition::equal(
                            Expression::column('fromId'),
                            Expression::column('from.id'),
                        )
                    )
            )
            ->where(
                Condition::in(Expression::column('toId'), $subQuery)
            )
            ->build();

        $rows = $this->entityManager
            ->getQueryExecutor()
            ->execute($query)
            ->fetchAll();

        /** @var iterable<ProjectTask> $tasks */

        foreach ($tasks as $task) {
            $from = LinkMultiple::create();

            foreach ($rows as $row) {
                if ($row['toId'] === $task->getId()) {
                    $from = $from->withAdded(
                        LinkMultipleItem::create($row['fromId'])
                            ->withName($row['fromName'] ?? '')
                            ->withColumnValue('type', $row['type'])
                            ->withColumnValue('status', $row['fromStatus'])
                    );
                }
            }

            $task->setValueObject('fromTasks', $from);
        }
    }
}
