<?php
/* ============================================================================
 *  staff/checkin.php — DingTalk-style 4-punch split shift with selfies.
 *  Morning in/out + afternoon in/out. Every punch requires a camera selfie
 *  (front camera only, compressed). Per-session late capture, GPS geofence.
 *  Legacy check_in / check_out / late_minutes / hours_worked are maintained
 *  so payroll keeps working. Bilingual EN/Lao.
 * ==========================================================================*/
session_start();

if (!isset($_SESSION["user_id"]) || empty($_SESSION["company_id"])) {
    header("Location: ../auth/login.php");
    exit;
}

require_once '../config/database.php';
require_once '../config/notify.php';
require_once '../config/approvals.php';
date_default_timezone_set('Asia/Vientiane');

$userId    = (int)$_SESSION["user_id"];
$companyId = (int)$_SESSION["company_id"];
$today     = date('Y-m-d');
$iso       = (int)date('N');

/* ── Context: flags, branch, today's AM/PM schedule ── */
function loadContext($pdo, $companyId, $userId, $iso) {
    $ctx = ['checkin_required'=>1,'geofence_required'=>1,'branch'=>null,
            'sched'=>null,'grace'=>5,'ot_after'=>0,'min_ot'=>30];

    $st = $pdo->prepare("SELECT * FROM att_staff WHERE company_id=? AND staff_id=? LIMIT 1");
    $st->execute([$companyId, $userId]);
    $as = $st->fetch(PDO::FETCH_ASSOC);

    $st = $pdo->prepare("SELECT geofence_default, min_ot_minutes, extra FROM att_rules WHERE company_id=? LIMIT 1");
    $st->execute([$companyId]);
    $rules = $st->fetch(PDO::FETCH_ASSOC) ?: [];
    $ctx['min_ot'] = (int)($rules['min_ot_minutes'] ?? 30);

    $schedule = [];
    if (!empty($rules['extra'])) {
        $ex = json_decode($rules['extra'], true);
        if (is_array($ex)) {
            if (!empty($ex['schedule']) && is_array($ex['schedule'])) {
                foreach ($ex['schedule'] as $k=>$v) $schedule[(int)$k] = $v;
            }
            if (isset($ex['grace']))    $ctx['grace']    = (int)$ex['grace'];
            if (isset($ex['ot_after'])) $ctx['ot_after'] = (int)$ex['ot_after'];
        }
    }
    $ctx['sched'] = $schedule[$iso] ?? null;

    if ($as) {
        $ctx['checkin_required']  = (int)$as['checkin_required'];
        $ctx['geofence_required'] = (int)$as['geofence_required'];
        $branchId = $as['default_branch_id'];
    } else {
        $ctx['geofence_required'] = (int)($rules['geofence_default'] ?? 1);
        $branchId = null;
    }
    /* today's roster branch override */
    $st = $pdo->prepare("SELECT branch_id FROM att_roster WHERE company_id=? AND staff_id=? AND work_date=CURDATE() LIMIT 1");
    $st->execute([$companyId, $userId]);
    if ($r = $st->fetch(PDO::FETCH_ASSOC)) { if ($r['branch_id'] !== null) $branchId = $r['branch_id']; }

    if ($branchId) {
        $st = $pdo->prepare("SELECT * FROM att_branches WHERE id=? AND company_id=? LIMIT 1");
        $st->execute([$branchId, $companyId]);
        $ctx['branch'] = $st->fetch(PDO::FETCH_ASSOC) ?: null;
    }
    return $ctx;
}

function haversine($lat1,$lng1,$lat2,$lng2){
    $R=6371000; $dLat=deg2rad($lat2-$lat1); $dLng=deg2rad($lng2-$lng1);
    $a=sin($dLat/2)**2 + cos(deg2rad($lat1))*cos(deg2rad($lat2))*sin($dLng/2)**2;
    return $R*2*atan2(sqrt($a),sqrt(1-$a));
}
function lateMins($schedHM,$grace,$nowHMS){
    if (!$schedHM) return 0;
    $g = strtotime($schedHM) + $grace*60;
    $diff = strtotime($nowHMS) - $g;
    return $diff > 0 ? (int)floor($diff/60) : 0;
}

$ctx   = loadContext($pdo, $companyId, $userId, $iso);
$sched = $ctx['sched'];

/* build today's ordered punch list */
$punches = [];
if ($sched) {
    $amS = $sched['am_start'] ?? ($sched['start'] ?? null);
    $amE = $sched['am_end']   ?? null;
    $pmS = $sched['pm_start'] ?? null;
    $pmE = $sched['pm_end']   ?? ($sched['end'] ?? null);
    if ($amS) {
        $punches['am_in']  = ['type'=>'in', 'sched'=>$amS, 'en'=>'Morning In',    'lo'=>'ເຂົ້າ ເຊົ້າ'];
        $punches['am_out'] = ['type'=>'out','sched'=>$amE, 'en'=>'Morning Out',   'lo'=>'ອອກ ເຊົ້າ'];
    }
    if ($pmS && $pmE) {
        $punches['pm_in']  = ['type'=>'in', 'sched'=>$pmS, 'en'=>'Afternoon In',  'lo'=>'ເຂົ້າ ບ່າຍ'];
        $punches['pm_out'] = ['type'=>'out','sched'=>$pmE, 'en'=>'Afternoon Out', 'lo'=>'ອອກ ບ່າຍ'];
    }
}

function todayRow($pdo,$companyId,$userId,$today){
    $st = $pdo->prepare("SELECT * FROM hr_attendance WHERE staff_id=? AND company_id=? AND work_date=? LIMIT 1");
    $st->execute([$userId,$companyId,$today]);
    return $st->fetch(PDO::FETCH_ASSOC) ?: null;
}

/* ════════ AJAX: a punch ════════ */
if ($_SERVER["REQUEST_METHOD"] === "POST" && ($_POST['action'] ?? '') === 'punch') {
    header('Content-Type: application/json; charset=utf-8');
    $now = date('H:i:s');
    try {
        if (!$ctx['checkin_required']) throw new Exception("You are exempt from check-in.");
        $punch = $_POST['punch'] ?? '';
        if (!isset($punches[$punch])) throw new Exception("That punch is not scheduled today.");

        $row = todayRow($pdo,$companyId,$userId,$today);
        if ($row && !empty($row[$punch])) throw new Exception("Already recorded at ".substr($row[$punch],0,5).".");

        /* selfie required */
        $photo = $_POST['photo'] ?? '';
        if (strpos($photo,'data:image/jpeg;base64,') !== 0) throw new Exception("A selfie photo is required.");
        $bin = base64_decode(substr($photo, strpos($photo,',')+1));
        if ($bin === false || strlen($bin) < 500)  throw new Exception("Photo capture failed, please retake.");
        if (strlen($bin) > 1500000) throw new Exception("Photo too large.");

        $lat = ($_POST['lat'] ?? '') !== '' ? (float)$_POST['lat'] : null;
        $lng = ($_POST['lng'] ?? '') !== '' ? (float)$_POST['lng'] : null;

        /* Location: never block. Always allow the punch, capture GPS, and just
           flag whether the person was off-site (outside the branch radius). */
        $branch=$ctx['branch']; $offsite=0; $canGeo=false;
        if ($branch && $branch['lat']!==null && $branch['lng']!==null && $lat!==null && $lng!==null) {
            $canGeo=true;
            $dist=haversine((float)$branch['lat'],(float)$branch['lng'],$lat,$lng);
            $offsite = ($dist > (int)$branch['radius_m']) ? 1 : 0;   // outside office = off-site
        } else {
            $offsite = 1;   // no branch set, or no GPS captured -> treat as off-site
        }

        /* Off-site punch must include a reason. Only enforced when geofence is
           required for this staff and we could actually verify the location. */
        $reason = trim($_POST['reason'] ?? '');
        $reallyOffsite = ($ctx['geofence_required'] && $canGeo && $offsite);
        if ($reallyOffsite && $reason === '') {
            echo json_encode([
                'ok'=>false, 'need_reason'=>true,
                'msg_en'=>'You are off-site. Please write a reason for this punch.',
                'msg_lo'=>'ທ່ານຢູ່ນອກສະຖານທີ່ກຳນົດ. ກະລຸນາຂຽນເຫດຜົນ.'
            ]);
            exit;
        }

        /* place label — on-site shows the office/branch name; otherwise "Off-site".
           (No external map lookup, so there is no cost.) */
        $place = (!$offsite && $branch && !empty($branch['name'])) ? $branch['name'] : 'Off-site';

        /* save selfie file */
        $rel = 'uploads/attendance/'.date('Y/m');
        $abs = __DIR__.'/../'.$rel;
        if (!is_dir($abs)) @mkdir($abs,0775,true);
        $fname = $userId.'_'.$today.'_'.$punch.'_'.date('His').'.jpg';
        if (@file_put_contents($abs.'/'.$fname,$bin) === false) throw new Exception("Could not save photo on server.");
        $photoPath = $rel.'/'.$fname;

        /* merge values */
        $g = function($k) use ($row){ return $row[$k] ?? null; };
        $v = [
            'am_in'=>$g('am_in'),'am_out'=>$g('am_out'),'pm_in'=>$g('pm_in'),'pm_out'=>$g('pm_out'),
            'am_in_photo'=>$g('am_in_photo'),'am_out_photo'=>$g('am_out_photo'),
            'pm_in_photo'=>$g('pm_in_photo'),'pm_out_photo'=>$g('pm_out_photo'),
            'am_late'=>(int)$g('am_late'),'pm_late'=>(int)$g('pm_late'),
            'am_in_lat'=>$g('am_in_lat'),'am_in_lng'=>$g('am_in_lng'),
            'pm_in_lat'=>$g('pm_in_lat'),'pm_in_lng'=>$g('pm_in_lng'),
            'am_in_place'=>$g('am_in_place'),'am_out_place'=>$g('am_out_place'),
            'pm_in_place'=>$g('pm_in_place'),'pm_out_place'=>$g('pm_out_place'),
            'offsite_reason'=>$g('offsite_reason'),
        ];
        /* keep the latest off-site reason (label which punch it was for) */
        if ($reallyOffsite && $reason !== '') {
            $tag = $punches[$punch]['en'] ?? $punch;
            $v['offsite_reason'] = mb_substr($tag.': '.$reason, 0, 255);
        }
        $v[$punch] = $now;
        $v[$punch.'_photo'] = $photoPath;
        $v[$punch.'_place'] = $place;
        if ($punch==='am_in'){ $v['am_in_lat']=$lat; $v['am_in_lng']=$lng; $v['am_late']=lateMins($punches['am_in']['sched'],$ctx['grace'],$now); }
        if ($punch==='pm_in'){ $v['pm_in_lat']=$lat; $v['pm_in_lng']=$lng; $v['pm_late']=lateMins($punches['pm_in']['sched'],$ctx['grace'],$now); }

        /* summary fields */
        $checkIn  = $v['am_in'] ?: $v['pm_in'];
        $checkOut = $v['pm_out'] ?: $v['am_out'];
        $lateTotal = (int)$v['am_late'] + (int)$v['pm_late'];
        $status = $lateTotal > 0 ? 'late' : 'present';

        $secs = 0;
        if ($v['am_in'] && $v['am_out']) { $d=strtotime($v['am_out'])-strtotime($v['am_in']); if($d>0)$secs+=$d; }
        if ($v['pm_in'] && $v['pm_out']) { $d=strtotime($v['pm_out'])-strtotime($v['pm_in']); if($d>0)$secs+=$d; }
        $hours = round($secs/3600,2);

        /* OT on the final out punch of the day */
        $hasPM = isset($punches['pm_out']);
        $lastOutKey = $hasPM ? 'pm_out' : 'am_out';
        $endHM      = $hasPM ? ($punches['pm_out']['sched']) : ($punches['am_out']['sched'] ?? null);
        $otMin = (int)($row['ot_minutes'] ?? 0);
        $otStatus = $row['ot_status'] ?? 'none';
        if ($punch === $lastOutKey && $endHM) {
            $thr = strtotime($endHM) + (int)$ctx['ot_after']*60;
            $over = strtotime($now) - $thr;
            $otMin = ($over > 0) ? (int)floor($over/60) : 0;
            if ($otMin < (int)$ctx['min_ot']) $otMin = 0;
            $ownerOT = appr_is_owner($pdo, $companyId, $userId);   // owner OT auto-approves
            $otStatus = $otMin > 0 ? ($ownerOT ? 'approved' : 'pending') : 'none';
        }

        /* incomplete if any scheduled punch still missing */
        $incomplete = 0;
        foreach ($punches as $k=>$_) if (empty($v[$k])) { $incomplete=1; break; }

        $isOffsite = max((int)($row['is_offsite'] ?? 0), $offsite);
        $branchId  = $branch['id'] ?? ($row['branch_id'] ?? null);

        if ($row) {
            $sql = "UPDATE hr_attendance SET
                am_in=?,am_out=?,pm_in=?,pm_out=?,
                am_in_photo=?,am_out_photo=?,pm_in_photo=?,pm_out_photo=?,
                am_late=?,pm_late=?,am_in_lat=?,am_in_lng=?,pm_in_lat=?,pm_in_lng=?,
                am_in_place=?,am_out_place=?,pm_in_place=?,pm_out_place=?,offsite_reason=?,
                check_in=?,check_out=?,late_minutes=?,hours_worked=?,status=?,
                ot_minutes=?,ot_status=?,is_offsite=?,is_incomplete=?,branch_id=?,source='checkin'
                WHERE id=?";
            $pdo->prepare($sql)->execute([
                $v['am_in'],$v['am_out'],$v['pm_in'],$v['pm_out'],
                $v['am_in_photo'],$v['am_out_photo'],$v['pm_in_photo'],$v['pm_out_photo'],
                $v['am_late'],$v['pm_late'],$v['am_in_lat'],$v['am_in_lng'],$v['pm_in_lat'],$v['pm_in_lng'],
                $v['am_in_place'],$v['am_out_place'],$v['pm_in_place'],$v['pm_out_place'],$v['offsite_reason'],
                $checkIn,$checkOut,$lateTotal,$hours,$status,
                $otMin,$otStatus,$isOffsite,$incomplete,$branchId,$row['id']
            ]);
        } else {
            $sql = "INSERT INTO hr_attendance
                (staff_id,company_id,work_date,am_in,am_out,pm_in,pm_out,
                 am_in_photo,am_out_photo,pm_in_photo,pm_out_photo,
                 am_late,pm_late,am_in_lat,am_in_lng,pm_in_lat,pm_in_lng,
                 am_in_place,am_out_place,pm_in_place,pm_out_place,offsite_reason,
                 check_in,check_out,late_minutes,hours_worked,status,
                 ot_minutes,ot_status,is_offsite,is_incomplete,branch_id,source)
                VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, 'checkin')";
            $pdo->prepare($sql)->execute([
                $userId,$companyId,$today,$v['am_in'],$v['am_out'],$v['pm_in'],$v['pm_out'],
                $v['am_in_photo'],$v['am_out_photo'],$v['pm_in_photo'],$v['pm_out_photo'],
                $v['am_late'],$v['pm_late'],$v['am_in_lat'],$v['am_in_lng'],$v['pm_in_lat'],$v['pm_in_lng'],
                $v['am_in_place'],$v['am_out_place'],$v['pm_in_place'],$v['pm_out_place'],$v['offsite_reason'],
                $checkIn,$checkOut,$lateTotal,$hours,$status,$otMin,$otStatus,$isOffsite,$incomplete,$branchId
            ]);
        }

        /* notify approvers when this punch created pending overtime */
        if ($punch === $lastOutKey && ($otStatus ?? '') === 'pending' && $otMin > 0) {
            $who = $_SESSION['name'] ?? 'A staff member';
            foreach (approvers_for_staff($pdo,$companyId,$userId) as $aid) {
                notify_user($pdo,$aid,"⏱️ OT approval needed", $who." has ".round($otMin/60,1)."h overtime waiting.","company/ot_approvals.php");
            }
        }

        $thisLate = ($punch==='am_in') ? (int)$v['am_late'] : (($punch==='pm_in') ? (int)$v['pm_late'] : 0);
        echo json_encode([
            'ok'=>true,'time'=>substr($now,0,5),'late'=>$thisLate,
            'msg_en'=> ($punches[$punch]['en']).' done'.($thisLate>0?" — $thisLate min late.":'.'),
            'msg_lo'=> ($punches[$punch]['lo']).' ສຳເລັດ'.($thisLate>0?" — ຊ້າ $thisLate ນາທີ.":'.'),
        ]);
        exit;
    } catch (Throwable $e) {
        echo json_encode(['ok'=>false,'msg_en'=>$e->getMessage(),'msg_lo'=>$e->getMessage()]);
        exit;
    }
}

/* ── Display ── */
$row    = todayRow($pdo,$companyId,$userId,$today);
$branch = $ctx['branch'];
$exempt = !$ctx['checkin_required'];
$backUrl = '../customer/company_home.php';
$allDone = true;
foreach ($punches as $k=>$_) if (empty($row[$k] ?? null)) { $allDone=false; break; }
?>
<!DOCTYPE html>
<html lang="lo">
<head>
    <?php $pwaTheme = '#2563eb'; include __DIR__ . '/../config/pwa_head.php'; ?>
    <title><?= htmlspecialchars($_SESSION["company_name"]) ?> — Check In</title>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Lao:wght@400;500;600;700;800&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
    <script src="../assets/lang.js" defer></script>
    <style>
        *,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
        :root{--primary:#2563eb;--surface:#fff;--bg:#f0f4f8;--border:#e2e8f0;--text:#0f172a;--muted:#64748b;
            --green:#16a34a;--green-lt:#dcfce7;--red:#dc2626;--red-lt:#fee2e2;--amber:#d97706;--amber-lt:#fef3c7;
            --blue-lt:#dbeafe;--radius:18px;--shadow:0 2px 14px rgba(15,23,42,.09);}
        body{font-family:"Noto Sans Lao","Inter",Arial,sans-serif;background:var(--bg);color:var(--text);min-height:100vh;}
        .top-bar{background:var(--surface);border-bottom:1px solid var(--border);
            padding:calc(12px + env(safe-area-inset-top, 0px)) 18px 12px;display:flex;
            justify-content:space-between;align-items:center;gap:12px;position:sticky;top:0;z-index:100;
            box-shadow:0 1px 6px rgba(15,23,42,.06);flex-wrap:wrap;}
        .brand{display:flex;align-items:center;gap:9px;}
        .brand-logo{width:32px;height:32px;background:linear-gradient(135deg,#1e3a5f,#2563eb);border-radius:8px;
            display:flex;align-items:center;justify-content:center;color:#fff;font-weight:800;font-size:13px;}
        .brand-text{font-size:13px;font-weight:700;}.brand-sub{font-size:11px;color:var(--muted);}
        .top-right{display:flex;align-items:center;gap:8px;}
        .lang-btn{padding:4px 10px;border-radius:999px;border:1.5px solid var(--border);background:var(--surface);
            font-size:11px;font-weight:700;color:var(--muted);cursor:pointer;font-family:inherit;}
        .lang-btn.active{background:var(--primary);border-color:var(--primary);color:#fff;}
        .back-link{background:#f1f5f9;color:var(--text);border:1.5px solid var(--border);padding:6px 12px;
            border-radius:8px;text-decoration:none;font-size:12px;font-weight:700;}
        .page{padding:20px 16px;max-width:520px;margin:auto;}
        .clock{text-align:center;margin:10px 0 16px;}
        .clock .time{font-size:44px;font-weight:800;letter-spacing:-1px;line-height:1;}
        .clock .date{font-size:14px;color:var(--muted);margin-top:6px;font-weight:600;}
        .banner{border-radius:14px;padding:14px 16px;margin-bottom:16px;font-weight:700;font-size:15px;text-align:center;}
        .b-done{background:var(--green-lt);color:#15803d;}
        .b-prog{background:var(--blue-lt);color:#1e40af;}
        .b-rest{background:#f1f5f9;color:var(--muted);}
        .b-exempt{background:var(--amber-lt);color:#92400e;}
        .loc-line{text-align:center;font-size:12px;color:var(--muted);margin-bottom:14px;}
        .punch-grid{display:grid;grid-template-columns:1fr;gap:12px;margin-bottom:16px;}
        .punch{background:var(--surface);border:1.5px solid var(--border);border-radius:16px;padding:16px 14px;
            text-align:center;box-shadow:var(--shadow);cursor:pointer;transition:transform .12s,border-color .12s;}
        .punch:active{transform:scale(.97);}
        .punch.done{cursor:default;border-color:#bbf7d0;background:#f7fdf9;display:flex;align-items:center;gap:14px;text-align:left;}
        .punch.done .pinfo{flex:1;text-align:center;}
        .pshot{display:flex;flex-direction:column;align-items:center;gap:5px;flex-shrink:0;}
        .pphoto{width:88px;height:88px;border-radius:12px;object-fit:cover;border:2px solid #bbf7d0;cursor:pointer;}
        .ploc{font-size:11px;font-weight:700;color:var(--muted);max-width:104px;text-align:center;line-height:1.25;}
        .punch .plabel{font-size:13px;font-weight:800;margin-bottom:4px;}
        .punch .psched{font-size:11px;color:var(--muted);}
        .punch .ptime{font-size:24px;font-weight:800;margin-top:8px;line-height:1;}
        .punch .pcta{margin-top:10px;display:inline-flex;align-items:center;gap:6px;background:var(--primary);
            color:#fff;border-radius:10px;padding:9px 12px;font-size:13px;font-weight:800;}
        .punch.outcta .pcta{background:#1e3a5f;}
        .tag{display:inline-block;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:800;margin-top:6px;}
        .tag.green{background:var(--green-lt);color:#15803d;}.tag.amber{background:var(--amber-lt);color:#92400e;}
        .tag.gray{background:#f1f5f9;color:var(--muted);}
        .pcheck{color:#16a34a;font-size:22px;margin-top:6px;}
        .hist{display:block;text-align:center;margin-top:12px;color:var(--primary);font-weight:700;text-decoration:none;font-size:13px;}
        .toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);max-width:90%;padding:13px 18px;
            border-radius:12px;font-size:14px;font-weight:700;color:#fff;box-shadow:0 8px 28px rgba(0,0,0,.25);
            z-index:300;opacity:0;transition:opacity .25s;pointer-events:none;text-align:center;}
        .toast.show{opacity:1;}.toast.ok{background:#15803d;}.toast.err{background:#dc2626;}
        /* camera overlay */
        .cam{display:none;position:fixed;inset:0;background:#000;z-index:400;flex-direction:column;align-items:center;justify-content:center;}
        .cam video,.cam img{width:100%;max-width:520px;max-height:70vh;object-fit:cover;border-radius:14px;background:#111;
            transform:scaleX(-1);}
        .cam .camhdr{color:#fff;font-weight:800;font-size:16px;margin-bottom:12px;text-align:center;}
        .cam .camctrls{display:flex;gap:14px;margin-top:18px;align-items:center;}
        .cam button{font-family:inherit;font-weight:800;border:none;border-radius:14px;cursor:pointer;}
        .cap-btn{width:74px;height:74px;border-radius:50%;background:#fff;border:5px solid #93c5fd;font-size:26px;}
        .use-btn{background:#16a34a;color:#fff;padding:16px 26px;font-size:16px;}
        .retake-btn{background:#374151;color:#fff;padding:16px 22px;font-size:15px;}
        .cancel-btn{background:transparent;color:#cbd5e1;padding:10px;font-size:14px;margin-top:8px;}
        .spin{width:18px;height:18px;border:3px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;
            display:inline-block;animation:sp .7s linear infinite;}
        @keyframes sp{to{transform:rotate(360deg);}}
    </style>
</head>
<body>

<div class="top-bar">
    <div class="brand">
        <div class="brand-logo">7D</div>
        <div>
            <div class="brand-text"><?= htmlspecialchars($_SESSION["company_name"]) ?></div>
            <div class="brand-sub" data-lo="ລົງເວລາ ດ້ວຍຮູບ" data-en="Photo Check In">ລົງເວລາ ດ້ວຍຮູບ</div>
        </div>
    </div>
    <div class="top-right">
        <button class="lang-btn" id="btn-lo" onclick="setLang('lo')">🇱🇦 ລາວ</button>
        <button class="lang-btn" id="btn-en" onclick="setLang('en')">🇬🇧 EN</button>
        <a class="back-link" href="<?= htmlspecialchars($backUrl) ?>">←</a>
    </div>
</div>

<div class="page">

    <div class="clock">
        <div class="time" id="liveClock">--:--</div>
        <div class="date"><?= date('l, d/m/Y') ?></div>
    </div>

    <?php if ($exempt): ?>
        <div class="banner b-exempt" data-lo="⭐ ທ່ານໄດ້ຮັບການຍົກເວັ້ນ — ບໍ່ຕ້ອງລົງເວລາ." data-en="⭐ You are exempt — no check-in required.">⭐ Exempt — no check-in required.</div>
    <?php elseif (!$punches): ?>
        <div class="banner b-rest" data-lo="ມື້ນີ້ບໍ່ມີຮອບເຮັດວຽກ (ມື້ພັກ)." data-en="No working session scheduled today (rest day).">No working session today (rest day).</div>
        <div class="loc-line" data-lo="ກຳນົດເວລາເຮັດວຽກໄດ້ທີ່ ໜ້າຕັ້ງຄ່າການເຂົ້າວຽກ." data-en="Set working hours in Attendance Settings.">Set working hours in Attendance Settings.</div>
    <?php else: ?>

        <div class="banner <?= $allDone?'b-done':'b-prog' ?>"
             data-lo="<?= $allDone?'ລົງເວລາຄົບແລ້ວ ✓':'ລົງເວລາໃຫ້ຄົບ 4 ຄັ້ງ' ?>"
             data-en="<?= $allDone?'All punches done ✓':'Punch in & out, morning & afternoon' ?>">
            <?= $allDone?'All punches done ✓':'Punch in & out, morning & afternoon' ?>
        </div>

        <div class="loc-line">
            📍 <span data-lo="ລົງເວລາໄດ້ຈາກບ່ອນໃດກໍໄດ້ — ລະບົບຈະບັນທຶກຕຳແໜ່ງຂອງທ່ານ."
                     data-en="You can check in from anywhere — your location is recorded.">You can check in from anywhere — your location is recorded.</span>
        </div>

        <div class="punch-grid">
            <?php foreach ($punches as $key=>$p):
                $val = $row[$key] ?? null;
                $isOut = $p['type']==='out';
                $lateField = $key==='am_in' ? ($row['am_late']??0) : ($key==='pm_in' ? ($row['pm_late']??0) : 0);
                $photo = $row[$key.'_photo'] ?? null;
            ?>
            <div class="punch <?= $val?'done':'' ?> <?= $isOut?'outcta':'' ?>" <?= $val?'':"onclick=\"openCamera('$key')\"" ?>>
                <div class="pinfo">
                    <div class="plabel" data-lo="<?= $p['lo'] ?>" data-en="<?= $p['en'] ?>"><?= $p['en'] ?></div>
                    <div class="psched"><?= htmlspecialchars(substr($p['sched'],0,5)) ?></div>
                    <?php if ($val): ?>
                        <div class="ptime"><?= substr($val,0,5) ?></div>
                        <?php if ($p['type']==='in'): ?>
                            <?php if ((int)$lateField>0): ?>
                                <span class="tag amber"><span data-lo="ຊ້າ" data-en="Late">Late</span> <?= (int)$lateField ?>′</span>
                            <?php else: ?>
                                <span class="tag green" data-lo="ຕົງເວລາ" data-en="On time">On time</span>
                            <?php endif; ?>
                        <?php else: ?>
                            <div class="pcheck">✓</div>
                        <?php endif; ?>
                    <?php else: ?>
                        <div class="pcta">📸 <span data-lo="ລົງເວລາ" data-en="Punch">Punch</span></div>
                    <?php endif; ?>
                </div>
                <?php if ($val && $photo): ?>
                    <div class="pshot">
                        <img class="pphoto" src="../<?= htmlspecialchars($photo) ?>" onclick="showShot(this.src)" alt="">
                        <div class="ploc">📍 <?php if ($branch && !(int)($row['is_offsite']??0)): ?><?= htmlspecialchars($branch['name']) ?><?php else: ?><span data-lo="ນອກສະຖານທີ່" data-en="Off-site">Off-site</span><?php endif; ?></div>
                    </div>
                <?php endif; ?>
            </div>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>

    <a class="hist" href="my_attendance.php" data-lo="ເບິ່ງປະຫວັດການເຂົ້າວຽກ →" data-en="View attendance history →">View attendance history →</a>
</div>

<!-- Camera overlay -->
<div class="cam" id="cam">
    <div class="camhdr" id="camHdr">📸</div>
    <video id="camVideo" autoplay playsinline muted></video>
    <img id="camStill" style="display:none" alt="">
    <canvas id="camCanvas" style="display:none"></canvas>
    <div class="camctrls" id="camLive">
        <button class="cap-btn" onclick="capturePhoto()">📷</button>
    </div>
    <div class="camctrls" id="camReview" style="display:none">
        <button class="retake-btn" onclick="retake()" data-lo="↻ ຖ່າຍໃໝ່" data-en="↻ Retake">↻ Retake</button>
        <button class="use-btn" onclick="usePhoto()" data-lo="✓ ໃຊ້ຮູບນີ້" data-en="✓ Use photo">✓ Use photo</button>
    </div>
    <button class="cancel-btn" onclick="closeCamera()" data-lo="ຍົກເລີກ" data-en="Cancel">Cancel</button>
</div>

<div class="toast" id="toast"></div>

<!-- off-site reason -->
<div id="reasonModal" style="display:none;position:fixed;inset:0;background:rgba(15,23,42,.55);z-index:360;align-items:center;justify-content:center;padding:18px;">
    <div style="background:#fff;border-radius:16px;max-width:420px;width:100%;padding:22px;box-shadow:0 20px 60px rgba(0,0,0,.3);">
        <div style="font-size:17px;font-weight:800;margin-bottom:4px;" data-lo="📍 ທ່ານຢູ່ນອກສະຖານທີ່" data-en="📍 You are off-site">📍 You are off-site</div>
        <div style="font-size:13px;color:#64748b;margin-bottom:14px;" data-lo="ກະລຸນາຂຽນເຫດຜົນທີ່ລົງເວລານອກບ່ອນ." data-en="Please write why you are punching away from the office.">Please write why you are punching away from the office.</div>
        <textarea id="reasonText" rows="3" style="width:100%;padding:11px;border:1.5px solid #e2e8f0;border-radius:10px;font-size:15px;font-family:inherit;" placeholder="..."></textarea>
        <div style="display:flex;gap:10px;margin-top:14px;">
            <button onclick="submitReason()" style="flex:1;background:#2563eb;color:#fff;border:none;padding:12px;border-radius:10px;font-weight:800;font-size:15px;cursor:pointer;font-family:inherit;" data-lo="✓ ສົ່ງ ແລະ ບັນທຶກ" data-en="✓ Submit & save">✓ Submit &amp; save</button>
            <button onclick="closeReason()" style="background:#f1f5f9;border:1.5px solid #e2e8f0;padding:12px 16px;border-radius:10px;font-weight:700;cursor:pointer;font-family:inherit;" data-lo="ຍົກເລີກ" data-en="Cancel">Cancel</button>
        </div>
    </div>
</div>

<!-- enlarge a punch selfie -->
<div id="shotModal" onclick="this.style.display='none'" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:350;align-items:center;justify-content:center;padding:20px;">
    <span style="position:absolute;top:18px;right:22px;color:#fff;font-size:34px;font-weight:700;">&times;</span>
    <img id="shotImg" src="" alt="" style="max-width:100%;max-height:85vh;border-radius:12px;">
</div>

<script>
const needGeo = <?= (!$exempt && $ctx['geofence_required'] && $branch) ? 'true' : 'false' ?>;
const PLABEL  = <?= json_encode(array_map(fn($p)=>['en'=>$p['en'],'lo'=>$p['lo']], $punches), JSON_UNESCAPED_UNICODE) ?>;

function showShot(src){var m=document.getElementById('shotModal');document.getElementById('shotImg').src=src;m.style.display='flex';}
function tick(){
    const o=new Intl.DateTimeFormat('en-GB',{hour:'2-digit',minute:'2-digit',hour12:false,timeZone:'Asia/Vientiane'});
    document.getElementById('liveClock').textContent=o.format(new Date());
}
tick(); setInterval(tick,1000);

function toast(m,ok){const t=document.getElementById('toast');t.textContent=m;t.className='toast show '+(ok?'ok':'err');setTimeout(()=>t.className='toast',4000);}

function getPos(){return new Promise(res=>{if(!navigator.geolocation){res(null);return;}
    navigator.geolocation.getCurrentPosition(p=>res({lat:p.coords.latitude,lng:p.coords.longitude}),()=>res(null),{enableHighAccuracy:true,timeout:10000,maximumAge:0});});}

let stream=null, currentPunch=null, captured=null;

async function openCamera(punch){
    currentPunch=punch;
    const lbl=PLABEL[punch];
    document.getElementById('camHdr').textContent='📸 '+(window._lang==='en'?lbl.en:lbl.lo);
    document.getElementById('cam').style.display='flex';
    setMode('live');
    try{
        stream=await navigator.mediaDevices.getUserMedia({video:{facingMode:'user'},audio:false});
        const v=document.getElementById('camVideo'); v.srcObject=stream; await v.play();
    }catch(e){
        toast(window._lang==='en'?'Cannot open camera. Allow camera access.':'ເປີດກ້ອງບໍ່ໄດ້. ກະລຸນາອະນຸຍາດກ້ອງ.',false);
        closeCamera();
    }
}
function setMode(m){
    document.getElementById('camVideo').style.display = m==='live'?'block':'none';
    document.getElementById('camStill').style.display = m==='review'?'block':'none';
    document.getElementById('camLive').style.display  = m==='live'?'flex':'none';
    document.getElementById('camReview').style.display= m==='review'?'flex':'none';
}
function capturePhoto(){
    const v=document.getElementById('camVideo'), c=document.getElementById('camCanvas');
    const w=480, sc=w/(v.videoWidth||640), h=Math.round((v.videoHeight||480)*sc);
    c.width=w; c.height=h;
    const ctx=c.getContext('2d'); ctx.drawImage(v,0,0,w,h);
    captured=c.toDataURL('image/jpeg',0.5);
    document.getElementById('camStill').src=captured;
    setMode('review');
}
function retake(){captured=null;setMode('live');}
function stopStream(){if(stream){stream.getTracks().forEach(t=>t.stop());stream=null;}}
function closeCamera(){stopStream();document.getElementById('cam').style.display='none';}

let pendingPhoto=null, pendingPunch=null, pendingPos=null;

async function usePhoto(){
    pendingPhoto=captured; pendingPunch=currentPunch;
    stopStream(); document.getElementById('cam').style.display='none';
    toast(window._lang==='en'?'Saving…':'ກຳລັງບັນທຶກ…',true);
    pendingPos=await getPos();   // capture location if available; never blocks the punch
    submitPunch('');
}

async function submitPunch(reason){
    const body=new URLSearchParams();
    body.set('action','punch'); body.set('punch',pendingPunch); body.set('photo',pendingPhoto);
    if(pendingPos){body.set('lat',pendingPos.lat);body.set('lng',pendingPos.lng);}
    if(reason) body.set('reason',reason);
    try{
        const res=await fetch('checkin.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body});
        const d=await res.json();
        if(d.need_reason){ openReason(); return; }   // off-site: ask for a reason, then resubmit
        toast(window._lang==='en'?d.msg_en:d.msg_lo, d.ok);
        if(d.ok) setTimeout(()=>location.reload(),1100);
    }catch(e){toast('Network error. Try again.',false);}
}

function openReason(){
    document.getElementById('reasonText').value='';
    document.getElementById('reasonModal').style.display='flex';
    setTimeout(()=>document.getElementById('reasonText').focus(),100);
}
function closeReason(){ document.getElementById('reasonModal').style.display='none'; }
function submitReason(){
    const r=document.getElementById('reasonText').value.trim();
    if(!r){ document.getElementById('reasonText').focus(); return; }
    closeReason();
    toast(window._lang==='en'?'Saving…':'ກຳລັງບັນທຶກ…',true);
    submitPunch(r);
}
</script>

<?php require __DIR__ . '/../config/auto_update.php'; ?>
</body>
</html>