<?php

declare(strict_types=1);
require dirname(__DIR__) . '/app/bootstrap.php';
require_once DENTAL_ROOT . '/app/appointment_planning.php';
header('Content-Type: application/json; charset=utf-8');

try {
    $branchId=(int)($_GET['branch_id']??public_request_branch_id()??0);
    $doctorId=(int)($_GET['doctor_id']??0);
    $serviceId=(int)($_GET['service_id']??0);
    $serviceIds=array_filter(array_map('intval',explode(',',(string)($_GET['service_ids']??''))));
    if($serviceId>0)array_unshift($serviceIds,$serviceId);
    $serviceIds=array_values(array_unique($serviceIds));
    $date=(string)($_GET['date']??'');
    $requestedTime=substr(trim((string)($_GET['time']??'')),0,5);
    $newPatient=(string)($_GET['patient_type']??'')==='new';
    $patientId=(int)($_GET['patient_id']??0);
    if($branchId<1||!$serviceIds||!preg_match('/^\d{4}-\d{2}-\d{2}$/',$date))throw new RuntimeException('Select at least one service and a date.');
    $services=appointment_service_definitions($branchId,$serviceIds);
    $providerModel=appointment_bundle_provider_model($services);
    $options=appointment_bundle_available_options($branchId,$date,$services,$doctorId,$newPatient,0,$patientId);

    $slots=[];$byTime=[];$doctorMap=[];
    foreach($options as $option){
        $doctor=[
            'id'=>(int)$option['doctor_id'],
            'name'=>(string)$option['doctor_name'],
            'specialty_name'=>(string)$option['specialty_name'],
            'chair_name'=>(string)$option['chair_name'],
        ];
        if((int)$option['doctor_id']>0)$doctorMap[(int)$option['doctor_id']]=$doctor;
        $segmentNames=array_map(static fn(array $segment):string=>(string)$segment['service_name'],(array)$option['segments']);
        $label=date('g:i A',strtotime((string)$option['time'])).'–'.date('g:i A',strtotime((string)$option['end_time']));
        $row=[
            'doctor_id'=>(int)$option['doctor_id'],
            'doctor_name'=>(string)$option['doctor_name'],
            'inhouse_provider_user_id'=>(int)($option['segments'][0]['inhouse_provider_user_id']??0),
            'inhouse_provider_name'=>(string)($option['segments'][0]['inhouse_provider_name']??''),
            'chair_id'=>(int)($option['segments'][0]['chair_id']??0),
            'chair_name'=>(string)$option['chair_name'],
            'time'=>(string)$option['time'],
            'end_time'=>(string)$option['end_time'],
            'duration_minutes'=>(int)$option['duration_minutes'],
            'label'=>$label,
            'service_names'=>$segmentNames,
            'segments'=>$option['segments'],
        ];
        $slots[]=$row;
        $time=(string)$option['time'];
        if(!isset($byTime[$time]))$byTime[$time]=['time'=>$time,'label'=>$label,'duration_minutes'=>(int)$option['duration_minutes'],'doctors'=>[]];
        $byTime[$time]['doctors'][]=$doctor;
    }
    ksort($byTime);
    $times=array_values($byTime);
    $selected=null;
    foreach($slots as $row)if($requestedTime!==''&&$row['time']===$requestedTime){$selected=$row;break;}
    $message='';
    if(!$slots)$message=$providerModel==='mixed'
        ? 'No complete sequence is available for every selected service, provider, and chair on this date. Choose another date or remove a service.'
        : 'No complete provider-and-chair time is available for the selected service bundle on this date.';

    echo json_encode([
        'ok'=>true,
        'slots'=>$slots,
        'times'=>$times,
        'doctors'=>array_values($doctorMap),
        'available_doctors'=>$requestedTime!==''&&isset($byTime[$requestedTime])?$byTime[$requestedTime]['doctors']:[],
        'reschedule_required'=>count($slots)===0,
        'message'=>$message,
        'chair_issue_count'=>0,
        'doctor_chair'=>$selected['chair_name']??null,
        'provider_type'=>$providerModel,
        'service'=>$services[0],
        'services'=>$services,
        'total_duration_minutes'=>$slots?(int)$slots[0]['duration_minutes']:array_sum(array_map(static fn(array $service):int=>(int)$service['duration_minutes'],$services)),
    ],JSON_UNESCAPED_SLASHES);
}catch(Throwable $e){
    http_response_code(422);
    echo json_encode(['ok'=>false,'message'=>$e->getMessage(),'slots'=>[],'times'=>[],'doctors'=>[],'available_doctors'=>[],'reschedule_required'=>true]);
}
