<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Workflow\Bpmn;

use PpPhp\Core\Platform\Workflow\Engine\WorkflowEngineDefinition;
use PpPhp\Core\Platform\Workflow\Engine\WorkflowGateway;

final class BpmnWorkflowCompiler
{
    public function compile(BpmnModel $model): WorkflowEngineDefinition
    {
        $activities = [];
        $gateways = [];

        foreach ($model->elements() as $element) {
            $type = (string) ($element['type'] ?? '');
            $id = (string) ($element['elementId'] ?? '');
            if ($id === '') {
                continue;
            }

            if (in_array($type, ['exclusiveGateway', 'parallelGateway', 'inclusiveGateway'], true)) {
                $branches = [];
                foreach ($model->flows() as $flow) {
                    if ((string) ($flow['sourceRef'] ?? '') === $id) {
                        $branches[] = (string) ($flow['targetRef'] ?? '');
                    }
                }

                $gatewayType = match ($type) {
                    'parallelGateway' => WorkflowGateway::PARALLEL,
                    'inclusiveGateway' => WorkflowGateway::INCLUSIVE,
                    default => WorkflowGateway::EXCLUSIVE,
                };

                $gateways[] = new WorkflowGateway($id, $gatewayType, $branches, '', date('c'))->toArray();
                continue;
            }

            $activities[] = [
                'activityId' => $id,
                'name' => (string) ($element['name'] ?? $id),
                'type' => $type,
            ];
        }

        $transitions = [];
        foreach ($model->flows() as $flow) {
            $transitions[] = [
                'from' => (string) ($flow['sourceRef'] ?? ''),
                'to' => (string) ($flow['targetRef'] ?? ''),
            ];
        }

        return WorkflowEngineDefinition::create(
            $model->processId(),
            $model->name(),
            $activities,
            $gateways,
            $transitions,
            $model->startElementId()
        );
    }
}
