<?php
// =============================================================
//  include/account_helpers.php
//
//  Shared by all account create/edit/deactivate flows:
//    add_user.php, add_clinical_student.php, add_rotation_nurse.php,
//    create_staff.php, edit_user.php, edit_staff.php,
//    edit_clinical_student.php, edit_rotation_nurse.php,
//    users.php, manage_staffs.php, manage_rotation_nurses.php,
//    manage_clinical_students.php
// =============================================================

/**
 * Checks email or phone uniqueness across ALL account tables
 * (users, rotation_nurses, clinical_students) — not just the caller's own table.
 *
 * @param mysqli $conn
 * @param string $field         'email' or 'phone'
 * @param string $value
 * @param string|null $excludeTable  table the record being saved belongs to (skip its own row)
 * @param int $excludeId             id to exclude within $excludeTable (0/null when creating)
 * @return array|null  ['table'=>.., 'id'=>.., 'name'=>..] of the conflicting record, or null if none
 */
function checkGlobalDuplicate(mysqli $conn, string $field, string $value, ?string $excludeTable = null, ?int $excludeId = 0, ?array $tables = null): ?array
{
    if (trim($value) === '') return null;
    if (!in_array($field, ['email', 'phone'], true)) return null;

    $tables = $tables ?? ['users', 'rotation_nurses', 'clinical_students'];
    foreach ($tables as $table) {
        $sql = "SELECT id, firstname, surname FROM `$table` WHERE `$field` = ?";
        $types  = 's';
        $params = [$value];
        if ($table === $excludeTable && !empty($excludeId)) {
            $sql   .= ' AND id != ?';
            $types .= 'i';
            $params[] = $excludeId;
        }
        $stmt = $conn->prepare($sql);
        if (!$stmt) continue;
        $stmt->bind_param($types, ...$params);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        if ($row) {
            return [
                'table' => $table,
                'id'    => (int)$row['id'],
                'name'  => trim($row['firstname'] . ' ' . $row['surname']),
            ];
        }
    }
    return null;
}

/**
 * Checks whether $value already exists in $table's $field column, excluding
 * one row (the record being edited, if any). Table-scoped counterpart to
 * checkGlobalDuplicate() — used for fields that are only unique within their
 * own table (username, student_id), not across all three account tables.
 */
function checkTableDuplicate(mysqli $conn, string $table, string $field, string $value, int $excludeId = 0): bool
{
    $stmt = $conn->prepare("SELECT id FROM `$table` WHERE `$field` = ? AND id != ?");
    if (!$stmt) return false;
    $stmt->bind_param('si', $value, $excludeId);
    $stmt->execute();
    $stmt->store_result();
    $found = $stmt->num_rows > 0;
    $stmt->close();
    return $found;
}

/**
 * Validates and saves an uploaded profile photo. Checks BOTH the sniffed MIME
 * type and the file extension against an allow-list — checking MIME alone lets
 * an image/PHP polyglot through if the extension isn't also constrained.
 *
 * @return string|null  the saved filename, or null if no file was uploaded / it failed validation
 */
function handleProfileUpload(string $namePrefix, int $maxBytes = 2 * 1024 * 1024): ?string
{
    if (!isset($_FILES['profile']) || $_FILES['profile']['error'] !== UPLOAD_ERR_OK) return null;

    $mime = @mime_content_type($_FILES['profile']['tmp_name']);
    $size = $_FILES['profile']['size'];
    $ext  = strtolower(pathinfo($_FILES['profile']['name'], PATHINFO_EXTENSION));

    if (!in_array($mime, ['image/jpeg', 'image/png', 'image/gif'], true)) return null;
    if ($size > $maxBytes) return null;
    if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif'], true)) return null;

    $newName = uniqid($namePrefix . '_', true) . '.' . $ext;
    $dir     = __DIR__ . '/../assets/upload/';
    if (!is_dir($dir)) mkdir($dir, 0755, true);

    return move_uploaded_file($_FILES['profile']['tmp_name'], $dir . $newName) ? $newName : null;
}

/**
 * Simple branded HTML wrapper used for every account-notification email.
 *
 * @param string $heading
 * @param string[] $lines  paragraphs/details, rendered in order
 */
function accountEmailTemplate(string $heading, array $lines): string
{
    $body = '';
    foreach ($lines as $line) {
        $body .= '<p style="margin:0 0 12px;color:#1f2937;font-size:14px;line-height:1.6;">' . $line . '</p>';
    }
    return '
    <div style="font-family:Arial,Helvetica,sans-serif;max-width:520px;margin:0 auto;">
        <div style="background:#2566a8;padding:18px 24px;border-radius:8px 8px 0 0;">
            <h1 style="margin:0;color:#fff;font-size:18px;">STH NRMS</h1>
        </div>
        <div style="border:1px solid #e5e7eb;border-top:none;border-radius:0 0 8px 8px;padding:24px;">
            <h2 style="margin:0 0 16px;color:#111827;font-size:16px;">' . htmlspecialchars($heading) . '</h2>
            ' . $body . '
            <p style="margin:20px 0 0;font-size:12px;color:#9ca3af;">This is an automated message from STH NRMS &mdash; ' . htmlspecialchars(preg_replace('#^https?://#', '', env('APP_URL', 'nrms.sthportal.com'))) . '</p>
        </div>
    </div>';
}

/**
 * Fire-and-log an account notification email. Never throws — failures are
 * logged and silently ignored so a mail outage never blocks account operations.
 */
function sendAccountEmail(string $email, string $subject, string $heading, array $lines): bool
{
    if (trim($email) === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
    try {
        require_once __DIR__ . '/../services/EmailServiceProvider.php';
        $svc = new EmailServiceProvider();
        $result = $svc->sendEmail($email, $subject, accountEmailTemplate($heading, $lines));
        if (!$result['success']) {
            error_log('Account email failed to ' . $email . ': ' . $result['message']);
        }
        return $result['success'];
    } catch (Exception $e) {
        error_log('Account email error to ' . $email . ': ' . $e->getMessage());
        return false;
    }
}
