<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Patient;
use App\Models\Surgeon;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class PatientController extends Controller
{
    /**
     * Affiche une liste paginée des patients uniques
     * associés à un chirurgien spécifique.
     * Supporte la recherche par nom, prénom et filtrage par sexe.
     */
    public function index(Request $request)
    {
        $validated = $request->validate([
            'surgeon_firebase_uid' => 'required|string|exists:surgeons,firebase_uid',
            'search' => 'nullable|string',
            'sexe' => 'nullable|in:Masculin,Féminin,Autre',
            'page' => 'nullable|integer|min:1'
        ]);

        $surgeon = Surgeon::where('firebase_uid', $validated['surgeon_firebase_uid'])->first();

        $query = Patient::whereHas('interventions', function ($query) use ($surgeon) {
                $query->where('surgeon_id', $surgeon->id);
            })
            ->withCount('interventions'); // Ajoute le nombre d'interventions

        // Recherche par nom ou prénom (insensible à la casse)
        if ($request->has('search') && !empty($request->input('search'))) {
            $searchTerm = $request->input('search');
            $query->where(function ($q) use ($searchTerm) {
                $q->whereRaw('LOWER(nom) LIKE ?', ['%' . strtolower($searchTerm) . '%'])
                  ->orWhereRaw('LOWER(prenom) LIKE ?', ['%' . strtolower($searchTerm) . '%'])
                  ->orWhereRaw('LOWER(numero_identifiant) LIKE ?', ['%' . strtolower($searchTerm) . '%']);
            });
        }

        // Filtre par sexe
        if ($request->has('sexe') && !empty($request->input('sexe'))) {
            $query->where('sexe', $request->input('sexe'));
        }

        $patients = $query->latest()->paginate(15);

        return response()->json($patients);
    }

    /**
     * Affiche les détails d'un patient spécifique
     * avec toutes ses interventions.
     */
    public function show(Request $request, $id)
    {
        $request->validate([
            'surgeon_firebase_uid' => 'required|string|exists:surgeons,firebase_uid'
        ]);

        $surgeon = Surgeon::where('firebase_uid', $request->query('surgeon_firebase_uid'))->first();

        // On vérifie que le patient a au moins une intervention avec ce chirurgien
        $patient = Patient::whereHas('interventions', function ($query) use ($surgeon) {
                $query->where('surgeon_id', $surgeon->id);
            })
            ->with([
                'interventions' => function ($query) use ($surgeon) {
                    $query->where('surgeon_id', $surgeon->id)
                          ->latest('date_intervention');
                }
            ])
            ->findOrFail($id);

        return response()->json($patient);
    }

    /**
     * Crée un nouveau patient.
     * Note: Dans votre logique actuelle, les patients sont créés via les interventions,
     * mais cette méthode peut être utile pour créer un patient avant l'intervention.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'surgeon_firebase_uid' => 'required|string|exists:surgeons,firebase_uid',
            'nom' => 'required|string|max:255',
            'prenom' => 'nullable|string|max:255',
            'date_naissance' => 'nullable|date',
            'sexe' => 'nullable|in:Masculin,Féminin,Autre',
            'profession' => 'nullable|string|max:255',
            'profession_autre' => 'nullable|string|max:255',
            'adresse' => 'nullable|string',
            'telephone' => 'nullable|string|max:20',
            'numero_identifiant' => 'nullable|string|unique:patients,numero_identifiant',
        ]);

        // On retire le surgeon_firebase_uid des données à insérer
        $surgeonUid = $validated['surgeon_firebase_uid'];
        unset($validated['surgeon_firebase_uid']);

        $patient = Patient::create($validated);

        return response()->json([
            'message' => 'Patient créé avec succès',
            'patient' => $patient
        ], 201);
    }

    /**
     * Met à jour les informations d'un patient.
     */
    public function update(Request $request, $id)
    {
        $validated = $request->validate([
            'surgeon_firebase_uid' => 'required|string|exists:surgeons,firebase_uid',
            'nom' => 'sometimes|required|string|max:255',
            'prenom' => 'nullable|string|max:255',
            'date_naissance' => 'nullable|date',
            'sexe' => 'nullable|in:Masculin,Féminin,Autre',
            'profession' => 'nullable|string|max:255',
            'profession_autre' => 'nullable|string|max:255',
            'adresse' => 'nullable|string',
            'telephone' => 'nullable|string|max:20',
            'numero_identifiant' => [
                'nullable',
                'string',
                Rule::unique('patients', 'numero_identifiant')->ignore($id)
            ],
        ]);

        $surgeon = Surgeon::where('firebase_uid', $validated['surgeon_firebase_uid'])->first();

        // Vérifier que le patient appartient au chirurgien
        $patient = Patient::whereHas('interventions', function ($query) use ($surgeon) {
                $query->where('surgeon_id', $surgeon->id);
            })
            ->findOrFail($id);

        // On retire le surgeon_firebase_uid des données à mettre à jour
        unset($validated['surgeon_firebase_uid']);

        $patient->update($validated);

        return response()->json([
            'message' => 'Patient mis à jour avec succès',
            'patient' => $patient->fresh()
        ]);
    }

    /**
     * Supprime un patient.
     * ATTENTION: Avec la cascade, cela supprimera aussi toutes les interventions liées.
     */
    public function destroy(Request $request, $id)
    {
        $request->validate([
            'surgeon_firebase_uid' => 'required|string|exists:surgeons,firebase_uid'
        ]);

        $surgeon = Surgeon::where('firebase_uid', $request->query('surgeon_firebase_uid'))->first();

        // Vérifier que le patient appartient au chirurgien
        $patient = Patient::whereHas('interventions', function ($query) use ($surgeon) {
                $query->where('surgeon_id', $surgeon->id);
            })
            ->findOrFail($id);

        $patientName = $patient->nom . ' ' . $patient->prenom;
        $patient->delete();

        return response()->json([
            'message' => "Le patient {$patientName} a été supprimé avec succès"
        ]);
    }

    /**
     * Recherche des patients par nom, prénom ou numéro d'identifiant
     * pour un chirurgien spécifique.
     */
    public function search(Request $request)
    {
        $validated = $request->validate([
            'surgeon_firebase_uid' => 'required|string|exists:surgeons,firebase_uid',
            'query' => 'required|string|min:2'
        ]);

        $surgeon = Surgeon::where('firebase_uid', $validated['surgeon_firebase_uid'])->first();
        $searchTerm = $validated['query'];

        $patients = Patient::whereHas('interventions', function ($query) use ($surgeon) {
                $query->where('surgeon_id', $surgeon->id);
            })
            ->where(function ($query) use ($searchTerm) {
                $query->where('nom', 'LIKE', "%{$searchTerm}%")
                      ->orWhere('prenom', 'LIKE', "%{$searchTerm}%")
                      ->orWhere('numero_identifiant', 'LIKE', "%{$searchTerm}%");
            })
            ->withCount('interventions')
            ->latest()
            ->paginate(15);

        return response()->json($patients);
    }
}