<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\Service;

use MauticPlugin\DealFlowBundle\Entity\DealAuditEventRepository;
use MauticPlugin\DealFlowBundle\Entity\DealRepository;
use MauticPlugin\DealFlowBundle\Entity\Pipeline;

class PipelineVelocityCalculator
{
    private const WINDOWS = [7, 14, 30];

    public function __construct(
        private readonly DealAuditEventRepository $auditRepository,
        private readonly DealRepository $dealRepository,
    ) {
    }

    /**
     * @return array<int, array{fwd: int, won: int, lost: int, fwdPct: string, wonPct: string, lostPct: string}>
     */
    public function calculate(Pipeline $pipeline): array
    {
        $result = [];

        foreach (self::WINDOWS as $days) {
            $since = new \DateTimeImmutable(sprintf('-%d days', $days));

            // Stage moves from audit events (bucketed by target stage type)
            $auditCounts = $this->auditRepository->countVelocityByStageType($pipeline, $since);

            // Won/lost from current stage type (covers cases where audit wasn't recorded)
            $statusCounts = $this->dealRepository->countByStageTypeSince($pipeline, $since);

            $fwd = $auditCounts['open'] ?? 0;
            // Use whichever is higher: audit events or actual deal status counts
            $won = max($auditCounts['won'] ?? 0, $statusCounts['won'] ?? 0);
            $lost = max($auditCounts['lost'] ?? 0, $statusCounts['lost'] ?? 0);
            $total = $fwd + $won + $lost;

            $result[$days] = [
                'fwd' => $fwd,
                'won' => $won,
                'lost' => $lost,
                'fwdPct' => $total > 0 ? round($fwd / $total * 100).'%' : '0%',
                'wonPct' => $total > 0 ? round($won / $total * 100).'%' : '0%',
                'lostPct' => $total > 0 ? round($lost / $total * 100).'%' : '0%',
            ];
        }

        return $result;
    }
}
