<?php

namespace App\Services\Care;

use App\Models\CareUnit;
use App\Models\NursingNote;
use App\Models\Visit;
use App\Models\WardHandover;
use Illuminate\Support\Collection;

class NursingDocumentationService
{
    public function addNote(
        Visit $visit,
        string $ownerRef,
        ?string $actorRef,
        string $body,
        string $noteType = 'progress',
        ?string $shiftCode = null,
        ?int $careUnitId = null,
    ): NursingNote {
        $note = NursingNote::create([
            'owner_ref' => $ownerRef,
            'organization_id' => $visit->organization_id,
            'visit_id' => $visit->id,
            'patient_id' => $visit->patient_id,
            'care_unit_id' => $careUnitId ?? $visit->care_unit_id,
            'note_type' => $noteType,
            'shift_code' => $shiftCode,
            'body' => $body,
            'recorded_by' => $actorRef,
            'recorded_at' => now(),
        ]);

        AuditLogger::record(
            $ownerRef,
            'nursing_note.created',
            $visit->organization_id,
            $actorRef,
            NursingNote::class,
            $note->id,
        );

        return $note;
    }

    /**
     * @return Collection<int, NursingNote>
     */
    public function notesForUnit(CareUnit $unit, string $ownerRef, int $limit = 50): Collection
    {
        return NursingNote::owned($ownerRef)
            ->where('care_unit_id', $unit->id)
            ->with(['patient', 'visit'])
            ->orderByDesc('recorded_at')
            ->limit($limit)
            ->get();
    }

    /**
     * @return Collection<int, NursingNote>
     */
    public function notesForVisit(Visit $visit, string $ownerRef, int $limit = 50): Collection
    {
        return NursingNote::owned($ownerRef)
            ->where('visit_id', $visit->id)
            ->orderByDesc('recorded_at')
            ->limit($limit)
            ->get();
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function createHandover(
        CareUnit $unit,
        string $ownerRef,
        ?string $actorRef,
        array $data,
        bool $complete = false,
    ): WardHandover {
        $handover = WardHandover::create([
            'owner_ref' => $ownerRef,
            'organization_id' => $unit->organization_id,
            'care_unit_id' => $unit->id,
            'from_shift' => $data['from_shift'] ?? null,
            'to_shift' => $data['to_shift'] ?? null,
            'handed_over_at' => $complete ? now() : ($data['handed_over_at'] ?? null),
            'handed_over_by' => $actorRef,
            'received_by' => $data['received_by'] ?? null,
            'situation' => $data['situation'] ?? null,
            'background' => $data['background'] ?? null,
            'assessment' => $data['assessment'] ?? null,
            'recommendation' => $data['recommendation'] ?? null,
            'patient_summaries' => $data['patient_summaries'] ?? $this->defaultPatientSummaries($unit, $ownerRef),
            'status' => $complete ? WardHandover::STATUS_COMPLETED : WardHandover::STATUS_DRAFT,
        ]);

        AuditLogger::record(
            $ownerRef,
            $complete ? 'ward_handover.completed' : 'ward_handover.created',
            $unit->organization_id,
            $actorRef,
            WardHandover::class,
            $handover->id,
        );

        return $handover;
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function completeHandover(
        WardHandover $handover,
        string $ownerRef,
        ?string $actorRef,
        array $data = [],
    ): WardHandover {
        $handover->update([
            'from_shift' => $data['from_shift'] ?? $handover->from_shift,
            'to_shift' => $data['to_shift'] ?? $handover->to_shift,
            'received_by' => $data['received_by'] ?? $handover->received_by,
            'situation' => $data['situation'] ?? $handover->situation,
            'background' => $data['background'] ?? $handover->background,
            'assessment' => $data['assessment'] ?? $handover->assessment,
            'recommendation' => $data['recommendation'] ?? $handover->recommendation,
            'patient_summaries' => $data['patient_summaries'] ?? $handover->patient_summaries,
            'handed_over_at' => now(),
            'handed_over_by' => $actorRef ?? $handover->handed_over_by,
            'status' => WardHandover::STATUS_COMPLETED,
        ]);

        AuditLogger::record(
            $ownerRef,
            'ward_handover.completed',
            $handover->organization_id,
            $actorRef,
            WardHandover::class,
            $handover->id,
        );

        return $handover->fresh();
    }

    /**
     * @return list<array{visit_id: int, patient_name: string, bed: ?string, note: string}>
     */
    public function defaultPatientSummaries(CareUnit $unit, string $ownerRef): array
    {
        $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();

        return $visits->map(fn (Visit $visit) => [
            'visit_id' => $visit->id,
            'patient_name' => $visit->patient?->fullName() ?? 'Unknown',
            'bed' => $visit->bed?->label,
            'note' => '',
        ])->all();
    }
}
