<?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\Hooks\ProjectBoard;

use Espo\Core\Hook\Hook\AfterSave;
use Espo\Core\ORM\Repository\Option\SaveOption;
use Espo\Core\Utils\Language;
use Espo\Modules\Project\Entities\ProjectBoard;
use Espo\Modules\Project\Entities\ProjectColumn;
use Espo\Modules\Project\Entities\ProjectTask;
use Espo\ORM\Entity;
use Espo\ORM\EntityManager;
use Espo\ORM\Repository\Option\SaveOptions;

/**
 * @implements AfterSave<ProjectBoard>
 */
class CreateColumns implements AfterSave
{
    /** @var array{string, string}[] */
    private array $pairs = [
        ['To Do', ProjectTask::STATUS_NOT_STARTED],
        ['In Progress', ProjectTask::STATUS_STARTED],
        ['Review', ProjectTask::STATUS_STARTED],
        ['Done', ProjectTask::STATUS_COMPLETED],
    ];

    public function __construct(
        private EntityManager $entityManager,
        private Language $defaultLanguage,
    ) {}

    public function afterSave(Entity $entity, SaveOptions $options): void
    {
        if (
            !$entity->isNew() ||
            !$options->get(SaveOption::API) && !$options->get('createColumns')
        ) {
            return;
        }

        if ($options->get(SaveOption::DUPLICATE_SOURCE_ID)) {
            $this->processDuplicate($entity, $options->get(SaveOption::DUPLICATE_SOURCE_ID));

            return;
        }

        foreach ($this->pairs as $i => $pair) {
            $column = $this->entityManager->getRDBRepositoryByClass(ProjectColumn::class)->getNew();

            $name = $this->defaultLanguage->translateOption($pair[0], 'name', ProjectColumn::ENTITY_TYPE);

            $column
                ->setName($name)
                ->setMappedStatus($pair[1])
                ->setBoardId($entity->getId())
                ->setOrder($i);

            $this->entityManager->saveEntity($column);
        }
    }

    private function processDuplicate(ProjectBoard $entity, string $sourceId): void
    {
        $source = $this->entityManager->getRDBRepositoryByClass(ProjectBoard::class)->getById($sourceId);

        if (!$source) {
            return;
        }

        /** @var iterable<ProjectColumn> $sourceColumns */
        $sourceColumns = $this->entityManager
            ->getRelation($source, 'columns')
            ->order('order')
            ->find();

        foreach ($sourceColumns as $i => $sourceColumn) {
            $column = $this->entityManager->getRDBRepositoryByClass(ProjectColumn::class)->getNew();

            $column
                ->setName($sourceColumn->getName())
                ->setMappedStatus($sourceColumn->getMappedStatus())
                ->setOrder($i)
                ->setBoardId($entity->getId());

            $this->entityManager->saveEntity($column);
        }
    }
}
