<?php
// =============================================================
//  POST /api/v1/credentials/save
//
//  Create or update a credential record — mirrors
//  app/manage_credentials.php's own action=save handler exactly,
//  including the reminder-reset-on-renewal rule: editing a credential
//  only clears reminder_sent when the expiry_date actually changed, so
//  touching an unrelated field (e.g. a typo in notes) doesn't spuriously
//  re-arm an already-sent expiry reminder.
//
//  Body (create): { owner_table, owner_id, credential_type,
//                    credential_number?, issued_date?, expiry_date, notes? }
//  Body (update): same, plus { id }
// =============================================================

require_once __DIR__ . '/../_bootstrap.php';
require_once __DIR__ . '/../../../include/CredentialHelpers.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    Api::error(405, 'MethodNotAllowed', 'Use POST');
}

$account = api_authenticate();
api_require_permission('edit_user');

if (!$conn->query("SHOW TABLES LIKE 'credentials'")->num_rows) {
    Api::error(409, 'CredentialsTableMissing', 'Credential tracking is not set up on this server yet.');
}

$OWNER_TABLES = ['users', 'rotation_nurses', 'clinical_students'];

$body             = Api::body();
$id               = (int)($body['id'] ?? 0);
$ownerTable       = (string)($body['owner_table'] ?? '');
$ownerId          = (int)($body['owner_id'] ?? 0);
$credentialType   = trim((string)($body['credential_type'] ?? ''));
$credentialNumber = trim((string)($body['credential_number'] ?? '')) ?: null;
$issuedDate       = trim((string)($body['issued_date'] ?? '')) ?: null;
$expiryDate       = trim((string)($body['expiry_date'] ?? ''));
$notes            = trim((string)($body['notes'] ?? '')) ?: null;

if (!in_array($ownerTable, $OWNER_TABLES, true)) Api::error(422, 'ValidationError', 'Invalid account type');
if ($ownerId <= 0) Api::error(422, 'ValidationError', 'Please select a person');
if ($credentialType === '') Api::error(422, 'ValidationError', 'Credential type is required');
if (!isValidDate($expiryDate)) Api::error(422, 'ValidationError', 'A valid expiry date is required');
if ($issuedDate && !isValidDate($issuedDate)) Api::error(422, 'ValidationError', 'Issued date is not a valid date');

$accountRepo = new AccountRepository($conn);
if (!$accountRepo->findById($ownerTable, $ownerId)) {
    Api::error(404, 'NotFound', 'Selected person not found');
}

if ($id) {
    $prevStmt = $conn->prepare('SELECT expiry_date, reminder_sent FROM credentials WHERE id = ?');
    $prevStmt->bind_param('i', $id);
    $prevStmt->execute();
    $prevRow = $prevStmt->get_result()->fetch_assoc();
    $prevStmt->close();
    if (!$prevRow) Api::error(404, 'NotFound', 'Credential not found');

    $reminderSent = ($prevRow['expiry_date'] !== $expiryDate) ? 0 : (int)$prevRow['reminder_sent'];

    $types = 'sisssssii';
    $vals  = [$ownerTable, $ownerId, $credentialType, $credentialNumber, $issuedDate, $expiryDate, $notes, $reminderSent, $id];
    if (strlen($types) !== count($vals)) {
        error_log('credentials/save.php update: type string length (' . strlen($types) . ') != value count (' . count($vals) . ')');
        Api::error(500, 'ServerError', 'Internal error preparing the credential record.');
    }
    $stmt = $conn->prepare("
        UPDATE credentials
        SET owner_table = ?, owner_id = ?, credential_type = ?, credential_number = ?,
            issued_date = ?, expiry_date = ?, notes = ?, reminder_sent = ?
        WHERE id = ?
    ");
    $stmt->bind_param($types, $ownerTable, $ownerId, $credentialType, $credentialNumber,
        $issuedDate, $expiryDate, $notes, $reminderSent, $id);
    $stmt->execute();
    $stmt->close();

    $permManager = new PermissionManager($conn);
    $permManager->logAudit($account->getId(), 'update_credential', 'credential', $id, null, json_encode(['owner_table' => $ownerTable, 'owner_id' => $ownerId]));

    Api::success(['id' => $id, 'action' => 'updated']);
} else {
    $createdBy = $account->getId();
    $insertTypes = 'sisssssi';
    $insertVals  = [$ownerTable, $ownerId, $credentialType, $credentialNumber, $issuedDate, $expiryDate, $notes, $createdBy];
    if (strlen($insertTypes) !== count($insertVals)) {
        error_log('credentials/save.php insert: type string length (' . strlen($insertTypes) . ') != value count (' . count($insertVals) . ')');
        Api::error(500, 'ServerError', 'Internal error preparing the credential record.');
    }
    $stmt = $conn->prepare("
        INSERT INTO credentials (owner_table, owner_id, credential_type, credential_number, issued_date, expiry_date, notes, created_by)
        VALUES (?,?,?,?,?,?,?,?)
    ");
    $stmt->bind_param($insertTypes, $ownerTable, $ownerId, $credentialType, $credentialNumber,
        $issuedDate, $expiryDate, $notes, $createdBy);
    $stmt->execute();
    $newId = $stmt->insert_id;
    $stmt->close();

    $permManager = new PermissionManager($conn);
    $permManager->logAudit($account->getId(), 'create_credential', 'credential', $newId, null, json_encode(['owner_table' => $ownerTable, 'owner_id' => $ownerId]));

    Api::success(['id' => $newId, 'action' => 'created']);
}
