<?php

declare(strict_types=1);
require DENTAL_ROOT . '/app/bootstrap.php';
require_login();
require_roles(['super_admin','clinic_admin']);
require DENTAL_ROOT . '/app/layout.php';
require DENTAL_ROOT . '/app/module_helpers.php';
require_once DENTAL_ROOT . '/app/chair_resource.php';

$pdo = db();
if (!clinic_chair_schema_ready()) {
    render_header('Chairs & Resources'); ?><section class="card"><h2>Update required</h2><p>Apply Version 0.5.8.3 before managing formal clinic chairs.</p><?php if (actual_role()==='super_admin'): ?><a class="btn primary" href="system_setup.php?tab=updates">Open Updates &amp; Database</a><?php endif; ?></section><?php render_footer(); return;
}
if (!chair_resource_schema_ready()) {
    render_header('Chairs & Resources'); ?><section class="card"><h2>Chair resource update required</h2><p>Apply Version 0.5.9.8.47 before managing temporary chair sessions, visit-level chair moves, and resource occupancy.</p><?php if (actual_role()==='super_admin'): ?><a class="btn primary" href="system_setup.php?tab=updates">Open Updates &amp; Database</a><?php endif; ?></section><?php render_footer(); return;
}

$branches = $pdo->query('SELECT id,name FROM `' . table('branches') . '` WHERE is_active=1 ORDER BY name')->fetchAll();
$branchId = (int)($_GET['branch_id'] ?? $_POST['branch_id'] ?? ($branches[0]['id'] ?? 0));
$branchIds = array_map(static fn(array $row): int => (int)$row['id'], $branches);
if ($branchId && !in_array($branchId, $branchIds, true)) $branchId = (int)($branches[0]['id'] ?? 0);

function chair_target(PDO $pdo, int $id): array
{
    $stmt = $pdo->prepare('SELECT * FROM `' . table('clinic_chairs') . '` WHERE id=? LIMIT 1');
    $stmt->execute([$id]);
    $row = $stmt->fetch();
    if (!$row) throw new RuntimeException('Chair/resource not found.');
    return $row;
}

function chair_future_appointments(PDO $pdo, int $branchId, int $chairId, string $chairName): int
{
    $stmt = $pdo->prepare('SELECT COUNT(*) FROM `' . table('appointments') . '` WHERE branch_id=? AND (chair_id=? OR (chair_id IS NULL AND chair_name=?)) AND start_at>=NOW() AND status NOT IN ("cancelled","no_show","completed")');
    $stmt->execute([$branchId,$chairId,$chairName]);
    return (int)$stmt->fetchColumn();
}

function chair_user_options(PDO $pdo, int $branchId): array
{
    $stmt = $pdo->prepare('SELECT u.id,u.name name,r.code role_code FROM `' . table('users') . '` u JOIN `' . table('roles') . '` r ON r.id=u.role_id LEFT JOIN `' . table('dentist_profiles') . '` dp ON dp.user_id=u.id WHERE u.status="active" AND r.code IN ("dentist","dental_assistant","staff") AND (u.branch_id=? OR u.branch_id IS NULL OR ?=0) ORDER BY r.code="dentist" DESC,name');
    $stmt->execute([$branchId,$branchId]);
    return $stmt->fetchAll();
}

function chair_active_queue_options(PDO $pdo, int $branchId): array
{
    $stmt = $pdo->prepare('SELECT q.id,q.queue_no,q.status,q.chair_name,CONCAT(COALESCE(p.first_name,"")," ",COALESCE(p.last_name,"")) patient,p.patient_no FROM `' . table('queue_entries') . '` q LEFT JOIN `' . table('patients') . '` p ON p.id=q.patient_id WHERE q.branch_id=? AND q.status IN ("seated","in_treatment") ORDER BY q.chair_name,q.queue_no');
    $stmt->execute([$branchId]);
    return $stmt->fetchAll();
}

function chair_session_conflict(PDO $pdo, int $branchId, int $chairId, int $dentistId, string $startAt, string $endAt, int $excludeId = 0): ?string
{
    $sql = 'SELECT csa.id,csa.chair_name,u.name dentist_name FROM `' . table('chair_session_assignments') . '` csa LEFT JOIN `' . table('users') . '` u ON u.id=csa.dentist_user_id WHERE csa.branch_id=? AND csa.status="active" AND csa.starts_at < ? AND csa.ends_at > ? AND (csa.chair_id=? OR (csa.dentist_user_id IS NOT NULL AND csa.dentist_user_id=?))';
    $args = [$branchId,$endAt,$startAt,$chairId,$dentistId];
    if ($excludeId > 0) { $sql .= ' AND csa.id<>?'; $args[] = $excludeId; }
    $sql .= ' ORDER BY csa.starts_at LIMIT 1';
    $stmt = $pdo->prepare($sql);
    $stmt->execute($args);
    $row = $stmt->fetch();
    if (!$row) return null;
    return 'This time overlaps another chair/provider session: ' . (string)($row['chair_name'] ?: 'Chair') . ' · ' . (string)($row['dentist_name'] ?: 'Provider');
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        verify_csrf();
        $action = (string)($_POST['action'] ?? 'save');
        if ($action === 'save') {
            if ($branchId < 1) throw new RuntimeException('Select a branch.');
            $id = (int)($_POST['id'] ?? 0);
            $code = strtoupper(trim((string)($_POST['chair_code'] ?? '')));
            $name = trim((string)($_POST['chair_name'] ?? ''));
            $room = trim((string)($_POST['room_name'] ?? ''));
            $mode = (string)($_POST['usage_mode'] ?? 'operatory');
            $resourceKind = $mode === 'dentist_bound' ? 'operatory' : $mode;
            $status = (string)($_POST['status'] ?? 'available');
            $notes = trim((string)($_POST['notes'] ?? ''));
            $allowedModes = array_keys(chair_resource_usage_labels());
            if ($code === '' || $name === '') throw new RuntimeException('Chair code and chair name are required.');
            if (!preg_match('/^[A-Z0-9][A-Z0-9_-]{0,39}$/', $code)) throw new RuntimeException('Chair code may contain letters, numbers, dashes, and underscores.');
            if (!in_array($mode, $allowedModes, true) || !in_array($status, ['available','maintenance','inactive'], true)) throw new RuntimeException('Choose a valid resource type and status.');
            if ($id > 0) {
                $old = chair_target($pdo,$id);
                if ((int)$old['branch_id'] !== $branchId) throw new RuntimeException('The chair does not belong to the selected branch.');
                $future = chair_future_appointments($pdo,$branchId,$id,(string)$old['chair_name']);
                if ($status !== 'available' && $future > 0) throw new RuntimeException('This chair has ' . $future . ' future active appointment(s). Reschedule them before marking it unavailable.');
                $pdo->beginTransaction();
                $pdo->prepare('UPDATE `' . table('clinic_chairs') . '` SET chair_code=?,chair_name=?,room_name=?,usage_mode=?,resource_kind=?,status=?,notes=?,current_status_note=?,updated_at=NOW() WHERE id=?')
                    ->execute([$code,$name,$room ?: null,$mode,$resourceKind,$status,$notes ?: null,$notes ?: null,$id]);
                if ((string)$old['chair_name'] !== $name) {
                    $pdo->prepare('UPDATE `' . table('doctor_chair_assignments') . '` SET chair_name=?,updated_at=NOW() WHERE chair_id=?')->execute([$name,$id]);
                    $pdo->prepare('UPDATE `' . table('chair_session_assignments') . '` SET chair_name=?,updated_at=NOW() WHERE chair_id=? AND status="active"')->execute([$name,$id]);
                    $pdo->prepare('UPDATE `' . table('queue_entries') . '` SET chair_name=?,updated_at=NOW() WHERE chair_id=? AND status IN ("seated","in_treatment")')->execute([$name,$id]);
                }
                chair_resource_record_event($pdo,$id,'resource_updated','Resource profile updated');
                $pdo->commit();
                audit('clinic_chair_updated','clinic_chair',$id,['name'=>$name,'status'=>$status,'usage_mode'=>$mode],$old);
            } else {
                $pdo->prepare('INSERT INTO `' . table('clinic_chairs') . '` (branch_id,chair_code,chair_name,room_name,usage_mode,resource_kind,status,notes,current_status_note,created_by,created_at) VALUES (?,?,?,?,?,?,?,?,?,?,NOW())')
                    ->execute([$branchId,$code,$name,$room ?: null,$mode,$resourceKind,$status,$notes ?: null,$notes ?: null,(int)current_user()['id']]);
                $id = (int)$pdo->lastInsertId();
                chair_resource_record_event($pdo,$id,'resource_created','Resource created');
                audit('clinic_chair_created','clinic_chair',$id,['branch_id'=>$branchId,'name'=>$name,'usage_mode'=>$mode]);
            }
            flash('success','Chair/resource saved.');
        } elseif ($action === 'assign_default') {
            $chairId = (int)($_POST['chair_id'] ?? 0);
            $dentistId = (int)($_POST['dentist_user_id'] ?? 0);
            $chair = chair_target($pdo,$chairId);
            $branchId = (int)$chair['branch_id'];
            if ($dentistId < 1) throw new RuntimeException('Select a Dentist for the optional default provider.');
            $mode = (string)($chair['usage_mode'] ?? $chair['resource_kind'] ?? 'operatory');
            if (!in_array($mode, chair_resource_clinical_modes(), true) || $chair['status'] !== 'available') throw new RuntimeException('Only an available treatment operatory can receive a default Dentist.');
            $dentist = $pdo->prepare('SELECT u.id,u.name FROM `' . table('users') . '` u JOIN `' . table('roles') . '` r ON r.id=u.role_id WHERE u.id=? AND u.status="active" AND r.code="dentist" LIMIT 1');
            $dentist->execute([$dentistId]);
            $dentistRow = $dentist->fetch();
            if (!$dentistRow) throw new RuntimeException('Active Dentist account not found.');
            $pdo->beginTransaction();
            $pdo->prepare('DELETE FROM `' . table('doctor_chair_assignments') . '` WHERE branch_id=? AND (dentist_user_id=? OR chair_id=?)')->execute([$branchId,$dentistId,$chairId]);
            $pdo->prepare('INSERT INTO `' . table('doctor_chair_assignments') . '` (dentist_user_id,branch_id,chair_id,chair_name,is_active,assignment_type,created_by,created_at) VALUES (?,?,?,?,1,"default_provider",?,NOW())')->execute([$dentistId,$branchId,$chairId,$chair['chair_name'],(int)current_user()['id']]);
            $pdo->prepare('UPDATE `' . table('clinic_chairs') . '` SET default_provider_user_id=?,updated_at=NOW() WHERE id=?')->execute([$dentistId,$chairId]);
            $pdo->prepare('UPDATE `' . table('dentist_profiles') . '` SET default_chair_name=?,primary_branch_id=COALESCE(primary_branch_id,?),updated_at=NOW() WHERE user_id=?')->execute([$chair['chair_name'],$branchId,$dentistId]);
            chair_resource_record_event($pdo,$chairId,'default_provider_assigned','Optional default Dentist assigned',null,null,$dentistId);
            $pdo->commit();
            audit('chair_default_provider_assigned','clinic_chair',$chairId,['dentist_user_id'=>$dentistId,'branch_id'=>$branchId]);
            flash('success',$chair['chair_name'] . ' default provider set to ' . $dentistRow['name'] . '. Future appointments are not silently rewritten.');
        } elseif ($action === 'unassign_default') {
            $chairId = (int)($_POST['chair_id'] ?? 0);
            $chair = chair_target($pdo,$chairId);
            $pdo->beginTransaction();
            $pdo->prepare('DELETE FROM `' . table('doctor_chair_assignments') . '` WHERE chair_id=?')->execute([$chairId]);
            $pdo->prepare('UPDATE `' . table('clinic_chairs') . '` SET default_provider_user_id=NULL,updated_at=NOW() WHERE id=?')->execute([$chairId]);
            chair_resource_record_event($pdo,$chairId,'default_provider_removed','Optional default provider removed');
            $pdo->commit();
            audit('chair_default_provider_unassigned','clinic_chair',$chairId);
            flash('success','Default provider removed. Existing appointment and active-visit chair assignments were not changed.');
        } elseif ($action === 'save_session') {
            $chairId = (int)($_POST['chair_id'] ?? 0);
            $dentistId = (int)($_POST['dentist_user_id'] ?? 0);
            $start = trim((string)($_POST['starts_at'] ?? ''));
            $end = trim((string)($_POST['ends_at'] ?? ''));
            $reason = trim((string)($_POST['reason'] ?? ''));
            $chair = chair_target($pdo,$chairId);
            $branchId = (int)$chair['branch_id'];
            if ($dentistId < 1) throw new RuntimeException('Select a Dentist for this temporary chair session.');
            if ($start === '' || $end === '' || strtotime($start) === false || strtotime($end) === false || strtotime($end) <= strtotime($start)) throw new RuntimeException('Enter a valid start and end time for the session.');
            $startAt = date('Y-m-d H:i:s', strtotime($start));
            $endAt = date('Y-m-d H:i:s', strtotime($end));
            $mode = (string)($chair['usage_mode'] ?? $chair['resource_kind'] ?? 'operatory');
            if (!in_array($mode, chair_resource_clinical_modes(), true) || $chair['status'] !== 'available') throw new RuntimeException('Temporary Dentist sessions require an available treatment operatory.');
            if ($message = chair_session_conflict($pdo,$branchId,$chairId,$dentistId,$startAt,$endAt)) throw new RuntimeException($message);
            $pdo->prepare('INSERT INTO `' . table('chair_session_assignments') . '` (branch_id,chair_id,chair_name,dentist_user_id,assignment_type,starts_at,ends_at,status,reason,created_by,created_at) VALUES (?,?,?,?,"session",?,?,"active",?,?,NOW())')
                ->execute([$branchId,$chairId,$chair['chair_name'],$dentistId,$startAt,$endAt,$reason ?: null,(int)current_user()['id']]);
            chair_resource_record_event($pdo,$chairId,'session_assigned',$reason ?: 'Temporary Dentist-chair session assigned',null,null,$dentistId);
            audit('chair_session_assigned','clinic_chair',$chairId,['dentist_user_id'=>$dentistId,'starts_at'=>$startAt,'ends_at'=>$endAt]);
            flash('success','Temporary Dentist-chair session saved. It overrides the default provider during that time only.');
        } elseif ($action === 'cancel_session') {
            $sessionId = (int)($_POST['session_id'] ?? 0);
            $stmt = $pdo->prepare('SELECT * FROM `' . table('chair_session_assignments') . '` WHERE id=? LIMIT 1');
            $stmt->execute([$sessionId]);
            $session = $stmt->fetch();
            if (!$session) throw new RuntimeException('Session assignment not found.');
            $branchId = (int)$session['branch_id'];
            $pdo->prepare('UPDATE `' . table('chair_session_assignments') . '` SET status="cancelled",updated_at=NOW() WHERE id=?')->execute([$sessionId]);
            chair_resource_record_event($pdo,(int)$session['chair_id'],'session_cancelled','Temporary session cancelled',null,null,(int)($session['dentist_user_id'] ?? 0) ?: null);
            audit('chair_session_cancelled','chair_session',$sessionId,['chair_id'=>(int)$session['chair_id']]);
            flash('success','Temporary chair session cancelled.');
        } elseif ($action === 'move_visit') {
            $queueId = (int)($_POST['queue_entry_id'] ?? 0);
            $targetChairId = (int)($_POST['target_chair_id'] ?? 0);
            $reason = trim((string)($_POST['reason'] ?? ''));
            chair_resource_move_queue_to_chair($pdo,$queueId,$targetChairId,$reason);
            flash('success','Active visit moved to the selected chair.');
        } elseif ($action === 'release_visit') {
            $queueId = (int)($_POST['queue_entry_id'] ?? 0);
            $reason = trim((string)($_POST['reason'] ?? ''));
            chair_resource_release_queue($pdo,$queueId,$reason);
            flash('success','Chair released from the active visit.');
        } elseif ($action === 'bulk_status') {
            $ids = array_values(array_unique(array_filter(array_map('intval',(array)($_POST['chair_ids'] ?? [])))));
            $status = (string)($_POST['bulk_status'] ?? '');
            if (!$ids) throw new RuntimeException('Select at least one chair.');
            if (!in_array($status,['available','maintenance','inactive'],true)) throw new RuntimeException('Select a valid status.');
            $pdo->beginTransaction();
            foreach ($ids as $id) {
                $chair = chair_target($pdo,$id);
                if ((int)$chair['branch_id'] !== $branchId) throw new RuntimeException('A selected chair belongs to another branch.');
                $future = chair_future_appointments($pdo,$branchId,$id,(string)$chair['chair_name']);
                if ($status !== 'available' && $future > 0) throw new RuntimeException($chair['chair_name'] . ' has ' . $future . ' future active appointment(s).');
                $pdo->prepare('UPDATE `' . table('clinic_chairs') . '` SET status=?,updated_at=NOW() WHERE id=?')->execute([$status,$id]);
                chair_resource_record_event($pdo,$id,'status_'.$status,'Bulk status update');
                audit('clinic_chair_bulk_status_updated','clinic_chair',$id,['status'=>$status]);
            }
            $pdo->commit();
            flash('success',count($ids) . ' chair' . (count($ids) === 1 ? '' : 's') . ' updated.');
        } else {
            throw new RuntimeException('Unsupported chair action.');
        }
        header('Location: chairs.php?branch_id=' . $branchId); exit;
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        flash('error',$e->getMessage());
        header('Location: chairs.php?branch_id=' . $branchId); exit;
    }
}

$state = module_management_state();
$q = $state['query'];
$statusFilter = module_safe_status_filter('status',['','available','maintenance','inactive']);
$modeFilter = module_safe_status_filter('mode',array_merge([''], array_keys(chair_resource_usage_labels())));
$chairs = [];
$selectedChair = null;
$total = 0;
$users = $branchId ? chair_user_options($pdo,$branchId) : [];
$activeVisits = $branchId ? chair_active_queue_options($pdo,$branchId) : [];
$occupants = $branchId ? chair_resource_current_occupants($pdo,$branchId) : [];
$occupantsByChair = [];
foreach ($occupants as $occ) $occupantsByChair[(int)($occ['chair_id'] ?? 0)][] = $occ;
$sessions = [];

if ($branchId) {
    $where = ['c.branch_id=?'];
    $args = [$branchId];
    if ($q !== '') {
        $term = module_like_term($q);
        $where[] = '(c.chair_code LIKE ? ESCAPE "\\\\" OR c.chair_name LIKE ? ESCAPE "\\\\" OR c.room_name LIKE ? ESCAPE "\\\\" OR u.name LIKE ? ESCAPE "\\\\" OR su.name LIKE ? ESCAPE "\\\\")';
        array_push($args,$term,$term,$term,$term,$term);
    }
    if ($statusFilter !== '') { $where[] = 'c.status=?'; $args[] = $statusFilter; }
    if ($modeFilter !== '') { $where[] = 'c.usage_mode=?'; $args[] = $modeFilter; }
    $whereSql = implode(' AND ', $where);
    $count = $pdo->prepare('SELECT COUNT(*) FROM `' . table('clinic_chairs') . '` c LEFT JOIN `' . table('doctor_chair_assignments') . '` dca ON dca.chair_id=c.id AND dca.is_active=1 LEFT JOIN `' . table('users') . '` u ON u.id=dca.dentist_user_id LEFT JOIN `' . table('chair_session_assignments') . '` csa ON csa.chair_id=c.id AND csa.status="active" AND csa.starts_at<=NOW() AND csa.ends_at>=NOW() LEFT JOIN `' . table('users') . '` su ON su.id=csa.dentist_user_id WHERE ' . $whereSql);
    $count->execute($args);
    $total = (int)$count->fetchColumn();
    $stmt = $pdo->prepare('SELECT c.*,dca.dentist_user_id,u.name dentist_name,csa.dentist_user_id session_dentist_user_id,su.name session_dentist_name,csa.starts_at session_starts_at,csa.ends_at session_ends_at,(SELECT COUNT(*) FROM `' . table('appointments') . '` a WHERE a.branch_id=c.branch_id AND (a.chair_id=c.id OR (a.chair_id IS NULL AND a.chair_name=c.chair_name)) AND a.start_at>=NOW() AND a.status NOT IN ("cancelled","no_show","completed")) future_appointments FROM `' . table('clinic_chairs') . '` c LEFT JOIN `' . table('doctor_chair_assignments') . '` dca ON dca.chair_id=c.id AND dca.is_active=1 LEFT JOIN `' . table('users') . '` u ON u.id=dca.dentist_user_id LEFT JOIN `' . table('chair_session_assignments') . '` csa ON csa.chair_id=c.id AND csa.status="active" AND csa.starts_at<=NOW() AND csa.ends_at>=NOW() LEFT JOIN `' . table('users') . '` su ON su.id=csa.dentist_user_id WHERE ' . $whereSql . ' ORDER BY c.chair_name LIMIT ' . $state['per_page'] . ' OFFSET ' . $state['offset']);
    $stmt->execute($args);
    $chairs = $stmt->fetchAll();
    $sessionStmt = $pdo->prepare('SELECT csa.*,c.chair_name,u.name dentist_name FROM `' . table('chair_session_assignments') . '` csa JOIN `' . table('clinic_chairs') . '` c ON c.id=csa.chair_id LEFT JOIN `' . table('users') . '` u ON u.id=csa.dentist_user_id WHERE csa.branch_id=? AND csa.status="active" AND csa.ends_at>=NOW() ORDER BY csa.starts_at LIMIT 20');
    $sessionStmt->execute([$branchId]);
    $sessions = $sessionStmt->fetchAll();
    if ($state['manage_id'] > 0) {
        $stmt = $pdo->prepare('SELECT c.*,dca.dentist_user_id,u.name dentist_name,(SELECT COUNT(*) FROM `' . table('appointments') . '` a WHERE a.branch_id=c.branch_id AND (a.chair_id=c.id OR (a.chair_id IS NULL AND a.chair_name=c.chair_name)) AND a.start_at>=NOW() AND a.status NOT IN ("cancelled","no_show","completed")) future_appointments FROM `' . table('clinic_chairs') . '` c LEFT JOIN `' . table('doctor_chair_assignments') . '` dca ON dca.chair_id=c.id AND dca.is_active=1 LEFT JOIN `' . table('users') . '` u ON u.id=dca.dentist_user_id WHERE c.id=? AND c.branch_id=? LIMIT 1');
        $stmt->execute([$state['manage_id'],$branchId]);
        $selectedChair = $stmt->fetch() ?: null;
    }
}

render_header('Chairs & Resources');
?>
<div class="management-workspace chair-resource-workspace">
<section class="role-welcome card"><div><span class="eyebrow">Operatory resource control</span><h2>Chairs &amp; Treatment Resources</h2><p>Chairs are clinic resources. A chair may have an optional default Dentist, a temporary session assignment, and a real-time visit occupant.</p></div><div class="inline-actions"><a class="btn ghost" href="inhouse_team.php?branch_id=<?=$branchId?>">In-house Care Team</a><a class="btn ghost" href="doctor_schedule.php">Doctor Schedule</a><button type="button" class="btn primary" data-open="chair-form">Add Chair / Resource</button></div></section>
<form method="get" class="card management-filters"><label>Search<input type="search" name="q" value="<?=e($q)?>" placeholder="Code, chair, room, or provider"></label><label>Branch<select name="branch_id"><?php foreach($branches as $branch):?><option value="<?=(int)$branch['id']?>" <?=$branchId===(int)$branch['id']?'selected':''?>><?=e((string)$branch['name'])?></option><?php endforeach;?></select></label><label>Status<select name="status"><option value="">All</option><?php foreach(['available','maintenance','inactive'] as $status):?><option value="<?=$status?>" <?=$statusFilter===$status?'selected':''?>><?=e(module_status($status))?></option><?php endforeach;?></select></label><label>Resource type<select name="mode"><option value="">All</option><?php foreach(chair_resource_usage_labels() as $mode=>$label):?><option value="<?=e($mode)?>" <?=$modeFilter===$mode?'selected':''?>><?=e($label)?></option><?php endforeach;?></select></label><div class="filter-actions"><button class="btn primary">Filter</button><a class="btn ghost" href="chairs.php?branch_id=<?=$branchId?>">Reset</a></div></form>
<section class="stats mini-stats"><?php stat_card('Matching resources',$total,'Filtered chairs/resources');stat_card('Occupied now',count($occupants),'Seated or in treatment');stat_card('Temporary sessions',count($sessions),'Upcoming/active');stat_card('Unassigned defaults',count(array_filter($chairs,fn($c)=>in_array((string)$c['usage_mode'],chair_resource_clinical_modes(),true)&&empty($c['dentist_user_id']))),'On this page');?></section>
<section class="card chair-status-board"><div class="card-head"><div><h2>Chair status board</h2><p>Real-time visit occupancy. Move or release a chair without changing the original appointment request.</p></div></div><div class="chair-board-grid"><?php foreach($chairs as $chair): $chairOccupants=$occupantsByChair[(int)$chair['id']]??[];?><article class="chair-board-card <?=$chairOccupants?'occupied':'empty'?>"><div><strong><?=e((string)$chair['chair_name'])?></strong><small><?=e(chair_resource_usage_label((string)$chair['usage_mode']))?> · <?=e(module_status((string)$chair['status']))?></small></div><?php if($chairOccupants): foreach($chairOccupants as $occ):?><div class="chair-occupant"><span><?=e(trim((string)$occ['patient']) ?: 'Patient')?></span><small><?=e((string)$occ['queue_no'])?> · <?=e(module_status((string)$occ['status']))?></small></div><?php endforeach; else:?><span class="badge success">Available</span><?php endif;?></article><?php endforeach;?><?php if(!$chairs):?><div class="queue-empty">No chairs/resources match this view.</div><?php endif;?></div></section>
<form method="post" class="card management-table-card" data-bulk-form><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="bulk_status"><input type="hidden" name="branch_id" value="<?=$branchId?>"><div class="card-head"><div><h2>Chair directory</h2><p>Default provider is only a preference. Actual chair use is recorded on appointment/visit/session.</p></div><?php module_render_list_count($total,'resources');?></div><div class="management-bulk-bar" data-bulk-bar hidden><strong><span data-selected-count>0</span> selected</strong><div class="management-bulk-actions"><select name="bulk_status"><option value="available">Mark available</option><option value="maintenance">Mark maintenance</option><option value="inactive">Mark inactive</option></select><button class="btn ghost" data-requires-selection data-confirm="Apply this status to the selected resources?">Apply status</button></div></div><?php module_render_server_pagination($total,$state['page'],$state['per_page'],'page','per_page','chairs');?><div class="table-wrap"><table><thead><tr><th class="management-checkbox"><input type="checkbox" data-select-all="input[data-row-select]"></th><th>Chair/resource</th><th>Type</th><th>Default provider</th><th>Temporary session now</th><th>Occupancy</th><th>Future appts</th><th>Status</th><th></th></tr></thead><tbody><?php foreach($chairs as $chair): $occCount=count($occupantsByChair[(int)$chair['id']]??[]);?><tr><td class="management-checkbox"><input type="checkbox" name="chair_ids[]" value="<?=(int)$chair['id']?>" data-row-select></td><td><strong><?=e((string)$chair['chair_name'])?></strong><small><?=e((string)$chair['chair_code'])?><?= $chair['room_name']?' · '.e((string)$chair['room_name']):'' ?></small></td><td><?=e(chair_resource_usage_label((string)$chair['usage_mode']))?></td><td><?=e((string)($chair['dentist_name'] ?: 'No default'))?></td><td><?=e((string)($chair['session_dentist_name'] ?: '—'))?><?php if($chair['session_starts_at']):?><small><?=e(date('g:i A',strtotime((string)$chair['session_starts_at'])))?>–<?=e(date('g:i A',strtotime((string)$chair['session_ends_at'])))?></small><?php endif;?></td><td><?=$occCount?'<span class="badge warning">Occupied</span>':'<span class="badge success">Open</span>'?></td><td><?=(int)$chair['future_appointments']?></td><td><span class="badge"><?=e(module_status((string)$chair['status']))?></span></td><td class="management-action-cell"><a class="btn ghost compact" href="<?=e(module_management_url(['manage_id'=>(int)$chair['id']]))?>">Manage</a></td></tr><?php endforeach;?><?php if(!$chairs):?><tr><td colspan="9" class="management-empty">No chairs match this view.</td></tr><?php endif;?></tbody></table></div><?php module_render_server_pagination($total,$state['page'],$state['per_page'],'page','per_page','chairs');?></form>
<section class="card"><div class="card-head"><div><h2>Temporary chair sessions</h2><p>Overrides default provider only for the session window.</p></div></div><div class="table-wrap"><table><thead><tr><th>Time</th><th>Chair</th><th>Dentist</th><th>Reason</th><th></th></tr></thead><tbody><?php foreach($sessions as $session):?><tr><td><?=e(date('M j, g:i A',strtotime((string)$session['starts_at'])))?>–<?=e(date('g:i A',strtotime((string)$session['ends_at'])))?></td><td><?=e((string)$session['chair_name'])?></td><td><?=e((string)($session['dentist_name'] ?: '—'))?></td><td><?=e((string)($session['reason'] ?: 'Session assignment'))?></td><td><form method="post"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="cancel_session"><input type="hidden" name="session_id" value="<?=(int)$session['id']?>"><button class="link-btn" data-confirm="Cancel this temporary chair session?">Cancel</button></form></td></tr><?php endforeach;?><?php if(!$sessions):?><tr><td colspan="5" class="muted">No active or upcoming temporary chair sessions.</td></tr><?php endif;?></tbody></table></div></section>
<?php if($activeVisits):?><section class="card"><h2>Move or release active visit</h2><form method="post" class="form-grid"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="move_visit"><label>Active visit<select name="queue_entry_id" required><option value="">Choose active visit</option><?php foreach($activeVisits as $visit):?><option value="<?=(int)$visit['id']?>"><?=e((string)$visit['queue_no'].' · '.trim((string)$visit['patient']).' · '.($visit['chair_name']?:'No chair').' · '.module_status((string)$visit['status']))?></option><?php endforeach;?></select></label><label>Move to chair<select name="target_chair_id" required><option value="">Choose target chair</option><?php foreach($chairs as $chair): if((string)$chair['status']!=='available')continue;?><option value="<?=(int)$chair['id']?>"><?=e((string)$chair['chair_name'].' · '.chair_resource_usage_label((string)$chair['usage_mode']))?></option><?php endforeach;?></select></label><label class="wide">Reason<input name="reason" required placeholder="Example: Emergency extraction needs surgery room"></label><div class="wide inline-actions"><button class="btn primary">Move active visit</button></div></form><form method="post" class="form-grid"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="release_visit"><label>Release chair from visit<select name="queue_entry_id" required><option value="">Choose active visit</option><?php foreach($activeVisits as $visit): if(!$visit['chair_name'])continue;?><option value="<?=(int)$visit['id']?>"><?=e((string)$visit['queue_no'].' · '.trim((string)$visit['patient']).' · '.$visit['chair_name'])?></option><?php endforeach;?></select></label><label class="wide">Reason<input name="reason" required placeholder="Example: Treatment paused; patient returned to waiting"></label><div class="wide"><button class="btn ghost" data-confirm="Release the chair from this active visit?">Release chair</button></div></form></section><?php endif;?>
<?php if($selectedChair):?><dialog id="manage-chair" class="management-dialog" data-auto-open-dialog="manage-chair"><div class="management-dialog-body"><button type="button" class="dialog-close" data-close>×</button><h2><?=e((string)$selectedChair['chair_name'])?></h2><div class="management-summary"><div><span>Resource type</span><strong><?=e(chair_resource_usage_label((string)$selectedChair['usage_mode']))?></strong></div><div><span>Default Dentist</span><strong><?=e((string)($selectedChair['dentist_name'] ?: 'No default'))?></strong></div><div><span>Future appointments</span><strong><?=(int)$selectedChair['future_appointments']?></strong></div></div><div class="alert info"><strong>Default is not ownership.</strong> The chair remains a clinic resource. Use temporary sessions or visit-level moves for daily operations.</div><form method="post" class="compact-form"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="assign_default"><input type="hidden" name="chair_id" value="<?=(int)$selectedChair['id']?>"><label>Optional default Dentist<select name="dentist_user_id" required><option value="">Choose Dentist</option><?php foreach($users as $u): if($u['role_code']!=='dentist')continue;?><option value="<?=(int)$u['id']?>" <?=(int)($selectedChair['dentist_user_id']??0)===(int)$u['id']?'selected':''?>><?=e((string)$u['name'])?></option><?php endforeach;?></select></label><button class="btn primary" <?=$selectedChair['status']!=='available'?'disabled':''?>>Save default provider</button></form><?php if($selectedChair['dentist_user_id']):?><form method="post"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="unassign_default"><input type="hidden" name="chair_id" value="<?=(int)$selectedChair['id']?>"><button class="btn ghost" data-confirm="Remove this optional default provider? Existing appointments and visits will not change.">Remove default provider</button></form><?php endif;?><hr><form method="post" class="form-grid"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save_session"><input type="hidden" name="chair_id" value="<?=(int)$selectedChair['id']?>"><h3 class="wide">Add temporary session assignment</h3><label>Dentist<select name="dentist_user_id" required><option value="">Choose Dentist</option><?php foreach($users as $u): if($u['role_code']!=='dentist')continue;?><option value="<?=(int)$u['id']?>"><?=e((string)$u['name'])?></option><?php endforeach;?></select></label><label>Starts<input type="datetime-local" name="starts_at" required></label><label>Ends<input type="datetime-local" name="ends_at" required></label><label class="wide">Reason<input name="reason" placeholder="Example: Dr. Cruz uses Chair 2 this afternoon"></label><button class="btn primary wide" <?=$selectedChair['status']!=='available'?'disabled':''?>>Save temporary session</button></form><hr><form method="post" class="form-grid"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save"><input type="hidden" name="id" value="<?=(int)$selectedChair['id']?>"><input type="hidden" name="branch_id" value="<?=$branchId?>"><h3 class="wide">Resource profile</h3><label>Code<input name="chair_code" value="<?=e((string)$selectedChair['chair_code'])?>" required></label><label>Name<input name="chair_name" value="<?=e((string)$selectedChair['chair_name'])?>" required></label><label>Room<input name="room_name" value="<?=e((string)$selectedChair['room_name'])?>"></label><label>Type<select name="usage_mode"><?php foreach(chair_resource_usage_labels() as $mode=>$label):?><option value="<?=e($mode)?>" <?=$selectedChair['usage_mode']===$mode?'selected':''?>><?=e($label)?></option><?php endforeach;?></select></label><label>Status<select name="status"><?php foreach(['available','maintenance','inactive'] as $status):?><option value="<?=$status?>" <?=$selectedChair['status']===$status?'selected':''?>><?=e(module_status($status))?></option><?php endforeach;?></select></label><label class="wide">Notes<textarea name="notes"><?=e((string)$selectedChair['notes'])?></textarea></label><button class="btn primary">Save resource</button><a class="btn ghost" href="<?=e(module_management_url(['manage_id'=>null]))?>">Close</a></form></div></dialog><?php endif;?>
<dialog id="chair-form"><form method="post" class="form-grid"><button type="button" class="dialog-close" data-close>×</button><h2 class="wide">Add chair / resource</h2><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save"><input type="hidden" name="branch_id" value="<?=$branchId?>"><label>Code<input name="chair_code" placeholder="C01" required></label><label>Name<input name="chair_name" placeholder="Chair 1" required></label><label>Room or area<input name="room_name" placeholder="Treatment Room A"></label><label>Type<select name="usage_mode"><?php foreach(chair_resource_usage_labels() as $mode=>$label):?><option value="<?=e($mode)?>" <?=$mode==='operatory'?'selected':''?>><?=e($label)?></option><?php endforeach;?></select></label><label>Status<select name="status"><option value="available">Available</option><option value="maintenance">Maintenance</option><option value="inactive">Inactive</option></select></label><label class="wide">Notes<textarea name="notes"></textarea></label><button class="btn primary">Add resource</button></form></dialog>
</div>
<?php render_footer();
