<?php

namespace App\Services;

use App\Models\Mr;
use App\Models\Visit;

class ReasonEngine
{
    /**
     * Rule-based reasons for deviation with evidence.
     * Avoid blaming when confidence is low or border ambiguous.
     */
    public function explainDeviation(int $mrId, string $from, string $to, array $context): array
    {
        $reasons = [];
        $total = $context['total_visits'] ?? 0;
        $outside = $context['outside'] ?? 0;
        $borderAmbiguous = $context['border_ambiguous'] ?? 0;
        $geoUnknown = $context['geo_unknown'] ?? 0;
        /** @var \Illuminate\Support\Collection $visits */
        $visits = $context['visits'] ?? collect();

        if ($total === 0) {
            return [['code' => 'no_visits', 'label' => 'No visits in period', 'evidence' => [], 'score' => 0]];
        }

        if ($outside > 0) {
            $outsideVisits = $visits->where('assignment_status', 'outside');
            $evidence = $outsideVisits->take(5)->map(fn ($v) => [
                'visit_id' => $v->id,
                'date' => $v->visit_date?->format('Y-m-d'),
                'doctor' => $v->mappedDoctor?->name,
                'area_resolved' => $v->areaResolved?->name ?? $v->areaResolved?->code,
            ])->toArray();
            $reasons[] = [
                'code' => 'outside_visits',
                'label' => 'Visits outside assigned territory',
                'evidence' => $evidence,
                'count' => $outside,
                'score' => min(40, $outside * 10),
            ];
        }

        if ($borderAmbiguous > 0) {
            $reasons[] = [
                'code' => 'border_ambiguous',
                'label' => 'Visits near territory border (ambiguous)',
                'evidence' => [],
                'count' => $borderAmbiguous,
                'score' => min(15, $borderAmbiguous * 5),
            ];
        }

        if ($geoUnknown > 0) {
            $reasons[] = [
                'code' => 'data_quality',
                'label' => 'Visits with unknown location (no GPS or doctor coords)',
                'evidence' => [],
                'count' => $geoUnknown,
                'score' => 0,
            ];
        }

        $lowConfidence = $visits->where('confidence_score', '<', 70)->count();
        if ($lowConfidence > 0 && count($reasons) > 0) {
            $reasons[] = [
                'code' => 'low_confidence_mapping',
                'label' => 'Some visits have low mapping confidence; interpret with caution',
                'evidence' => [],
                'count' => $lowConfidence,
                'score' => 0,
            ];
        }

        return $reasons;
    }
}
