rejuvallife/app/Http/Controllers/Agent/MeetingController.php
2024-10-25 01:02:11 +05:00

424 lines
15 KiB
PHP

<?php
namespace App\Http\Controllers\Agent;
use Agence104\LiveKit\AccessToken;
use Agence104\LiveKit\AccessTokenOptions;
use Agence104\LiveKit\EgressServiceClient;
use Agence104\LiveKit\RoomCreateOptions;
use Agence104\LiveKit\RoomServiceClient;
use Agence104\LiveKit\VideoGrant;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Classes\JassJWT;
use App\Events\AppointmentCallEnded;
use App\Events\AppointmentCreated;
use App\Events\DeviceCurrentStatus;
use App\Models\Appointment;
use App\Models\Doctor;
use App\Models\DoctorAppointment;
use App\Models\Lab;
use App\Models\Patient;
use App\Models\PatientNote;
use App\Models\Telemedpro;
use Carbon\Carbon;
use DateTime;
use Error;
use Exception;
use Illuminate\Support\Facades\Auth;
use Livekit\EncodedFileOutput;
use Livekit\EncodedFileType;
use Illuminate\Support\Facades\Http;
class MeetingController extends Controller
{
public function getAsseblyAiToekn()
{
$response = Http::withHeaders([
'Authorization' => '0014470a9fa14b598a73cc0133acca8c',
])->post('https://api.assemblyai.com/v2/realtime/token', [
'expires_in' => 1600
]);
return $response->body();
}
public function show($meeting_id)
{
return view('agent.jetsi', compact('meeting_id'));
}
public function joinMeeting($meeting_id)
{
$jassToken = JassJWT::generate();
$appoinement = Appointment::where("meeting_id", $meeting_id)->firstOrFail();
return view('agent.join-meeting', compact('meeting_id'), compact('jassToken'));
}
public function startCall($patient_id, $agent_id, $appointment_id, Request $request)
{
$call_type = $request->input('call_type');
$telemed_pro = Telemedpro::where("id", $agent_id)->firstOrFail();
$appointment = Appointment::find($appointment_id);
$appointment->in_call = 1;
$appointment->start_time = Carbon::now()->format('Y-m-d H:i:s');
$appointment_booking_tokens = $this->bookAppointmentApi($appointment, $telemed_pro);
$appointment->agent_call_token = $appointment_booking_tokens['tokenAgent'];
$appointment->patient_call_token = $appointment_booking_tokens['tokenPatient'];
$appointment->telemed_pros_id = $agent_id;
$appointment->save();
event(new AppointmentCreated($patient_id, $appointment->id, $appointment->patient_call_token, $call_type));
return response()->json([
'message' => 'Appointment created!',
'appointment_id' => $appointment->id,
'meeting_id' => $appointment->agent_call_token,
'call_type' => $call_type
], 200);
}
public function startRecording(Appointment $appointment)
{
$telemed = Telemedpro::find($appointment->telemed_pros_id);
if ($telemed->recording_switch == 0) {
return response()->json([
'message' => "Recording Off",
'Response' => 'Error',
], 200);
}
$roomName = 'appointment-' . $appointment->id;
$video_token = md5(rand(100000000, 999999999) . rand(1, 9));
$appointment->video_token = $video_token;
$appointment->save();
$client = new EgressServiceClient("https://plugnmeet.codelfi.com", config('app.LK_API_KEY'), config('app.LK_API_SECRET'));
try {
$info = $client->startRoomCompositeEgress($roomName, 'speaker', new EncodedFileOutput([
"filepath" => "/out/recordings/" . $video_token . ".mp4",
"file_type" => EncodedFileType::MP4,
]));
} catch (Exception $e) {
return response()->json([
'message' => $e->getMessage(),
'Response' => 'Error',
], 200);
}
return response()->json([
'message' => "Success",
'Response' => 'Success',
], 200);
}
public function bookAppointmentApi($appointment, $availableTelemedPros)
{
$roomName = 'appointment-' . $appointment->id . "-" . uniqid();
$opts = (new RoomCreateOptions())
->setName($roomName)
->setEmptyTimeout(30)
->setMaxParticipants(5);
$host = "https://plugnmeet.codelfi.com";
$svc = new RoomServiceClient($host, config('app.LK_API_KEY'), config('app.LK_API_SECRET'));
try {
$svc->deleteRoom($roomName);
} catch (Exception | Error $e) {
}
$room = $svc->createRoom($opts);
$participantPatientName = "patient-" . uniqid() . $appointment->patient->first_name . " " . $appointment->patient->last_name;
$tokenOptionsPatient = (new AccessTokenOptions())
->setIdentity($participantPatientName);
$videoGrantPatient = (new VideoGrant())
->setRoomJoin()
->setRoomName($roomName);
$tokenPatient = (new AccessToken(config('app.LK_API_KEY'), config('app.LK_API_SECRET')))
->init($tokenOptionsPatient)
->setGrant($videoGrantPatient)
->toJwt();
$participantAgentName = "agent-" . uniqid() . $availableTelemedPros->name;
$tokenOptionsAgent = (new AccessTokenOptions())
->setIdentity($participantAgentName);
$videoGrantAgent = (new VideoGrant())
->setRoomJoin()
->setRoomName($roomName);
$tokenAgent = (new AccessToken(config('app.LK_API_KEY'), config('app.LK_API_SECRET')))
->init($tokenOptionsAgent)
->setGrant($videoGrantAgent)
->toJwt();
return [
'tokenPatient' => $tokenPatient,
'tokenAgent' => $tokenAgent,
];
}
public function endCall($patient_id, $appointment_id)
{
$appointment = Appointment::find($appointment_id);
$appointment->in_call = 0;
$appointment->end_time = Carbon::now()->format('Y-m-d H:i:s');
$appointment->save();
event(new AppointmentCallEnded($patient_id, $appointment->id));
return response()->json([
'message' => 'Call ended',
'appointment_id' => $appointment->id,
], 200);
}
public function searchLabsByAddress(Request $request)
{
$address = $request->input('address');
try {
$labs = Lab::where('address', 'like', '%' . $address . '%')
->orWhere('city', 'like', '%' . $address . '%')
->orWhere('state', 'like', '%' . $address . '%')
->orWhere('zip_code', 'like', '%' . $address . '%')
->get(['id', 'name', 'city', 'state', 'zip_code', 'lang', 'lat']);
return response()->json($labs, 200);
} catch (\Exception $e) {
return response()->json(['error' => 'Failed to search labs'], 500);
}
}
public function bookAppointment(Request $request)
{
$validatedData = $request->validate([
'telemed_pros_id' => 'required|exists:telemed_pros,id',
'patient_id' => 'required|exists:patients,id',
'doctor_id' => 'required|exists:doctors,id',
'appointment_id' => 'required',
'appointment_time' => 'required|date_format:Y-m-d H:i:s',
]);
$appointment = DoctorAppointment::create($validatedData);
return response()->json([
'message' => 'Appointment booked successfully',
'meeting_id' => $appointment->meeting_id,
'appointment_time' => $validatedData['appointment_time']
]);
}
public function updateInfo(Request $request, $patientId)
{
try {
$patient = Patient::find($patientId);
$patient->update($request->only(['city', 'state', 'address', 'zip_code', 'dob', 'country']));
$patient->save();
return response()->json(['message' => 'Patient address updated successfully'], 200);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
}
public function getInfo(Request $request, $patientId)
{
try {
$patient = Patient::find($patientId)->makeHidden(['password', 'remember_token']);
if ($patient->dob) {
$birthDate = new DateTime($patient->dob);
$today = new DateTime(date('Y-m-d'));
$age = $today->diff($birthDate)->y;
$patient->age = $age;
} else {
$patient->age = 0;
}
return response()->json($patient);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
}
public function getDoctorList()
{
try {
// Fetch only the necessary columns for efficiency
$doctors = Doctor::select('id', 'name', 'designation')->get()->makeHidden(['password', 'remember_token']);
// Return a successful JSON response with the doctors
return response()->json($doctors, 200);
} catch (\Exception $e) {
// Handle exceptions gracefully
return response()->json(['error' => $e->getMessage()], 500);
}
}
public function getAppointmentList()
{
try {
$appointments = Appointment::select("patients.first_name", "patients.last_name", "telemed_pros.name as agent_name", "appointments.*") // Eager load the associated telemed pro
->leftJoin("telemed_pros", "telemed_pros.id", "appointments.telemed_pros_id")
->leftJoin("patients", "patients.id", "appointments.patient_id")
/* ->orderBy('appointment_time', 'desc') */ // Optional: sort by appointment time
->get();
return response()->json($appointments, 200);
} catch (\Exception $e) {
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
}
}
public function getDoctorAppointmentList()
{
try {
$appointments = DoctorAppointment::select("patients.first_name", "patients.last_name", "doctor_appointments.*") // Eager load the associated telemed pro
->leftJoin("patients", "patients.id", "doctor_appointments.patient_id")
->orderBy('doctor_appointments.created_at', 'desc') // Optional: sort by appointment time
->get();
return response()->json($appointments, 200);
} catch (\Exception $e) {
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
}
}
public function availableSlots($date)
{
// Ensure date is in a valid format
$date = Carbon::parse($date);
// Generate all possible 30-minute slots between 9 AM and 4 PM
$slots = collect();
$startTime = Carbon::parse($date)->setTime(9, 0, 0);
$endTime = Carbon::parse($date)->setTime(16, 0, 0);
while ($startTime < $endTime) {
$slots->push($startTime->format('Y-m-d H:i:s'));
$startTime->addMinutes(30);
}
// Filter out booked slots
$bookedAppointments = Appointment::where('appointment_date', '>=', $date->format('Y-m-d'))
->where('appointment_date', '<', $date->addDay()->format('Y-m-d'))
->pluck('appointment_date');
$availableSlots = $slots->diff($bookedAppointments);
$formattedSlots = $availableSlots->map(function ($slot) {
$start = Carbon::parse($slot);
// Add AM/PM
$startTime = $start->format('g:i A');
$end = (clone $start)->addMinutes(29);
// Add AM/PM
$endTime = $end->format('g:i A');
return $startTime /* . ' - ' . $endTime */;
});
// Additional checking if slot is booked
$formattedSlots = $formattedSlots->filter(function ($slot) {
$startTime = Carbon::parse($slot);
/*$startTime = Carbon::parse(explode(' - ', $slot)[0]);
$endTime = Carbon::parse(explode(' - ', $slot)[1]); */
//return !Appointment::whereBetween('appointment_time', [$startTime/* , $endTime */])->exists();
return !Appointment::where('appointment_time', $startTime)->exists();
});
return response()->json([
'available_slots' => $formattedSlots->toArray()
]);
}
public function appointmentDetail(Appointment $appointment)
{
$patient = Patient::find($appointment->patient_id);
$telemedPro = Telemedpro::find($appointment->telemed_pros_id);
$doctor_appointment = DoctorAppointment::select("id", "appointment_date", "appointment_time", "appointment_id")->where('appointment_id', $appointment->id)->first();
if (!$doctor_appointment)
$doctor_appointment = [];
else
$doctor_appointment = $doctor_appointment->toArray();
if ($patient) {
if ($patient->dob) {
$birthDate = new DateTime($patient->dob);
$today = new DateTime(date('Y-m-d'));
$age = $today->diff($birthDate)->y;
$patient->age = $age;
} else {
$patient->age = 0;
}
}
return response()->json([
'patient' => $patient->toArray() ?? [],
'telemedPro' => $telemedPro->toArray() ?? [],
'doctor_appointment' => $doctor_appointment ?? [],
'agent_appointment' => $appointment,
'video_url' => "https://plugnmeet.codelfi.com/recordings/" . $appointment->video_token . ".mp4",
]);
}
public function labDetail(Appointment $appointment)
{
$lab = Lab::where("appointment_id", $appointment->id)->first();
return response()->json([
'lab_name' => $lab->name,
'lab_address' => $lab->address,
'lab_city' => $lab->city,
'lab_state' => $lab->state,
'lab_distance' => $lab->distance,
'lab_contact_no' => $lab->contact_no,
'lab_lang' => $lab->lang,
'lab_lat' => $lab->lat,
'slot_date' => $lab->slot_date,
'slot_time' => $lab->slot_time,
'booking_time' => $lab->booking_time,
]);
}
public function getRoomList()
{
$svc = new RoomServiceClient("https://plugnmeet.codelfi.com", config('app.LK_API_KEY'), config('app.LK_API_SECRET'));
// List rooms.
$rooms = $svc->listRooms();
dd($rooms);
}
public function addNotePatient(Request $request)
{
// Validation (adjust as needed)
$patient = Auth::guard('patient')->user();
$addNotePatient = PatientNote::create([
'note' => $request->input('note'),
'note_type' => $request->input('note_type'),
'patient_id' => $patient->id,
]);
return response()->json([
'message' => 'Note created',
'data' => $addNotePatient
], 200);
}
public function getNotePatient(Request $request)
{
// Validation (adjust as needed)
$patient = Auth::guard('patient')->user();
$addNotePatient = PatientNote::where("patient_id", $patient->id)->get();
return response()->json([
'message' => 'Note created',
'data' => $addNotePatient
], 200);
}
public function markAppointmentsStatus($id)
{
$appointment = Appointment::find($id);
$appointment->status = 'completed';
$appointment->save();
return response()->json([
'message' => 'status updated !'
], 200);
}
}