<?php

namespace Modules\ClinicCore\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Storage;
use Modules\ClinicCore\Entities\ClcPatient;
use Modules\ClinicCore\Entities\ClcClinicalPhoto;

/**
 * Before/after clinical photography for a patient. Shared across all clinic
 * specialties. Images live on the public disk under
 * clinic_photos/{business}/{patient}.
 */
class ClcClinicalPhotoController extends Controller
{
    private function biz()
    {
        return request()->session()->get('user.business_id');
    }

    private function guardPatient($patientId): ClcPatient
    {
        if (!auth()->user()->can('clinic.manage_pets')) {
            abort(403, 'Unauthorized action.');
        }
        return ClcPatient::where('business_id', $this->biz())->findOrFail($patientId);
    }

    /** JSON list of a patient's photos, newest first. */
    public function index($patientId)
    {
        $patient = $this->guardPatient($patientId);

        $photos = ClcClinicalPhoto::where('clc_patient_id', $patient->id)
            ->orderByDesc('taken_at')->orderByDesc('id')
            ->get(['id', 'phase', 'body_area', 'caption', 'taken_at', 'file_path', 'appointment_id']);

        return response()->json([
            'success' => true,
            'phases'  => ClcClinicalPhoto::phases(),
            'photos'  => $photos->map(fn ($p) => [
                'id'        => $p->id,
                'phase'     => $p->phase,
                'body_area' => $p->body_area,
                'caption'   => $p->caption,
                'taken_at'  => optional($p->taken_at)->format('Y-m-d'),
                'url'       => $p->url,
            ]),
        ]);
    }

    /** Upload one or more photos for a patient. */
    public function store(Request $request, $patientId)
    {
        $patient = $this->guardPatient($patientId);

        $request->validate([
            'photos'    => 'required',
            'photos.*'  => 'image|mimes:jpeg,jpg,png,webp,heic|max:12288', // 12 MB each
            'phase'     => 'nullable|in:baseline,before,after,progress,other',
            'body_area' => 'nullable|string|max:80',
            'caption'   => 'nullable|string|max:255',
            'taken_at'  => 'nullable|date',
        ]);

        $files = $request->file('photos');
        if (!is_array($files)) {
            $files = [$files];
        }

        $businessId = $this->biz();
        $saved = 0;
        foreach ($files as $file) {
            if (!$file || !$file->isValid()) continue;
            $path = $file->store("clinic_photos/{$businessId}/{$patient->id}", 'public');
            ClcClinicalPhoto::create([
                'business_id'    => $businessId,
                'clc_patient_id' => $patient->id,
                'appointment_id' => $request->appointment_id ?: null,
                'specialty_id'   => $patient->specialty_id ?? null,
                'phase'          => $request->phase ?: 'progress',
                'body_area'      => $request->body_area ?: null,
                'caption'        => $request->caption ?: null,
                'taken_at'       => $request->taken_at ?: now()->toDateString(),
                'file_path'      => $path,
                'file_name'      => $file->getClientOriginalName(),
                'file_size'      => $file->getSize(),
                'mime_type'      => $file->getClientMimeType(),
                'user_id'        => auth()->id(),
            ]);
            $saved++;
        }

        return response()->json(['success' => true, 'saved' => $saved, 'msg' => $saved . ' photo(s) uploaded.']);
    }

    /** Edit a photo's metadata (phase / body area / caption / date). */
    public function update(Request $request, $photoId)
    {
        if (!auth()->user()->can('clinic.manage_pets')) abort(403);

        $photo = ClcClinicalPhoto::where('business_id', $this->biz())->findOrFail($photoId);
        $request->validate([
            'phase'     => 'nullable|in:baseline,before,after,progress,other',
            'body_area' => 'nullable|string|max:80',
            'caption'   => 'nullable|string|max:255',
            'taken_at'  => 'nullable|date',
        ]);
        $photo->update($request->only(['phase', 'body_area', 'caption', 'taken_at']));

        return response()->json(['success' => true, 'msg' => 'Photo updated.']);
    }

    /** Delete a photo (file + row). */
    public function destroy($photoId)
    {
        if (!auth()->user()->can('clinic.manage_pets')) abort(403);

        $photo = ClcClinicalPhoto::where('business_id', $this->biz())->findOrFail($photoId);
        try {
            if ($photo->file_path) Storage::disk('public')->delete($photo->file_path);
        } catch (\Throwable $e) {
            // file already gone — still remove the row
        }
        $photo->delete();

        return response()->json(['success' => true, 'msg' => 'Photo deleted.']);
    }
}
