<?php

namespace App\Http\Controllers\Secretary;

use App\Http\Controllers\Controller;
use App\Models\Patient;
use App\Models\User;
use App\Models\Queue;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;

class PatientController extends Controller
{
    public function search(Request $request)
    {
        $q = trim($request->get('q', ''));
        if (strlen($q) < 2) return response()->json([]);

        return response()->json(
            User::where('role','patient')
                ->where(fn($x) => $x->where('name','like',"%$q%")->orWhere('phone','like',"%$q%")->orWhere('email','like',"%$q%"))
                ->with('patient')->take(8)->get()
                ->map(fn($u) => [
                    'id'         => $u->patient?->id,
                    'name'       => $u->name,
                    'phone'      => $u->phone,
                    'blood_type' => $u->patient?->blood_type,
                    'gender'     => match($u->patient?->gender){'male'=>'ذكر','female'=>'أنثى',default=>null},
                    'age'        => $u->patient?->date_of_birth ? \Carbon\Carbon::parse($u->patient->date_of_birth)->age.' سنة' : null,
                    'chronic'    => $u->patient?->chronic_diseases,
                    'allergies'  => $u->patient?->allergies,
                ])
        );
    }

    public function index(Request $request)
    {
        $doctorId = session('secretary_doctor_id');
        $patients = Patient::with('user')
            ->where(function($q) use($doctorId){
                $q->whereHas('appointments', fn($x) => $x->where('doctor_id',$doctorId))
                  ->orWhereHas('queues',       fn($x) => $x->where('doctor_id',$doctorId));
            })
            ->when($request->search, fn($q) =>
                $q->whereHas('user', fn($u) =>
                    $u->where('name','like',"%{$request->search}%")->orWhere('phone','like',"%{$request->search}%")
                )
            )
            ->latest()->paginate(15)->withQueryString();

        return view('secretary.patients.index', compact('patients'));
    }

    public function create()
    {
        return view('secretary.patients.form', ['patient' => null]);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'name'                       => 'required|string|max:100',
            'phone'                      => 'required|string|unique:users,phone',
            'email'                      => 'nullable|email|unique:users,email',
            'gender'                     => 'nullable|in:male,female',
            'date_of_birth'              => 'nullable|date',
            'blood_type'                 => 'nullable|in:A+,A-,B+,B-,AB+,AB-,O+,O-',
            'weight'                     => 'nullable|numeric',
            'height'                     => 'nullable|numeric',
            'national_id'                => 'nullable|string|unique:patients,national_id',
            'chronic_diseases'           => 'nullable|string|max:500',
            'allergies'                  => 'nullable|string|max:500',
            'current_medications'        => 'nullable|string|max:500',
            'emergency_contact_name'     => 'nullable|string|max:100',
            'emergency_contact_phone'    => 'nullable|string|max:20',
            'emergency_contact_relation' => 'nullable|string|max:50',
            'add_to_queue'               => 'nullable|boolean',
        ]);

        DB::beginTransaction();
        try {
            $user = User::create([
                'name'      => $data['name'],
                'phone'     => $data['phone'],
                'email'     => $data['email'] ?? null,
                'password'  => Hash::make($data['phone']),
                'role'      => 'patient',
                'is_active' => true,
            ]);
            $patient = Patient::create([
                'user_id'                    => $user->id,
                'gender'                     => $data['gender'] ?? null,
                'date_of_birth'              => $data['date_of_birth'] ?? null,
                'blood_type'                 => $data['blood_type'] ?? null,
                'weight'                     => $data['weight'] ?? null,
                'height'                     => $data['height'] ?? null,
                'national_id'                => $data['national_id'] ?? null,
                'chronic_diseases'           => $data['chronic_diseases'] ?? null,
                'allergies'                  => $data['allergies'] ?? null,
                'current_medications'        => $data['current_medications'] ?? null,
                'emergency_contact_name'     => $data['emergency_contact_name'] ?? null,
                'emergency_contact_phone'    => $data['emergency_contact_phone'] ?? null,
                'emergency_contact_relation' => $data['emergency_contact_relation'] ?? null,
            ]);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error','حدث خطأ: '.$e->getMessage())->withInput();
        }

        if ($request->boolean('add_to_queue')) {
            $doctorId = session('secretary_doctor_id');
            $doctor   = \App\Models\Doctor::find($doctorId);
            $lastNum  = Queue::where('doctor_id',$doctorId)->today()->max('queue_number') ?? 0;
            $waitPos  = Queue::where('doctor_id',$doctorId)->today()->whereIn('status',['waiting','called'])->count();
            Queue::create([
                'doctor_id'=>$doctorId,'patient_id'=>$patient->id,
                'queue_date'=>today(),'queue_number'=>$lastNum+1,'position'=>$waitPos+1,
                'status'=>'waiting','arrived_at'=>now(),
                'estimated_wait_minutes'=>($waitPos+1)*($doctor->appointment_duration??15),
            ]);
            return redirect()->route('secretary.dashboard')
                ->with('success','تم تسجيل '.$user->name.' وإضافته للطابور برقم '.($lastNum+1));
        }

        return redirect()->route('secretary.patients.show',$patient->id)
            ->with('success','تم تسجيل المريض '.$user->name.' بنجاح');
    }

    public function show($id)
    {
        $doctorId = session('secretary_doctor_id');
        $patient  = Patient::with([
            'user',
            'medicalRecords' => fn($q) => $q->where('doctor_id',$doctorId)->latest()->take(10),
            'appointments'   => fn($q) => $q->where('doctor_id',$doctorId)->latest()->take(5),
        ])->findOrFail($id);

        $inQueue     = Queue::where('patient_id',$id)->where('doctor_id',$doctorId)->today()
                            ->whereIn('status',['waiting','called','in_progress'])->first();
        $totalVisits = $patient->medicalRecords()->where('doctor_id',$doctorId)->count();

        return view('secretary.patients.show', compact('patient','inQueue','totalVisits'));
    }

    public function edit($id)
    {
        $patient = Patient::with('user')->findOrFail($id);
        return view('secretary.patients.form', compact('patient'));
    }

    public function update(Request $request, $id)
    {
        $patient = Patient::with('user')->findOrFail($id);
        $data = $request->validate([
            'name'                       => 'required|string|max:100',
            'phone'                      => 'required|string|unique:users,phone,'.$patient->user_id,
            'email'                      => 'nullable|email|unique:users,email,'.$patient->user_id,
            'gender'                     => 'nullable|in:male,female',
            'date_of_birth'              => 'nullable|date',
            'blood_type'                 => 'nullable|in:A+,A-,B+,B-,AB+,AB-,O+,O-',
            'weight'                     => 'nullable|numeric',
            'height'                     => 'nullable|numeric',
            'national_id'                => 'nullable|string|unique:patients,national_id,'.$id,
            'chronic_diseases'           => 'nullable|string|max:500',
            'allergies'                  => 'nullable|string|max:500',
            'current_medications'        => 'nullable|string|max:500',
            'emergency_contact_name'     => 'nullable|string|max:100',
            'emergency_contact_phone'    => 'nullable|string|max:20',
            'emergency_contact_relation' => 'nullable|string|max:50',
        ]);

        $patient->user->update(['name'=>$data['name'],'phone'=>$data['phone'],'email'=>$data['email']??null]);
        $patient->update(\Illuminate\Support\Arr::except($data, ['name','phone','email']));

        return redirect()->route('secretary.patients.show',$id)->with('success','تم تحديث بيانات المريض');
    }
}
