<?php

declare(strict_types=1);
require DENTAL_ROOT . '/app/bootstrap.php';
require_login();
require_documentation_schema();
require_permission('communications.manage',['super_admin','clinic_admin','receptionist','staff','dentist']);
require DENTAL_ROOT . '/app/layout.php';
require DENTAL_ROOT . '/app/module_helpers.php';

$pdo = db();
$canManageCommunications = task_context_action_allowed('communications.manage');
$patientId = (int)($_GET['patient_id'] ?? 0);
$selectedPatient = null;
if ($patientId > 0) {
    $selectedPatient = require_patient($patientId);
    if (!task_patient_scope_allowed($patientId)) access_denied('This patient is outside the active task workspace.');
}

function communication_send_email(PDO $pdo, array $communication): array
{
    $recipient = trim((string)($communication['recipient'] ?? ''));
    if (!filter_var($recipient, FILTER_VALIDATE_EMAIL)) {
        if ((int)($communication['id'] ?? 0) > 0) {
            $pdo->prepare('UPDATE `' . table('communications') . '` SET delivery_status="not_available" WHERE id=?')->execute([(int)$communication['id']]);
        }
        return ['id'=>0,'status'=>'not_available','error'=>'The communication has no valid recipient email address.','attempts'=>0];
    }
    $subject = trim((string)($communication['subject'] ?? '')) ?: 'Message from your dental clinic';
    $summary = trim((string)($communication['summary'] ?? ''));
    $html = '<p>' . nl2br(e($summary)) . '</p>';
    $meta = [
        'type' => 'patient_communication',
        'patient_id' => (int)($communication['patient_id'] ?? 0),
        'appointment_id' => (int)($communication['appointment_id'] ?? 0),
        'communication_id' => (int)$communication['id'],
    ];
    $delivery = queue_mail_message_with_attempt($recipient, $subject, $html, $summary, $meta);
    email_delivery_link_entity((int)($delivery['id'] ?? 0), $meta);
    return $delivery;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        verify_csrf();
        require_task_action('communications.manage');
        $action = (string)($_POST['action'] ?? 'save');

        if ($action === 'retry_email') {
            $communicationId = (int)($_POST['communication_id'] ?? 0);
            $stmt = $pdo->prepare('SELECT * FROM `' . table('communications') . '` WHERE id=? LIMIT 1');
            $stmt->execute([$communicationId]);
            $communication = $stmt->fetch();
            if (!$communication || (string)$communication['channel'] !== 'email' || (string)$communication['direction'] !== 'outbound') {
                throw new RuntimeException('The selected outbound email communication was not found.');
            }
            if ((int)($communication['patient_id'] ?? 0) > 0 && !task_patient_scope_allowed((int)$communication['patient_id'])) {
                throw new RuntimeException('This communication is outside the active task workspace.');
            }
            $outboxId = (int)($communication['email_outbox_id'] ?? 0);
            if ($outboxId > 0) {
                $retryStmt=$pdo->prepare('UPDATE `' . table('email_outbox') . '` SET status="pending",attempts=0,last_error=NULL,available_at=NOW(),updated_at=NOW() WHERE id=? AND status IN ("failed","retry","pending")');
                $retryStmt->execute([$outboxId]);
                if($retryStmt->rowCount()<1)throw new RuntimeException('This email is already accepted or currently being processed. Use a new communication to send another copy.');
                $delivery = (new Dental\Services\EmailService(dental_config(),$pdo))->processMessage($outboxId);
            } else {
                $delivery = communication_send_email($pdo, $communication);
            }
            $feedback = email_delivery_feedback($delivery, 'Communication email');
            audit('communication_email_retried','communication',$communicationId,['outbox_id'=>$delivery['id']??$outboxId,'status'=>$delivery['status']??'unknown']);
            module_return('communications.php'.((int)$communication['patient_id']>0?'?patient_id='.(int)$communication['patient_id']:''),$feedback['type'],$feedback['message']);
        }

        $postedPatientId = (int)($_POST['patient_id'] ?? 0);
        $patient = $postedPatientId ? require_patient($postedPatientId) : null;
        if ($postedPatientId > 0 && !task_patient_scope_allowed($postedPatientId)) {
            throw new RuntimeException('This patient is outside the active task workspace.');
        }
        $channel = (string)($_POST['channel'] ?? 'phone');
        if (!in_array($channel,['phone','email','sms','portal','in_person','other'],true)) $channel = 'phone';
        $direction = (string)($_POST['direction'] ?? 'outbound');
        if (!in_array($direction,['outbound','inbound'],true)) $direction = 'outbound';
        $recipient = trim((string)($_POST['recipient'] ?? ''));
        if ($recipient === '' && $patient) $recipient = $channel === 'email' ? (string)$patient['email'] : (string)$patient['mobile'];
        $summary = trim((string)($_POST['summary'] ?? ''));
        if ($summary === '') throw new RuntimeException('Enter a communication summary.');
        $subject = trim((string)($_POST['subject'] ?? ''));
        $initialStatus = ($channel === 'email' && $direction === 'outbound') ? 'pending' : 'logged';

        $stmt = $pdo->prepare('INSERT INTO `' . table('communications') . '` (patient_id,appointment_id,user_id,channel,direction,recipient,subject,summary,delivery_status,follow_up_needed,communicated_at,created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW())');
        $stmt->execute([
            $postedPatientId ?: null,
            ($_POST['appointment_id'] ?? '') !== '' ? (int)$_POST['appointment_id'] : null,
            (int)current_user()['id'],
            $channel,
            $direction,
            $recipient,
            $subject,
            $summary,
            $initialStatus,
            isset($_POST['follow_up_needed']) ? 1 : 0,
            normalize_date_time_local($_POST['communicated_at'] ?? '') ?: date('Y-m-d H:i:s'),
        ]);
        $communicationId = (int)$pdo->lastInsertId();
        audit('communication_logged','communication',$communicationId,['patient_id'=>$postedPatientId,'channel'=>$channel,'direction'=>$direction]);

        if ($channel === 'email' && $direction === 'outbound') {
            $communication = [
                'id'=>$communicationId,'patient_id'=>$postedPatientId,
                'appointment_id'=>(int)($_POST['appointment_id'] ?? 0),
                'recipient'=>$recipient,'subject'=>$subject,'summary'=>$summary,
            ];
            try {
                $delivery = communication_send_email($pdo,$communication);
            } catch (Throwable $mailException) {
                $delivery = ['id'=>0,'status'=>'failed','error'=>$mailException->getMessage(),'attempts'=>0];
                $pdo->prepare('UPDATE `' . table('communications') . '` SET delivery_status="failed" WHERE id=?')->execute([$communicationId]);
            }
            $feedback = email_delivery_feedback($delivery,'Communication email');
            module_return('communications.php'.($postedPatientId?'?patient_id='.$postedPatientId:''),$feedback['type'],'Communication logged. '.$feedback['message']);
        }

        module_return('communications.php'.($postedPatientId?'?patient_id='.$postedPatientId:''),'success','Communication logged.');
    } catch (Throwable $exception) {
        module_return('communications.php'.($patientId?'?patient_id='.$patientId:''),'error',$exception->getMessage());
    }
}

$q = trim((string)($_GET['q'] ?? ''));
$channelFilter = trim((string)($_GET['channel'] ?? ''));
if (!in_array($channelFilter,['phone','email','sms','portal','in_person','other'],true)) $channelFilter = '';
$page = module_page_number();
$perPage = module_page_size('per_page',25);
$emailTrackingReady = schema_column_exists(table('communications'),'email_outbox_id');
$from = ' FROM `' . table('communications') . '` c LEFT JOIN `' . table('patients') . '` p ON p.id=c.patient_id LEFT JOIN `' . table('users') . '` u ON u.id=c.user_id';
if ($emailTrackingReady) $from .= ' LEFT JOIN `' . table('email_outbox') . '` eo ON eo.id=c.email_outbox_id';
$where = ' WHERE 1=1';
$args = [];
if ($patientId) { $where .= ' AND c.patient_id=?'; $args[] = $patientId; }
if ($channelFilter !== '') { $where .= ' AND c.channel=?'; $args[] = $channelFilter; }
if ($q !== '') {
    $like = '%'.$q.'%';
    $where .= ' AND (p.patient_no LIKE ? OR p.first_name LIKE ? OR p.last_name LIKE ? OR c.recipient LIKE ? OR c.subject LIKE ? OR c.summary LIKE ?)';
    array_push($args,$like,$like,$like,$like,$like,$like);
}
[$scopeSql,$scopeArgs] = task_patient_scope_condition('c.patient_id');
$where .= $scopeSql;
$args = array_merge($args,$scopeArgs);
$countStmt = $pdo->prepare('SELECT COUNT(*)'.$from.$where);
$countStmt->execute($args);
$total = (int)$countStmt->fetchColumn();
$pages = max(1,(int)ceil($total/$perPage));
$page = min($page,$pages);
$offset = ($page-1)*$perPage;
$emailSelect = $emailTrackingReady
    ? ',eo.status outbox_status,eo.last_error outbox_error,eo.sent_at outbox_sent_at,eo.attempts outbox_attempts'
    : ',NULL outbox_status,NULL outbox_error,NULL outbox_sent_at,NULL outbox_attempts';
$stmt = $pdo->prepare('SELECT c.*,CONCAT(p.first_name," ",p.last_name) patient,p.patient_no,u.name staff'.$emailSelect.$from.$where.' ORDER BY c.communicated_at DESC,c.id DESC LIMIT '.$perPage.' OFFSET '.$offset);
$stmt->execute($args);
$rows = $stmt->fetchAll();

render_header('Communications');
render_module_intro('Patient communication log','Record calls, messages, portal contact, email delivery, and follow-up requirements.',$canManageCommunications?'Log communication':null,$canManageCommunications?'communication-form':null);
?>
<form method="get" class="card compact-filter" data-auto-submit><?php if($patientId):?><input type="hidden" name="patient_id" value="<?=$patientId?>"><?php endif;?><label>Search<input type="search" name="q" value="<?=e($q)?>" placeholder="Patient, recipient, subject, or summary" data-auto-search data-min-length="2"></label><label>Channel<select name="channel"><option value="">All channels</option><?php foreach(['phone','email','sms','portal','in_person','other'] as $channel):?><option value="<?=e($channel)?>" <?=$channelFilter===$channel?'selected':''?>><?=e(module_status($channel))?></option><?php endforeach;?></select></label><?php if($patientId||$q!==''||$channelFilter!==''):?><a class="btn link" href="communications.php">Clear</a><?php endif;?></form>
<div class="card server-list-card"><?php module_render_server_pagination($total,$page,$perPage,'page','per_page','communications');?><div class="table-wrap" data-no-pagination><table data-no-pagination="true"><thead><tr><th>Date</th><th>Patient</th><th>Channel</th><th>Direction</th><th>Recipient</th><th>Summary</th><th>Staff</th><th>Status</th><th></th></tr></thead><tbody>
<?php foreach($rows as $row):$deliveryStatus=(string)($row['outbox_status']?:$row['delivery_status']?:'logged');?><tr>
<td><?=e(date('M j, Y g:i A',strtotime((string)$row['communicated_at'])))?></td>
<td><?=e($row['patient']?:'General')?><?php if($row['patient_no']):?><small><?=e((string)$row['patient_no'])?></small><?php endif;?></td>
<td><?=e(module_status((string)$row['channel']))?></td><td><?=e(module_status((string)$row['direction']))?></td><td><?=e((string)$row['recipient'])?></td>
<td><strong><?=e((string)$row['subject'])?></strong><small><?=e((string)$row['summary'])?></small><?php if($row['follow_up_needed']):?><span class="badge">Follow-up needed</span><?php endif;?></td>
<td><?=e($row['staff']?:'System')?></td>
<td><span class="badge <?=e(email_delivery_badge_class($deliveryStatus))?>"><?=e((string)$row['channel']==='email'&&$row['direction']==='outbound'?email_delivery_label($deliveryStatus):module_status($deliveryStatus))?></span><?php if($row['outbox_error']):?><small title="<?=e((string)$row['outbox_error'])?>"><?=e((string)$row['outbox_error'])?></small><?php elseif($row['outbox_sent_at']):?><small><?=e(date('M j, g:i A',strtotime((string)$row['outbox_sent_at'])))?></small><?php endif;?></td>
<td><?php if($canManageCommunications&&(string)$row['channel']==='email'&&(string)$row['direction']==='outbound'&&in_array($deliveryStatus,['failed','retry','pending'],true)):?><form method="post"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="retry_email"><input type="hidden" name="communication_id" value="<?=(int)$row['id']?>"><button class="link-btn" type="submit">Retry now</button></form><?php endif;?></td>
</tr><?php endforeach;?><?php if(!$rows):?><tr><td colspan="9">No communication records match this view.</td></tr><?php endif;?></tbody></table></div><?php module_render_server_pagination($total,$page,$perPage,'page','per_page','communications');?></div>
<?php if($canManageCommunications):?><dialog id="communication-form" class="wide-dialog"><form method="post" class="form-grid"><button type="button" class="dialog-close" data-close>×</button><h2 class="wide">Log communication</h2><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save"><label class="wide">Patient<?php module_remote_patient_picker('patient_id',$selectedPatient,false);?></label><label>Appointment ID<input type="number" name="appointment_id"></label><label>Channel<select name="channel"><option value="phone">Phone</option><option value="email">Email</option><option value="sms">SMS</option><option value="portal">Patient portal</option><option value="in_person">In person</option><option value="other">Other</option></select></label><label>Direction<select name="direction"><option value="outbound">Outbound</option><option value="inbound">Inbound</option></select></label><label>Recipient<input name="recipient" placeholder="Uses patient email/mobile when blank"></label><label>Date and time<input type="datetime-local" name="communicated_at" value="<?=e(date('Y-m-d\TH:i'))?>"></label><label class="wide">Subject<input name="subject"></label><label class="wide">Summary<textarea name="summary" required></textarea></label><label class="check-option wide"><input type="checkbox" name="follow_up_needed"><span>Follow-up is required</span></label><button class="btn primary">Save communication</button></form></dialog><?php endif;?>
<?php render_footer(); ?>
