<?php

namespace App\Services\Care\Dentistry;

use App\Models\DentalImage;
use App\Models\Organization;
use App\Models\PatientAttachment;
use App\Models\Visit;
use App\Services\Care\AuditLogger;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

class DentalImagingService
{
    /**
     * @param  array{modality: string, tooth_codes?: list<string>, caption?: ?string, bill_fee?: bool}  $meta
     */
    public function upload(
        Organization $organization,
        Visit $visit,
        UploadedFile $file,
        array $meta,
        string $ownerRef,
        ?string $actorRef = null,
    ): DentalImage {
        $visit->loadMissing('patient');
        $modality = (string) ($meta['modality'] ?? '');
        if (! array_key_exists($modality, DentalCatalog::modalities())) {
            throw new \InvalidArgumentException("Invalid imaging modality [{$modality}].");
        }

        $toothCodes = array_values(array_filter(
            $meta['tooth_codes'] ?? [],
            fn ($c) => DentalCatalog::isValidToothCode((string) $c),
        ));

        $path = $file->store("care/patients/{$visit->patient_id}/dental", 'public');

        $attachment = PatientAttachment::create([
            'owner_ref' => $ownerRef,
            'patient_id' => $visit->patient_id,
            'file_path' => $path,
            'original_name' => $file->getClientOriginalName(),
            'mime_type' => $file->getMimeType(),
            'document_type' => 'dental_imaging_'.$modality,
            'uploaded_by' => $actorRef ?? $ownerRef,
        ]);

        $image = DentalImage::create([
            'owner_ref' => $ownerRef,
            'organization_id' => $organization->id,
            'patient_id' => $visit->patient_id,
            'visit_id' => $visit->id,
            'patient_attachment_id' => $attachment->id,
            'modality' => $modality,
            'tooth_codes' => $toothCodes,
            'caption' => $meta['caption'] ?? null,
            'uploaded_by' => $actorRef ?? $ownerRef,
            'captured_at' => now(),
        ]);

        AuditLogger::record(
            $ownerRef,
            'dental.image.uploaded',
            $organization->id,
            $actorRef,
            DentalImage::class,
            $image->id,
        );

        return $image->fresh('attachment');
    }

    public function void(DentalImage $image, string $ownerRef, ?string $actorRef = null): void
    {
        $image->delete();

        AuditLogger::record(
            $ownerRef,
            'dental.image.voided',
            $image->organization_id,
            $actorRef,
            DentalImage::class,
            $image->id,
        );
    }

    public function url(DentalImage $image): ?string
    {
        $path = $image->attachment?->file_path;
        if (! $path) {
            return null;
        }

        return Storage::disk('public')->url($path);
    }
}
