<?php

namespace App\Services\Calculation;

class CalculationStep
{
    protected string $name;
    protected string $outputKey;
    protected \Closure $formula;
    protected RoundingRule $roundingRule;
    protected ?int $overrideValue = null;
    protected bool $isOverridden = false;
    protected array $dependencies = [];

    public function __construct(
        string $name,
        string $outputKey,
        \Closure $formula,
        RoundingRule $roundingRule = RoundingRule::UNIT,
        array $dependencies = []
    ) {
        $this->name = $name;
        $this->outputKey = $outputKey;
        $this->formula = $formula;
        $this->roundingRule = $roundingRule;
        $this->dependencies = $dependencies;
    }

    public function name(): string
    {
        return $this->name;
    }

    public function outputKey(): string
    {
        return $this->outputKey;
    }

    public function dependencies(): array
    {
        return $this->dependencies;
    }

    public function override(int $value): static
    {
        $this->overrideValue = $value;
        $this->isOverridden = true;
        return $this;
    }

    public function isOverridden(): bool
    {
        return $this->isOverridden;
    }

    public function execute(array $data): array
    {
        if ($this->isOverridden) {
            return [
                'name' => $this->name,
                'output_key' => $this->outputKey,
                'formula_raw' => null,
                'calculated_value' => null,
                'rounded_value' => $this->overrideValue,
                'is_overridden' => true,
                'dependencies' => $this->dependencies,
            ];
        }

        $rawValue = call_user_func($this->formula, $data);
        $roundedValue = $this->roundingRule->apply($rawValue);

        return [
            'name' => $this->name,
            'output_key' => $this->outputKey,
            'formula_raw' => $rawValue,
            'calculated_value' => $rawValue,
            'rounded_value' => $roundedValue,
            'is_overridden' => false,
            'dependencies' => $this->dependencies,
        ];
    }
}
