<?php
declare(strict_types=1);
namespace App\Controllers;
use App\Core\Auth;use App\Core\Controller;use App\Core\Csrf;use App\Core\Response;use App\Core\Session;use App\Services\AppointmentService;use App\Services\AssignmentService;use InvalidArgumentException;use RuntimeException;
final class AppointmentController extends Controller{
    private function assertAppointmentManager(): void
    {
        $user = $_SESSION['user'] ?? [];
        $role = strtoupper((string)($user['role_name'] ?? $user['role'] ?? ''));
        if (in_array($role, ['THERAPIST', 'THERAPIST_ROLE'], true)) {
            throw new \RuntimeException('Therapists cannot create or manage appointments.');
        }
    }


 public function __construct(private ?AppointmentService $service=null,private ?AssignmentService $assignments=null){$this->service??=new AppointmentService();$this->assignments??=new AssignmentService();}
 private function therapistId():?int{if(!Auth::hasRole('THERAPIST'))return null;$id=$this->assignments->therapistIdForUser(Auth::id()??0);if($id===null)throw new RuntimeException('Your therapist profile is not active.',403);return$id;}
 private function authorize(array $a,?int $tid):void{if($tid!==null&&(int)$a['therapist_id']!==$tid)throw new RuntimeException('You do not have permission to access this appointment.',403);}
 public function index():Response{$tid=$this->therapistId();$f=['view'=>(string)($_GET['view']??'week'),'date'=>(string)($_GET['date']??date('Y-m-d')),'status'=>(string)($_GET['status']??'')];return$this->view('appointments/index',['pageTitle'=>'Appointments','pageDescription'=>$tid!==null?'Your patient appointments.':'Schedule and manage appointments.','appointments'=>$this->service->list($f,$tid),'filters'=>$f,'csrf'=>Csrf::token(),'message'=>Session::pull('appointment_message'),'error'=>Session::pull('appointment_error')]);}
 private function ensureScheduler():void{if(Auth::hasRole('THERAPIST'))throw new RuntimeException('Therapists cannot create or manage appointments. Please ask Admin or reception to schedule the appointment.',403);}
 public function createForm():Response{
        $this->assertAppointmentManager();$this->ensureScheduler();$tid=$this->therapistId();return$this->view('appointments/form',['pageTitle'=>'New Appointment','pageDescription'=>'Schedule a patient appointment.','appointment'=>null,'form'=>Session::pull('appointment_form')??[],'error'=>Session::pull('appointment_error'),'csrf'=>Csrf::token(),...$this->service->formData($tid),'therapistLocked'=>$tid!==null]);}
 public function create():Response{$this->ensureScheduler();Csrf::verify((string)($_POST['_csrf']??''));$tid=$this->therapistId();try{$id=$this->service->create($_POST,Auth::id()??0,$tid);Session::put('appointment_message','Appointment created successfully.');return Response::redirect('/crm/public/appointments/'.$id.'/edit');}catch(InvalidArgumentException $e){Session::put('appointment_error',$e->getMessage());Session::put('appointment_form',$_POST);return Response::redirect('/crm/public/appointments/create');}}
 public function editForm(int $id):Response{
        $this->assertAppointmentManager();$this->ensureScheduler();$tid=$this->therapistId();$a=$this->service->find($id);$this->authorize($a,$tid);return$this->view('appointments/form',['pageTitle'=>'Edit Appointment','pageDescription'=>'Update appointment details.','appointment'=>$a,'form'=>Session::pull('appointment_form')??[],'error'=>Session::pull('appointment_error'),'csrf'=>Csrf::token(),...$this->service->formData($tid),'therapistLocked'=>$tid!==null]);}
 public function update(int $id):Response{
        $this->assertAppointmentManager();$this->ensureScheduler();Csrf::verify((string)($_POST['_csrf']??''));$tid=$this->therapistId();try{$a=$this->service->find($id);$this->authorize($a,$tid);$this->service->update($id,$_POST,$tid);Session::put('appointment_message','Appointment updated successfully.');}catch(InvalidArgumentException $e){Session::put('appointment_error',$e->getMessage());Session::put('appointment_form',$_POST);}return Response::redirect('/crm/public/appointments/'.$id.'/edit');}
 public function cancel(int $id):Response{$this->ensureScheduler();Csrf::verify((string)($_POST['_csrf']??''));$tid=$this->therapistId();try{$a=$this->service->find($id);$this->authorize($a,$tid);$this->service->cancel($id);Session::put('appointment_message','Appointment cancelled.');}catch(InvalidArgumentException $e){Session::put('appointment_error',$e->getMessage());}return Response::redirect('/crm/public/appointments');}
 public function status(int $id):Response{Csrf::verify((string)($_POST['_csrf']??''));$tid=$this->therapistId();if($tid===null)throw new RuntimeException('Only therapists use this action.',403);$status=(string)($_POST['status']??'');if(!in_array($status,['completed','no_show'],true))throw new InvalidArgumentException('Invalid appointment status.');$a=$this->service->find($id);$this->authorize($a,$tid);if(!in_array($a['status'],['scheduled','confirmed'],true))throw new InvalidArgumentException('Only scheduled or confirmed appointments can be updated.');$this->service->markStatus($id,$status);Session::put('appointment_message',$status==='completed'?'Appointment marked completed.':'Appointment marked no-show.');return Response::redirect('/crm/public/appointments');}
}
