<?php
declare(strict_types=1);

/**
 * modules/payroll/staff/advance.php
 * Record a salary advance for a staff member.
 *
 * Flow:
 *  - Step 1 (no staff_id): show a dropdown to pick staff, then continue.
 *  - Step 2 (with staff_id): show advance form, save to staff_advances + transactions.
 *
 * Writes:
 *  - staff_advances (company_id, staff_id, amount, paid_at, method, reference, notes, created_at)
 *  - transactions   (account_code='STAFF_ADVANCE', type='expense',
 *                    segment=<Rent|Chauffeur>, booking_id=NULL, reference, notes, created_at)
 *
 * Visible to: MD, Accounts, Admin
 */

require_once dirname(__DIR__, 3) . '/config/functions.php';
require_role(['MD','Accounts','Admin']);

$user = current_user();
$cid  = (int)($user['company_id'] ?? 0);
if ($cid <= 0) redirect(url_public('login.php'));

$errors = [];
$notice = null;

/** Helpers */
function segment_for_staff(?string $department): string {
  // Map strictly to enum values in transactions.segment
  return (strtolower((string)$department) === 'rent') ? 'Rent' : 'Chauffeur';
}
function safe_anchor(int $year, int $month, int $day): DateTimeImmutable {
  // Build a YYYY-mm-<salary_day or last day> safely
  $base = new DateTimeImmutable(sprintf('%04d-%02d-01', $year, $month));
  $last = (int)$base->format('t');
  $d    = max(1, min($day, $last));
  return new DateTimeImmutable(sprintf('%04d-%02d-%02d', $year, $month, $d));
}

/** Common request vars */
$staffId   = (int)($_GET['staff_id'] ?? $_POST['staff_id'] ?? 0);
$returnUrl = (string)($_GET['return'] ?? $_POST['return'] ?? url_modules('payroll/staff/list.php'));

/** If the first form posts a staff selection, use it */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'select_staff') {
  $staffId = (int)($_POST['staff_id'] ?? 0);
}

/** Load active staff list for dropdown (Step 1) */
$staffList = [];
try {
  $q = db()->prepare("
    SELECT id, full_name, department
      FROM staff_members
     WHERE company_id = :cid
       AND is_active = 1
     ORDER BY full_name ASC
  ");
  $q->execute([':cid' => $cid]);
  $staffList = $q->fetchAll() ?: [];
} catch (Throwable $e) {
  $errors[] = (defined('APP_ENV') && APP_ENV==='dev') ? $e->getMessage() : 'Unable to load staff list.';
}

/** If we have a staff_id, load the staff row (Step 2) */
$staff     = null;
$staffName = '—';
$department = 'Chauffeur';
$salaryDay  = 25;

if ($staffId > 0) {
  try {
    $s = db()->prepare("
      SELECT id, company_id, full_name, department, salary_day
        FROM staff_members
       WHERE id = :id AND company_id = :cid
       LIMIT 1
    ");
    $s->execute([':id'=>$staffId, ':cid'=>$cid]);
    $staff = $s->fetch() ?: null;

    if ($staff) {
      $staffName  = (string)$staff['full_name'];
      $department = (string)($staff['department'] ?? 'Chauffeur');
      $salaryDay  = (int)($staff['salary_day'] ?? 25);
      if ($salaryDay <= 0 || $salaryDay > 31) $salaryDay = 25;
    } else {
      $errors[] = 'Staff not found or access denied.';
    }
  } catch (Throwable $e) {
    $errors[] = (defined('APP_ENV') && APP_ENV==='dev') ? $e->getMessage() : 'Unable to load staff.';
  }
}

/** Figure paid_at default and the friendly anchor (for reference label) */
$paidAtInput = $_POST['paid_at'] ?? date('Y-m-d\TH:i');
$paidAtObj   = new DateTimeImmutable(str_replace(' ', 'T', $paidAtInput));
$y = (int)$paidAtObj->format('Y');
$m = (int)$paidAtObj->format('m');
$anchorCur      = safe_anchor($y, $m, $salaryDay);
$payMonthLabel  = $anchorCur->format('Y-m'); // e.g. "2025-10"

/** Handle save */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'save' && $staff && !$errors) {
  try {
    csrf_verify((string)($_POST['csrf'] ?? ''));

    $amount  = to_dec($_POST['amount'] ?? 0);
    $paidAt  = trim((string)($_POST['paid_at'] ?? ''));
    $method  = trim((string)($_POST['method'] ?? 'Bank Transfer'));
    $ref     = trim((string)($_POST['reference'] ?? ''));
    $notes   = trim((string)($_POST['notes'] ?? ''));

    if ($amount <= 0) throw new RuntimeException('Amount must be positive.');
    if ($paidAt === '') $paidAt = date('Y-m-d H:i:s');

    $pdo = db();
    $pdo->beginTransaction();

    // 1) staff_advances
    $ins = $pdo->prepare("
      INSERT INTO staff_advances
        (company_id, staff_id, amount, paid_at, method, reference, notes, created_at)
      VALUES
        (:cid, :sid, :amt, :paid_at, :method, :ref, :notes, NOW())
    ");
    $ins->execute([
      ':cid'=>$cid, ':sid'=>$staffId, ':amt'=>$amount,
      ':paid_at'=>$paidAt,
      ':method'=>$method !== '' ? $method : null,
      ':ref'=>$ref !== '' ? $ref : null,
      ':notes'=>$notes !== '' ? $notes : null,
    ]);

    // 2) transactions with segment derived from department (NEVER NULL)
    $segment = segment_for_staff($department);
    $tx = $pdo->prepare("
      INSERT INTO transactions
        (company_id, date, account_code, segment, type, amount, booking_id, rental_id, invoice_id, reference, milestone, notes, attachment_url, created_at)
      VALUES
        (:cid, DATE(:paid_at), 'STAFF_ADVANCE', :segment, 'expense', :amt, NULL, NULL, NULL, :ref, NULL, :notes, NULL, NOW())
    ");
    $tx->execute([
      ':cid'     => $cid,
      ':paid_at' => $paidAt,
      ':segment' => $segment, // 'Rent' or 'Chauffeur'
      ':amt'     => $amount,
      ':ref'     => $ref !== '' ? $ref : ('Salary Advance — '.$staffName.' — '.$payMonthLabel),
      ':notes'   => $notes !== '' ? $notes : null,
    ]);

    audit_log('payroll.advance.create','staff',(int)$staffId,[
      'amount'=>$amount,'paid_at'=>$paidAt,'segment'=>$segment,'method'=>$method,'reference'=>$ref
    ]);

    $pdo->commit();
    $redir = $returnUrl . (str_contains($returnUrl,'?') ? '&' : '?') . 'ok=1';
    redirect($redir);

  } catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    $errors[] = (defined('APP_ENV') && APP_ENV==='dev') ? $e->getMessage() : 'Unable to save advance.';
  }
}

/** Render */
include dirname(__DIR__, 3) . '/includes/header.php';
?>
<div class="d-flex justify-content-between align-items-center mb-3">
  <div>
    <h1 class="h4 mb-0">Record Salary Advance</h1>
    <?php if ($staff): ?>
      <div class="text-muted">Staff: <?= e($staffName) ?> · Department: <?= e($department) ?></div>
    <?php else: ?>
      <div class="text-muted">Choose a staff member to continue.</div>
    <?php endif; ?>
  </div>
  <div>
    <a class="btn btn-outline-secondary" href="<?= e($returnUrl) ?>">← Back</a>
  </div>
</div>

<?php if ($errors): ?>
  <div class="alert alert-danger"><ul class="mb-0"><?php foreach ($errors as $er) echo '<li>'.e($er).'</li>'; ?></ul></div>
<?php endif; ?>

<?php if (!$staff): ?>
  <!-- Step 1: Pick staff -->
  <div class="card shadow-sm">
    <form method="post" class="card-body row g-3">
      <input type="hidden" name="csrf" value="<?= e(csrf_token()) ?>">
      <input type="hidden" name="action" value="select_staff">
      <input type="hidden" name="return" value="<?= e($returnUrl) ?>">

      <div class="col-md-8">
        <label class="form-label">Staff Member</label>
        <select name="staff_id" class="form-select" required>
          <option value="">— Select staff —</option>
          <?php foreach ($staffList as $st): ?>
            <option value="<?= (int)$st['id'] ?>">
              <?= e($st['full_name'].' ('.$st['department'].')') ?>
            </option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="col-md-4 d-flex align-items-end">
        <button class="btn btn-dark w-100">Continue</button>
      </div>
    </form>
  </div>

<?php else: ?>
  <!-- Step 2: Advance form -->
  <form method="post" class="row g-3">
    <input type="hidden" name="csrf" value="<?= e(csrf_token()) ?>">
    <input type="hidden" name="action" value="save">
    <input type="hidden" name="staff_id" value="<?= (int)$staffId ?>">
    <input type="hidden" name="return" value="<?= e($returnUrl) ?>">

    <div class="col-md-4">
      <label class="form-label">Amount (£)</label>
      <input type="number" step="0.01" min="0.01" required class="form-control" name="amount">
    </div>
    <div class="col-md-4">
      <label class="form-label">Paid At</label>
      <input type="datetime-local" class="form-control" name="paid_at" value="<?= e($paidAtObj->format('Y-m-d\TH:i')) ?>">
    </div>
    <div class="col-md-4">
      <label class="form-label">Method</label>
      <input class="form-control" name="method" value="Bank Transfer">
    </div>
    <div class="col-md-6">
      <label class="form-label">Reference</label>
      <input class="form-control" name="reference" placeholder="Txn / note"
             value="<?= e('Salary Advance — '.$staffName.' — '.$payMonthLabel) ?>">
    </div>
    <div class="col-md-6">
      <label class="form-label">Notes</label>
      <input class="form-control" name="notes" placeholder="Optional">
    </div>

    <div class="col-12 d-flex gap-2">
      <button class="btn btn-dark">Save Advance</button>
      <a class="btn btn-outline-secondary" href="<?= e($returnUrl) ?>">Cancel</a>
    </div>
  </form>
<?php endif; ?>

<?php include dirname(__DIR__, 3) . '/includes/footer.php'; ?>
