<?php

namespace App\Services\Care;

use App\Models\Assessment;
use App\Models\AssessmentTemplate;
use App\Models\CareUnit;
use App\Models\Visit;
use App\Models\VisitVital;
use Illuminate\Support\Collection;

class NursingAssessmentService
{
    /** @var list<string> */
    public const NURSING_PACK_CODES = ['news2', 'braden', 'morse', 'pain_nrs'];

    /**
     * @return Collection<int, AssessmentTemplate>
     */
    public function nursingTemplates(): Collection
    {
        return AssessmentTemplate::query()
            ->whereNull('organization_id')
            ->where('is_current', true)
            ->where('is_active', true)
            ->whereIn('code', self::NURSING_PACK_CODES)
            ->orderBy('name')
            ->get();
    }

    /**
     * Board rows for placed patients: latest nursing assessments + latest vitals.
     *
     * @return list<array<string, mixed>>
     */
    public function unitBoard(CareUnit $unit, string $ownerRef): array
    {
        $templates = $this->nursingTemplates();
        $visits = Visit::owned($ownerRef)
            ->where('care_unit_id', $unit->id)
            ->whereIn('status', [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS])
            ->with(['patient', 'bed'])
            ->orderBy('placed_at')
            ->get();

        $rows = [];
        foreach ($visits as $visit) {
            $latestByCode = Assessment::owned($ownerRef)
                ->where('visit_id', $visit->id)
                ->whereIn('status', [Assessment::STATUS_DRAFT, Assessment::STATUS_COMPLETED])
                ->whereHas('template', fn ($q) => $q->whereIn('code', $templates->pluck('code')->all()))
                ->with(['template', 'score'])
                ->orderByDesc('id')
                ->get()
                ->unique(fn (Assessment $a) => $a->template?->code)
                ->keyBy(fn (Assessment $a) => $a->template?->code);

            $latestVitals = VisitVital::owned($ownerRef)
                ->where('visit_id', $visit->id)
                ->orderByDesc('recorded_at')
                ->first();

            $rows[] = [
                'visit' => $visit,
                'patient' => $visit->patient,
                'bed' => $visit->bed,
                'assessments' => $latestByCode,
                'vitals' => $latestVitals,
            ];
        }

        return $rows;
    }

    public function recordVisitVitals(
        Visit $visit,
        string $ownerRef,
        ?string $actorRef,
        array $data,
    ): VisitVital {
        $vital = VisitVital::create([
            'owner_ref' => $ownerRef,
            'organization_id' => $visit->organization_id,
            'visit_id' => $visit->id,
            'patient_id' => $visit->patient_id,
            'care_unit_id' => $visit->care_unit_id,
            'bp_systolic' => $data['bp_systolic'] ?? null,
            'bp_diastolic' => $data['bp_diastolic'] ?? null,
            'pulse' => $data['pulse'] ?? null,
            'temperature' => $data['temperature'] ?? null,
            'spo2' => $data['spo2'] ?? null,
            'respiratory_rate' => $data['respiratory_rate'] ?? null,
            'notes' => $data['notes'] ?? null,
            'recorded_by' => $actorRef,
            'recorded_at' => now(),
        ]);

        AuditLogger::record(
            $ownerRef,
            'visit_vitals.recorded',
            $visit->organization_id,
            $actorRef,
            VisitVital::class,
            $vital->id,
        );

        return $vital;
    }
}
