<?php

declare(strict_types=1);

namespace ImovelZapAi\Conversations\Application\Services;

final class LeadScoreCalculator
{
    /**
     * @param  array<string, mixed>  $qualification
     * @return array{
     *     urgency_score: int,
     *     interest_score: int,
     *     properties_viewed: int,
     *     requested_visit: bool,
     *     wait_minutes: int,
     *     total_score: int,
     *     factors: array<string, mixed>
     * }
     */
    public function calculate(
        array $qualification,
        int $propertiesViewed,
        bool $requestedVisit,
        int $waitMinutes = 0,
    ): array {
        $urgency = $this->urgencyScore($qualification['move_timeline'] ?? null);
        $interest = $this->interestScore($qualification, $propertiesViewed);
        $visitBoost = $requestedVisit ? 25 : 0;
        $viewedBoost = min($propertiesViewed * 5, 20);
        $waitBoost = min((int) floor($waitMinutes / 5), 15);

        $total = $urgency + $interest + $visitBoost + $viewedBoost + $waitBoost;

        return [
            'urgency_score' => $urgency,
            'interest_score' => $interest,
            'properties_viewed' => $propertiesViewed,
            'requested_visit' => $requestedVisit,
            'wait_minutes' => $waitMinutes,
            'total_score' => $total,
            'factors' => [
                'visit_boost' => $visitBoost,
                'viewed_boost' => $viewedBoost,
                'wait_boost' => $waitBoost,
            ],
        ];
    }

    private function urgencyScore(?string $timeline): int
    {
        if ($timeline === null || $timeline === '') {
            return 10;
        }

        $normalized = mb_strtolower($timeline);

        if (preg_match('/\b(já|ja|urgent|imediato|essa semana|hoje|amanhã|amanha)\b/u', $normalized)) {
            return 40;
        }

        if (preg_match('/\b(m[eê]s|30 dias|15 dias)\b/u', $normalized)) {
            return 30;
        }

        if (preg_match('/\b(\d+)\s*m(?:es|eses)\b/u', $normalized, $matches) && (int) $matches[1] <= 3) {
            return 25;
        }

        return 15;
    }

    /**
     * @param  array<string, mixed>  $qualification
     */
    private function interestScore(array $qualification, int $propertiesViewed): int
    {
        $score = 20;

        foreach (['intent', 'will_finance', 'move_timeline', 'visited_similar'] as $field) {
            if (! empty($qualification[$field])) {
                $score += 5;
            }
        }

        return min($score + min($propertiesViewed * 3, 15), 50);
    }
}
