<?php
require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../includes/functions.php';
startSession(); requireLogin(); requireRole('superadmin','admin','hr','management');
$db   = Database::getInstance();
$page = 'Biometric Upload';

// Handle template download
if (isset($_GET['template'])) {
    header('Content-Type: text/csv; charset=UTF-8');
    header('Content-Disposition: attachment; filename="biometric_template.csv"');
    $out = fopen('php://output','w');
    fputcsv($out,['employee_id','date','in_time','out_time']);
    fputcsv($out,['EMP-0001','2026-06-17','09:05:00','18:10:00']);
    fputcsv($out,['EMP-0002','2026-06-17','08:55:00','17:45:00']);
    fputcsv($out,['EMP-0001','2026-06-18','09:30:00','18:00:00']);
    fclose($out); exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    verifyCsrf();

    if (isset($_FILES['bio_file'])) {
        $file = $_FILES['bio_file'];
        if ($file['error'] !== UPLOAD_ERR_OK) {
            setFlash('error','Upload failed. Please try again.');
            header('Location: biometric_upload.php'); exit;
        }

        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, ['csv','txt'])) {
            setFlash('error','Only CSV or TXT files are supported.');
            header('Location: biometric_upload.php'); exit;
        }

        // Log the upload
        $uploadId = $db->execute(
            "INSERT INTO biometric_uploads (filename,uploaded_by,upload_date,status) VALUES (?,?,CURDATE(),'processing')",
            [$file['name'], currentUser()['id']]
        );
        $uploadId = $db->lastInsertId();

        $handle    = fopen($file['tmp_name'],'r');
        $header    = fgetcsv($handle); // skip header
        $total     = 0;
        $processed = 0;
        $errors    = 0;
        $errorLog  = [];
        $rowNum    = 2;

        // Load policy for grace period
        // FIX (07 Jul 2026): was hardcoded to company_id=1 (every org used
        // GlobalTech's grace period setting). Use the current user's own company.
        $policy     = $db->fetchOne("SELECT * FROM permission_policy WHERE company_id=? LIMIT 1", [companyId()]);
        $graceMin   = $policy['late_grace_minutes'] ?? 15;

        // Cache employee map: emp_code -> id
        // FIX: scope to current org — employee codes are only unique
        // within an organization now, not globally.
        [$empOrgClause, $empOrgParams] = orgScopeClause($db, 'company_id');
        $empMap = [];
        $allEmps = $db->fetchAll("SELECT id, employee_id FROM employees WHERE status='active' AND $empOrgClause", $empOrgParams);
        foreach ($allEmps as $e) $empMap[$e['employee_id']] = $e['id'];

        // Cache shifts: employee_id -> shift in_time
        $shiftMap = [];
        [$shiftOrgClause, $shiftOrgParams] = orgScopeClause($db, 'e.company_id');
        $shiftData = $db->fetchAll("SELECT e.id AS emp_id, s.start_time FROM employees e JOIN shifts s ON s.id=e.shift_id WHERE e.status='active' AND $shiftOrgClause", $shiftOrgParams);
        foreach ($shiftData as $s) $shiftMap[$s['emp_id']] = $s['start_time'];

        while (($cols = fgetcsv($handle)) !== false) {
            if (empty(array_filter($cols))) { $rowNum++; continue; }
            $total++;

            $empCode = trim($cols[0] ?? '');
            $date    = trim($cols[1] ?? '');
            $inTime  = trim($cols[2] ?? '');
            $outTime = trim($cols[3] ?? '') ?: null;

            // Validate
            if (!$empCode || !$date || !$inTime) {
                $errorLog[] = "Row $rowNum: Missing required fields (employee_id, date, in_time)";
                $errors++; $rowNum++; continue;
            }

            $empId = $empMap[$empCode] ?? null;
            if (!$empId) {
                $errorLog[] = "Row $rowNum: Employee '$empCode' not found";
                $errors++; $rowNum++; continue;
            }

            // Parse times
            $inTs  = strtotime("$date $inTime");
            $outTs = $outTime ? strtotime("$date $outTime") : null;

            // Calculate work hours
            $workHours = $outTs ? round(($outTs - $inTs) / 3600, 2) : 0;
            $workHours = max(0, $workHours);

            // Determine if late
            $shiftIn  = $shiftMap[$empId] ?? '09:00:00';
            $shiftTs  = strtotime("$date $shiftIn");
            $lateMin  = max(0, ($inTs - $shiftTs) / 60);
            $isLate   = $lateMin > $graceMin ? 1 : 0;
            $lateMinutes = $isLate ? (int)$lateMin : 0;

            // OT hours (work > 9 hrs standard)
            $otHours = $workHours > 9 ? round($workHours - 9, 2) : 0;

            // Determine status
            $status = 'P';
            if ($workHours > 0 && $workHours < 4.5) $status = 'H';

            try {
                $existing = $db->fetchOne("SELECT id,is_locked FROM muster WHERE employee_id=? AND muster_date=?", [$empId,$date]);
                if ($existing && $existing['is_locked']) {
                    $errorLog[] = "Row $rowNum: $empCode $date is locked — skipped";
                    $errors++; $rowNum++; continue;
                }
                if ($existing) {
                    $db->execute("UPDATE muster SET status=?,in_time=?,out_time=?,work_hours=?,ot_hours=?,is_late=?,late_minutes=?,modified_by=?,remarks='Biometric' WHERE id=?",
                        [$status,$inTime,$outTime,$workHours,$otHours,$isLate,$lateMinutes,currentUser()['id'],$existing['id']]);
                } else {
                    $db->execute("INSERT INTO muster (employee_id,muster_date,status,in_time,out_time,work_hours,ot_hours,is_late,late_minutes,modified_by,remarks) VALUES (?,?,?,?,?,?,?,?,?,?,'Biometric')",
                        [$empId,$date,$status,$inTime,$outTime,$workHours,$otHours,$isLate,$lateMinutes,currentUser()['id']]);
                }
                $processed++;
            } catch (Exception $ex) {
                $errorLog[] = "Row $rowNum: $empCode — ".$ex->getMessage();
                $errors++;
            }
            $rowNum++;
        }
        fclose($handle);

        // Update upload log
        $db->execute("UPDATE biometric_uploads SET total_records=?,processed=?,errors=?,status=?,error_log=? WHERE id=?",
            [$total,$processed,$errors,($errors>0?'completed':'completed'),implode("\n",$errorLog),$uploadId]);

        setFlash('success', "Biometric upload complete. Total: $total | Processed: $processed | Errors: $errors");
        header('Location: biometric_upload.php'); exit;
    }
}

$uploads = $db->fetchAll("SELECT bu.*,u.username FROM biometric_uploads bu LEFT JOIN users u ON u.id=bu.uploaded_by ORDER BY bu.created_at DESC LIMIT 20");

include __DIR__ . '/../../includes/header.php';
?>
<div class="row g-3">
  <div class="col-md-5">
    <div class="pc-card mb-3">
      <div class="pc-card-title"><i class="ti ti-fingerprint me-2"></i>Upload Biometric Data</div>

      <div class="alert alert-info small py-2 mb-3">
        <i class="ti ti-info-circle me-1"></i>
        Upload a CSV file exported from your biometric device. Each row must have employee code, date, in-time, and out-time.
        <br>Late detection uses the shift start time configured for each employee.
      </div>

      <a href="?template=1" class="btn btn-outline-secondary btn-sm w-100 mb-3">
        <i class="ti ti-download me-1"></i>Download CSV Template
      </a>

      <form method="POST" enctype="multipart/form-data">
        <?=csrfField()?>
        <div class="mb-3">
          <label class="pc-label">Select Biometric CSV File</label>
          <input type="file" name="bio_file" class="form-control form-control-sm" accept=".csv,.txt" required>
          <div class="form-text">Supported: CSV / TXT. Max size: <?=ini_get('upload_max_filesize')?>.</div>
        </div>
        <button class="btn btn-pc w-100"><i class="ti ti-upload me-1"></i>Process & Upload</button>
      </form>
    </div>

    <div class="pc-card">
      <div class="pc-card-title"><i class="ti ti-table me-2"></i>CSV Column Format</div>
      <table class="pc-table">
        <thead><tr><th>#</th><th>Column</th><th>Format</th><th>Example</th></tr></thead>
        <tbody>
          <tr><td>1</td><td><code>employee_id</code></td><td>Text</td><td>EMP-0001</td></tr>
          <tr><td>2</td><td><code>date</code></td><td>YYYY-MM-DD</td><td>2026-06-17</td></tr>
          <tr><td>3</td><td><code>in_time</code></td><td>HH:MM:SS</td><td>09:05:00</td></tr>
          <tr><td>4</td><td><code>out_time</code></td><td>HH:MM:SS</td><td>18:10:00</td></tr>
        </tbody>
      </table>
      <div class="small text-muted mt-2">
        <strong>Notes:</strong>
        <ul class="mb-0 ps-3">
          <li>out_time can be left blank (will mark as present with 0 work hours)</li>
          <li>Late detection: if in_time &gt; shift start + grace period</li>
          <li>Half day: if work_hours &lt; 4.5 hrs</li>
          <li>Locked muster records will be skipped</li>
          <li>Existing records for same employee+date will be overwritten</li>
        </ul>
      </div>
    </div>
  </div>

  <div class="col-md-7">
    <div class="pc-card">
      <div class="pc-card-title"><i class="ti ti-history me-2"></i>Upload History</div>
      <div class="pc-table-wrap">
        <table class="pc-table">
          <thead><tr><th>File</th><th>Uploaded By</th><th>Date</th><th>Total</th><th>Processed</th><th>Errors</th><th>Status</th><th>Log</th></tr></thead>
          <tbody>
          <?php foreach ($uploads as $u): ?>
          <tr>
            <td class="fw-semibold" style="max-width:140px;overflow:hidden;text-overflow:ellipsis"><?=clean($u['filename'])?></td>
            <td><?=clean($u['username']??'—')?></td>
            <td><?=fmtDate($u['created_at'])?></td>
            <td><?=$u['total_records']?></td>
            <td class="text-success fw-bold"><?=$u['processed']?></td>
            <td class="<?=$u['errors']>0?'text-danger fw-bold':''?>"><?=$u['errors']?></td>
            <td><?=statusBadge($u['status'])?></td>
            <td>
              <?php if ($u['error_log']): ?>
              <button class="btn btn-xs btn-outline-secondary py-0 px-1"
                onclick="document.getElementById('log_<?=$u['id']?>').classList.toggle('d-none')">
                View
              </button>
              <div id="log_<?=$u['id']?>" class="d-none mt-1 small text-danger" style="white-space:pre-wrap;max-height:100px;overflow-y:auto;background:#fff5f5;padding:4px;border-radius:4px"><?=clean($u['error_log'])?></div>
              <?php else: ?>—<?php endif; ?>
            </td>
          </tr>
          <?php endforeach; ?>
          <?php if (!$uploads): ?><tr><td colspan="8" class="text-center text-muted py-3">No uploads yet</td></tr><?php endif; ?>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>
<?php include __DIR__ . '/../../includes/footer.php'; ?>