<?php
/* =============================================================================
 * File   : ams_mark.php
 * Goal   : Strict 200 m geofence (+ accuracy ≤100 m) for IN/OUT.
 *          - Save IN distance -> tracker.distance (km)
 *          - Save OUT distance -> tracker.out_distance (km)
 *          - Log EVERY attempt (IN/OUT, in-range/out-range) -> tracker_log
 * Stack  : Core PHP + MySQLi (NO PDO). DB in ../config.php
 * DB     : utf8mb4 / utf8mb4_general_ci (enforced)
 * ============================================================================= */

date_default_timezone_set('Asia/Kolkata');
include('../config.php');
@session_start();

/* ---------------- Auth guard ---------------- */
if (!isset($_SESSION['user_id1'])) { header('Location: index.php'); exit; }
$user_id1 = (string)$_SESSION['user_id1'];

/* ---------------- Extend session cookie ---------------- */
$timeout = 60 * 60 * 24 * 365;
$s_name  = session_name();
if (isset($_COOKIE[$s_name])) { setcookie($s_name, $_COOKIE[$s_name], time() + $timeout, '/'); }

/* ---------------- Charset & collation ---------------- */
if (isset($conn) && $conn instanceof mysqli) {
    @mysqli_set_charset($conn, 'utf8mb4');
    @mysqli_query($conn, "SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci'");
    @mysqli_query($conn, "SET collation_connection='utf8mb4_general_ci'");
}

/* ---------------- Constants ---------------- */
define('MAX_RANGE_M', 200.0);   // geofence radius
define('MAX_ACC_M',   100.0);   // required GPS accuracy

/* ---------------- Load employee ---------------- */
$emp = [
  'empid'=>'','Employee_Full_Name'=>'','Team_Name'=>'','Role'=>'',
  'Location_of_Work'=>'','Functional_Reporting'=>'','Reporting_Head_Code'=>'',
  'Team_Head_Code'=>'','bh_empid'=>'0','photo'=>'','Designation'=>''
];
$qEmp = mysqli_query($conn, "SELECT * FROM hr_dump WHERE empid='".mysqli_real_escape_string($conn,$user_id1)."' LIMIT 1");
if ($qEmp && mysqli_num_rows($qEmp)>0) { $emp = array_merge($emp, mysqli_fetch_assoc($qEmp)); }

/* Keep common scalars for bind-by-ref */
$emp_empid    = (string)($emp['empid'] ?? '');
$emp_name     = (string)($emp['Employee_Full_Name'] ?? '');
$emp_team     = (string)($emp['Team_Name'] ?? '');
$emp_role     = (string)($emp['Role'] ?? '');
$emp_locwork  = (string)($emp['Location_of_Work'] ?? '');
$emp_func     = (string)($emp['Functional_Reporting'] ?? '');
$emp_rhc      = (string)($emp['Reporting_Head_Code'] ?? '');
$emp_thc      = (string)($emp['Team_Head_Code'] ?? '');
$emp_bh       = (string)($emp['bh_empid'] ?? '');

/* ---------------- Client env (IP/Browser/Device) ---------------- */
function getUserIpAddr(){
  if(!empty($_SERVER['HTTP_CLIENT_IP'])) return $_SERVER['HTTP_CLIENT_IP'];
  if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) return trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]);
  return $_SERVER['REMOTE_ADDR'] ?? '';
}
$ip = getUserIpAddr();
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$browser = 'Unknown';
foreach (["Opera","Edg","Chrome","Safari","Firefox","MSIE","Trident"] as $b) { if (strpos($ua, $b) !== false) { $browser = $b; break; } }
if ($browser==='MSIE' || $browser==='Trident') $browser='Internet Explorer';
if ($browser==='Edg') $browser='Microsoft Edge';
$ual = strtolower($ua);
$device = (strpos($ual,'iphone')!==false||strpos($ual,'ipad')!==false) ? 'IOS' : (strpos($ual,'android')!==false ? 'ANDROID' : (strpos($ual,'windows')!==false ? 'WINDOWS' : 'UNKNOWN'));

/* ---------------- Geo helpers ---------------- */
function haversine_m($lat1,$lon1,$lat2,$lon2){
  $R=6371000.0; $phi1=deg2rad($lat1); $phi2=deg2rad($lat2);
  $dphi=deg2rad($lat2-$lat1); $dlam=deg2rad($lon2-$lon1);
  $a=sin($dphi/2)**2 + cos($phi1)*cos($phi2)*sin($dlam/2)**2;
  return 2*$R*atan2(sqrt($a),sqrt(1-$a));
}
function find_nearest_location($conn,$lat,$lng){
  $nearest=null; $min=PHP_INT_MAX;
  $q=mysqli_query($conn,"SELECT id,location,latitude,longitude FROM locations WHERE latitude IS NOT NULL AND longitude IS NOT NULL");
  if($q){
    while($r=mysqli_fetch_assoc($q)){
      $m=haversine_m((float)$lat,(float)$lng,(float)$r['latitude'],(float)$r['longitude']);
      if($m<$min){ $min=$m; $nearest=$r; $nearest['_meters']=$m; }
    }
  }
  return [$nearest,$min];
}

/* ---------------- Attempt logger (tracker_log) ---------------- */
function log_attempt($conn,$data){
  $sql = "INSERT INTO tracker_log
          (user_IP,user_browser,user_device,hardwareName,hardwareModel,fingerprint,
           empid,Employee_Full_Name,cityID,location,lat,longt,PunchFrom,range_status,created_at)
          VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
  if($stmt = mysqli_prepare($conn,$sql)){
    mysqli_stmt_bind_param(
      $stmt,"ssssssssssssss",
      $data['ip'],$data['browser'],$data['device'],$data['hw'],$data['model'],$data['fp'],
      $data['empid'],$data['name'],$data['cityID'],$data['location'],$data['lat'],$data['lng'],
      $data['pfrom'],$data['status']
    );
    @mysqli_stmt_execute($stmt);
    @mysqli_stmt_close($stmt);
  }
}

/* ---------------- AJAX: nearest + accuracy ---------------- */
if (isset($_GET['ajax']) && $_GET['ajax']==='nearest' && $_SERVER['REQUEST_METHOD']==='POST'){
  header('Content-Type: application/json');
  $lat = isset($_POST['lat']) ? (float)$_POST['lat'] : 0;
  $lng = isset($_POST['lng']) ? (float)$_POST['lng'] : 0;
  $acc = isset($_POST['acc']) ? (float)$_POST['acc'] : 99999;
  if(!$lat && !$lng){ echo json_encode(['ok'=>false,'msg'=>'GPS not available']); exit; }
  list($nearest,$m)=find_nearest_location($conn,$lat,$lng);
  if($nearest){
    $inRange = ($m<=MAX_RANGE_M) && ($acc<=MAX_ACC_M);
    echo json_encode([
      'ok'=>true,'inRange'=>$inRange,'meters'=>max(0,round($m)),'accuracy'=>round($acc),
      'location'=>$nearest['location'],'loc_id'=>$nearest['id'],
      'latitude'=>(float)$nearest['latitude'],'longitude'=>(float)$nearest['longitude']
    ]);
  }else{
    echo json_encode(['ok'=>false,'msg'=>'No office locations configured']);
  }
  exit;
}

/* ---------------- AJAX: log blocked attempts ---------------- */
if (isset($_GET['ajax']) && $_GET['ajax']==='log' && $_SERVER['REQUEST_METHOD']==='POST'){
  header('Content-Type: application/json');
  $pfrom = ($_POST['pfrom'] ?? '');
  $lat   = isset($_POST['lat']) ? (float)$_POST['lat'] : 0;
  $lng   = isset($_POST['lng']) ? (float)$_POST['lng'] : 0;
  $acc   = isset($_POST['acc']) ? (float)$_POST['acc'] : 99999;

  list($nearest,$m)=find_nearest_location($conn,$lat,$lng);
  $inRange = false;
  $locName = '';
  if($nearest){
    $locName = $nearest['location'];
    $inRange = ($m<=MAX_RANGE_M) && ($acc<=MAX_ACC_M);
  }

  $log_cityID = '';
  log_attempt($conn, [
    'ip'=>$ip,'browser'=>$browser,'device'=>$device,'hw'=>($_POST['hw']??'Unknown'),
    'model'=>($_POST['model']??'Unknown'),'fp'=>($_POST['fp']??''),
    'empid'=>$emp_empid,'name'=>$emp_name,
    'cityID'=>$log_cityID,'location'=>$locName,
    'lat'=>(string)$lat,'lng'=>(string)$lng,'pfrom'=>$pfrom,'status'=>$inRange?'in-range':'out-range'
  ]);

  echo json_encode(['ok'=>true,'logged'=>true]);
  exit;
}

/* ---------------- Today state ---------------- */
$todayDate = date('Y-m-d');
$todayRow  = null;
$tr = mysqli_query($conn,"SELECT * FROM tracker WHERE empid='".mysqli_real_escape_string($conn,(string)$emp_empid)."' AND OfficeDate='{$todayDate}' ORDER BY id ASC LIMIT 1");
if($tr){ $todayRow = mysqli_fetch_assoc($tr); }
$nextAction = $todayRow ? 'OUT' : 'IN';

/* ---------------- POST: Punch IN / OUT ---------------- */
$toast=''; $flash=''; $flashType='info';
if($_SERVER['REQUEST_METHOD']==='POST' && isset($_POST['action'])){
  $desired = $_POST['action']==='OUT' ? 'OUT' : 'IN';
  $dev_lat = isset($_POST['lat'])   ? (float)$_POST['lat']   : 0;
  $dev_lng = isset($_POST['longt']) ? (float)$_POST['longt'] : 0;
  $acc_m   = isset($_POST['acc'])   ? (float)$_POST['acc']   : 99999;

  $hwName  = $_POST['hardwareName']  ?? 'Unknown';
  $hwModel = $_POST['hardwareModel'] ?? 'Unknown';
  $finger  = $_POST['fingerprint']   ?? '';
  $now     = date('H:i:s');

  list($nearest,$meters) = ($dev_lat||$dev_lng) ? find_nearest_location($conn,$dev_lat,$dev_lng) : [null,PHP_INT_MAX];
  $meters      = is_finite($meters) ? max(0.0,(float)$meters) : PHP_INT_MAX;
  $distance_km = ($meters===PHP_INT_MAX) ? 99999 : round($meters/1000, 6);
  $inRange     = ($nearest && $meters<=MAX_RANGE_M && $acc_m<=MAX_ACC_M);

  $log_cityID = $todayRow['cityID'] ?? '';
  $log_loc    = $nearest['location'] ?? '';
  log_attempt($conn, [
    'ip'=>$ip,'browser'=>$browser,'device'=>$device,'hw'=>$hwName,'model'=>$hwModel,'fp'=>$finger,
    'empid'=>$emp_empid,'name'=>$emp_name,'cityID'=>$log_cityID,'location'=>$log_loc,
    'lat'=>(string)$dev_lat,'lng'=>(string)$dev_lng,'pfrom'=>$desired,'status'=>$inRange?'in-range':'out-range'
  ]);

  if(!$inRange){
    $flash='OUT-OF-RANGE • Move within '.(int)MAX_RANGE_M.' m and wait for accuracy ≤ '.(int)MAX_ACC_M." m. (~".($meters===PHP_INT_MAX?'?':round($meters))." m, ±".(int)$acc_m." m)";
    $flashType='warning';
  } else {
    if(!$todayRow){
      if($desired!=='IN'){ $flash='First action must be IN.'; $flashType='warning'; }
      else{
        $OfficeIn   = $now;
        $OfficeLate = ($OfficeIn >= '10:16:00') ? gmdate('H:i:s', max(0,strtotime($OfficeIn)-strtotime('10:00:00'))) : '';
        $status     = 'MIS';

        /* prepare bind vars */
        $entry        = 'Punch In';
        $cityID       = '';
        $loc_id_var   = isset($nearest['id'])        ? (string)$nearest['id']        : '';
        $loc_lat_var  = isset($nearest['latitude'])  ? (string)$nearest['latitude']  : '';
        $loc_lng_var  = isset($nearest['longitude']) ? (string)$nearest['longitude'] : '';
        $dev_lat_var  = (string)$dev_lat;
        $dev_lng_var  = (string)$dev_lng;
        $loc_name_var = (string)$log_loc;
        $dist_in_km   = (float)$distance_km;
        $out_zero     = 0.0;

        $sql = "INSERT INTO tracker
          (user_IP,user_browser,user_device,hardwareName,hardwareModel,fingerprint,
           empid,Employee_Full_Name,Team_Name,Role,entry,Location_of_Work,
           Functional_Reporting,Reporting_Head_Code,Team_Head_Code,bh_empid,
           loc_id,latitude,longitude,lat,longt,cityID,location,distance,out_distance,status,
           OfficeDate,OfficeIn,OfficeLate)
         VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        $stmt = mysqli_prepare($conn,$sql);
        if($stmt){
          $types = str_repeat('s',23) . 'dd' . str_repeat('s',4); // 29 params
          mysqli_stmt_bind_param(
            $stmt,
            $types,
            $ip,$browser,$device,$hwName,$hwModel,$finger,
            $emp_empid,$emp_name,$emp_team,$emp_role,$entry,$emp_locwork,
            $emp_func,$emp_rhc,$emp_thc,$emp_bh,
            $loc_id_var,$loc_lat_var,$loc_lng_var,$dev_lat_var,$dev_lng_var,$cityID,$loc_name_var,
            $dist_in_km,$out_zero,$status,$todayDate,$OfficeIn,$OfficeLate
          );
          if(mysqli_stmt_execute($stmt)){ header('Location: ams_mark.php?toast=in'); exit; }
          else { $flash='Error while Punch In: '.mysqli_error($conn); $flashType='danger'; }
          mysqli_stmt_close($stmt);
        } else { $flash='DB Prepare Error (IN): '.mysqli_error($conn); $flashType='danger'; }
      }
    } else {
      $OfficeIn  = (string)$todayRow['OfficeIn'];
      $nowH      = $now;
      $workinghr = gmdate('H:i:s', max(0, strtotime($nowH)-strtotime($OfficeIn)));

      /* legacy status rules */
      $status = 'PRESENT';
      $OfficeEarly = '';
      if ($nowH <= '18:30:00') {
        $timeout = '18:30:00';
        $timelength = max(0, strtotime($timeout) - strtotime($nowH));
        $OfficeEarly = gmdate("H:i:s", $timelength);
        if ($OfficeIn <= '10:16:00' && $nowH >= '18:15:00') $status = "EARLY";
        if ($OfficeIn <= '10:16:00' && $nowH >= '16:30:00' && $nowH <= '18:15:00') $status = "SRT";
        if ($OfficeIn <= '10:16:00' && $nowH <= '16:30:00') $status = "HALF";
        if ($OfficeIn >= '10:16:00' && $nowH >= '16:30:00') $status = "HALF";
        if ($workinghr <= '04:00:00') $status = "ABSENT";
        if ($workinghr >= '04:00:00' && $workinghr <= '06:15:00') $status = "HALF";
        if ($workinghr >= '06:15:00' && $workinghr <= '08:15:00') $status = "SRT";
      } else {
        if ($OfficeIn >= '15:30:00' ) $status = "ABSENT";
        if ($OfficeIn <= '15:30:00' ) $status = "HALF";
        if ($OfficeIn >= '12:00:00' ) $status = "HALF";
        if ($OfficeIn >= '10:30:00' && $OfficeIn <= '12:00:00' ) $status = "SRT";
        if ($OfficeIn >= '10:16:00' && $OfficeIn <= '10:30:00' ) $status = "LATE";
        if ($OfficeIn <= '10:16:00' ) $status = "PRESENT";
        if ($workinghr <= '04:00:00') $status = "ABSENT";
        if ($workinghr >= '04:00:00' && $workinghr <= '06:15:00') $status = "HALF";
      }

      $loc_id_var   = isset($nearest['id'])        ? (string)$nearest['id']        : '';
      $loc_lat_var  = isset($nearest['latitude'])  ? (string)$nearest['latitude']  : '';
      $loc_lng_var  = isset($nearest['longitude']) ? (string)$nearest['longitude'] : '';
      $out_lat_var  = (string)$dev_lat;
      $out_lng_var  = (string)$dev_lng;
      $cityID_var   = (string)($todayRow['cityID'] ?? '');
      $out_loc_var  = isset($nearest['location']) ? (string)$nearest['location'] : '';
      $out_dist_km  = (float)$distance_km;
      $OfficeOut    = $nowH;

      $sqlU = "UPDATE tracker SET
         out_user_IP=?, out_browser=?, out_hardwareName=?, out_hardwareModel=?, out_fingerprint=?, out_device=?,
         loc_id=?, latitude=?, longitude=?, out_lat=?, out_longt=?, cityID=?, out_location=?, out_distance=?,
         status=?, OfficeEarly=?, OfficeOut=?, workinghr=?, entry='Punch Out'
       WHERE empid=? AND OfficeDate=?
       ORDER BY id ASC LIMIT 1";
      $stmtU = mysqli_prepare($conn,$sqlU);
      if($stmtU){
        $typesU = str_repeat('s',13) . 'd' . str_repeat('s',6); // 20 params
        mysqli_stmt_bind_param(
          $stmtU,
          $typesU,
          $ip,$browser,$hwName,$hwModel,$finger,$device,
          $loc_id_var,$loc_lat_var,$loc_lng_var,$out_lat_var,$out_lng_var,$cityID_var,$out_loc_var,$out_dist_km,
          $status,$OfficeEarly,$OfficeOut,$workinghr,$emp_empid,$todayDate
        );
        if(mysqli_stmt_execute($stmtU)){ header('Location: ams_mark.php?toast=out'); exit; }
        else { $flash='Error while Punch Out: '.mysqli_error($conn); $flashType='danger'; }
        mysqli_stmt_close($stmtU);
      } else { $flash='DB Prepare Error (OUT): '.mysqli_error($conn); $flashType='danger'; }
    }
  }

  /* refresh */
  $tr = mysqli_query($conn,"SELECT * FROM tracker WHERE empid='".mysqli_real_escape_string($conn,(string)$emp_empid)."' AND OfficeDate='{$todayDate}' ORDER BY id ASC LIMIT 1");
  if($tr){ $todayRow = mysqli_fetch_assoc($tr); }
  $nextAction = $todayRow ? 'OUT' : 'IN';
}

/* ---------------- UI helpers ---------------- */
function fmt_hm($t){ if(!$t) return '--:--'; return date('h:i A', strtotime($t)); }
function seconds_between($t1,$t2){ $a=strtotime($t1); $b=strtotime($t2); if(!$a||!$b) return 0; $d=$b-$a; return $d<0?0:$d; }
function fmt_hms($s){ $h=floor($s/3600); $m=floor(($s%3600)/60); $sec=$s%60; return sprintf('%02d:%02d:%02d',$h,$m,$sec); }

$now       = date('H:i:s');
$inTime    = $todayRow['OfficeIn']      ?? null;
$outTime   = $todayRow['OfficeOut']     ?? null;
$inLoc     = $todayRow['location']      ?? '';
$outLoc    = $todayRow['out_location']  ?? '';
$isLate    = ($inTime && $inTime >= '10:16:00');
$workedS   = $inTime ? seconds_between($inTime, $outTime ? $outTime : $now) : 0;
$workedTxt = fmt_hms($workedS);
$pct       = (8*3600) ? min(100, round(($workedS/(8*3600))*100)) : 0;
$toast     = $_GET['toast'] ?? '';

$EMP_NAME  = htmlspecialchars($emp_name ?: 'User',ENT_QUOTES,'UTF-8');
$AVATAR    = !empty($emp['photo']) ? htmlspecialchars($emp['photo'],ENT_QUOTES,'UTF-8') : '../assets/img/logo.png';
$DESIG     = htmlspecialchars($emp['Designation'] ?? '',ENT_QUOTES,'UTF-8');
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Mark Attendance</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<?php include('header.php'); ?>
<style>
:root{ --hdr: calc(env(safe-area-inset-top, 0px) + 56px); --bnav: calc(env(safe-area-inset-bottom, 0px) + 68px); }
html,body{margin:0;padding:0;background:#f5f8ff;min-height:100%;height:100%;}
#appCapsule{margin:0;padding: calc(var(--hdr) + 6px) 0 calc(var(--bnav)); min-height:100vh; box-sizing:border-box;}
.ams-wrap{max-width:520px;margin:0 auto; padding:0 12px; min-height: calc(100vh - var(--hdr) - var(--bnav)); display:flex; flex-direction:column; gap:10px;}
.ams-card{background:linear-gradient(180deg,#ffffff,#f7fbff);border:1px solid #e6eefc;border-radius:16px;box-shadow:0 10px 24px rgba(41,92,255,.10),0 4px 12px rgba(33,56,96,.06);}
.ams-top{display:flex;align-items:center;gap:10px;padding:10px 12px;margin:0;}
.ams-top img{width:80px;height:45px;border-radius:5px;box-shadow:0 6px 12px rgba(41,92,255,.22);}
.ams-top .nm{font-weight:800;color:#0b1e5b;}
.ams-top .ds{font-size:12px;color:#5f7199;margin-top:2px}
.ams-ring{--p:<?php echo (int)$pct; ?>; position:relative; margin:8px auto 4px; width:170px; height:170px; border-radius:50%;
  background: radial-gradient(110px 110px at 50% 45%, #ffffff, #eef4ff);
  box-shadow: inset 0 0 0 8px rgba(255,255,255,.9), 0 10px 22px rgba(30,82,255,.18), 0 0 0 6px rgba(126,160,255,.08);}
.ams-ring:before{content:"";position:absolute;inset:-8px;border-radius:50%;
  background: conic-gradient(#8fb3ff calc(var(--p)*1%), rgba(147,176,255,.22) 0);}
.ams-ring-inner{position:absolute;inset:14px;border-radius:50%;display:grid;place-items:center;background: radial-gradient(100px 100px at 50% 40%, #ffffff, #f0f5ff);border:1px solid #e5edff;}
.ams-label{text-align:center;color:#1a2f66;line-height:1.2}
.ams-label b{display:block;font-size:22px;letter-spacing:.3px;}
.ams-label small{display:block;margin-top:6px;color:#6174a1;font-size:12px}
.ams-btn{display:block;margin:10px auto 2px;width:200px;border:none;border-radius:999px;padding:12px 16px;font-size:16px;font-weight:800;cursor:pointer;transition:transform .06s ease, box-shadow .15s ease;}
.ams-btn:active{transform:translateY(1px)}
.ams-in{background:#28d391;color:#064a34;box-shadow:0 10px 18px rgba(40,211,145,.30),0 0 0 6px rgba(77,235,173,.14);}
.ams-out{background:#ff6677;color:#5c0c16;box-shadow:0 10px 18px rgba(255,102,119,.26),0 0 0 6px rgba(255,158,170,.16);}
.ams-note{min-height:18px;text-align:center;font-size:12px;margin:4px 0;color:#6a7ca4}
.ams-stats{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:8px 10px 12px;}
.ams-t{background:#fff;border:1px solid #e8efff;border-radius:14px;padding:10px;box-shadow:0 6px 16px rgba(30,82,255,.08);}
.ams-t .h{font-size:12px;color:#6b7ca1}
.ams-t .v{margin-top:4px;font-weight:800;color:#132a66;font-size:18px}
.ams-t .loc{font-size:12px;color:#6b6b6b;margin-top:2px}
.ams-badge-late{display:inline-block;margin-left:8px;padding:2px 8px;border-radius:999px;background:#ffecef;color:#b12739;border:1px solid #ffc8d0;font-size:12px;font-weight:700}
.old-history, #checked-history, .checked-history, .today-history{display:none!important;}
</style>
</head>
<body>

<div id="appCapsule">
  <div class="ams-wrap">

    <!-- PROFILE HEADER -->
    <div class="ams-card">
      <div class="ams-top">
        <img src="<?php echo $AVATAR; ?>" alt="Avatar">
        <div>
          <div class="nm"><?php echo $EMP_NAME; ?></div>
          <div class="ds"><?php echo htmlspecialchars($emp_empid,ENT_QUOTES); ?> <?php echo $DESIG? '• '.$DESIG : ''; ?></div>
        </div>
      </div>
    </div>

    <!-- RING + ACTION -->
    <div class="ams-card" style="padding-bottom:12px;">
      <div class="ams-ring" id="ring">
        <div class="ams-ring-inner">
          <div class="ams-label">
            <b id="runState"><?php echo $nextAction==='IN'?'Ready':'Running'; ?></b>
            <small>Worked: <span id="workedClock"><?php echo htmlspecialchars($workedTxt,ENT_QUOTES); ?></span></small>
          </div>
        </div>
      </div>

      <form id="punchForm" action="" method="post" autocomplete="off" style="text-align:center">
        <input type="hidden" name="action" id="action" value="<?php echo $nextAction; ?>">
        <input type="hidden" name="user_IP" value="<?php echo htmlspecialchars($ip,ENT_QUOTES); ?>">
        <input type="hidden" name="user_browser" value="<?php echo htmlspecialchars($browser,ENT_QUOTES); ?>">
        <input type="hidden" name="user_device" value="<?php echo htmlspecialchars($device,ENT_QUOTES); ?>">
        <input type="hidden" id="hardwareName" name="hardwareName" value="Unknown">
        <input type="hidden" id="hardwareModel" name="hardwareModel" value="Unknown">
        <input type="hidden" id="fingerprint" name="fingerprint" value="">
        <input type="hidden" name="empid" value="<?php echo htmlspecialchars($emp_empid,ENT_QUOTES); ?>">
        <input type="hidden" name="Employee_Full_Name" value="<?php echo htmlspecialchars($emp_name,ENT_QUOTES); ?>">
        <input type="hidden" name="Team_Name" value="<?php echo htmlspecialchars($emp_team,ENT_QUOTES); ?>">
        <input type="hidden" name="Role" value="<?php echo htmlspecialchars($emp_role,ENT_QUOTES); ?>">
        <input type="hidden" name="Location_of_Work" value="<?php echo htmlspecialchars($emp_locwork,ENT_QUOTES); ?>">
        <input type="hidden" name="Functional_Reporting" value="<?php echo htmlspecialchars($emp_func,ENT_QUOTES); ?>">
        <input type="hidden" name="Reporting_Head_Code" value="<?php echo htmlspecialchars($emp_rhc,ENT_QUOTES); ?>">
        <input type="hidden" name="Team_Head_Code" value="<?php echo htmlspecialchars($emp_thc,ENT_QUOTES); ?>">
        <input type="hidden" name="bh_empid" value="<?php echo htmlspecialchars($emp_bh,ENT_QUOTES); ?>">
        <input type="hidden" name="lat" id="lat">
        <input type="hidden" name="longt" id="longt">
        <input type="hidden" name="acc" id="acc"><!-- GPS accuracy (m) -->

        <?php if($nextAction==='IN'): ?>
          <button type="button" id="btnToggle" class="ams-btn ams-in" onclick="doPunch()">PUNCH IN</button>
        <?php else: ?>
          <button type="button" id="btnToggle" class="ams-btn ams-out" onclick="doPunch()">PUNCH OUT</button>
        <?php endif; ?>
      </form>

      <div id="rangeStatus" class="ams-note"></div>
      <div id="permTip" class="ams-note" style="display:none">Tip: Tap the lock/location icon near the URL → set <b>Location: Allow</b>, then try again.</div>

      <!-- IN / OUT tiles -->
      <div class="ams-stats">
        <div class="ams-t">
          <div class="h">Check In <?php if($isLate): ?><span class="ams-badge-late">Late</span><?php endif; ?></div>
          <div class="v"><?php echo $inTime ? fmt_hm($inTime) : '--:--'; ?></div>
          <div class="loc"><?php echo $inLoc !== '' ? htmlspecialchars($inLoc,ENT_QUOTES) : '—'; ?></div>
        </div>
        <div class="ams-t">
          <div class="h">Check Out</div>
          <div class="v"><?php echo $outTime ? fmt_hm($outTime) : '--:--'; ?></div>
          <div class="loc"><?php echo ($outLoc !== '' ? htmlspecialchars($outLoc,ENT_QUOTES) : ($outTime ? '—' : '—')); ?></div>
        </div>
      </div>
    </div>

    <?php include('include/copyright.php'); ?>
  </div>
</div>

<!-- Toast -->
<div id="toastx" class="toastx<?php echo $toast ? '' : ''; ?>">
  <?php if($toast==='in'): ?>
    <div><strong>Punched In</strong><br><small>Welcome!</small></div>
  <?php elseif($toast==='out'): ?>
    <div><strong>Punched Out</strong><br><small>Have a nice day.</small></div>
  <?php endif; ?>
</div>

<?php include('footer.php'); ?>

<!-- Device / fingerprint (optional) -->
<script src="https://investorsclinic.org/ams-live/client.js"></script>
<script async src="https://cloud.51degrees.com/api/v4/AQR6ugX3KzEAXStH3Eg.js"></script>
<script>
document.body.onload = function() {
  if (window.fod && typeof fod.complete==='function') {
    fod.complete(function (data) {
      var d = (data && data.device) ? data.device : {};
      document.getElementById('hardwareName').value  = d.hardwarename || d["hardwarename"] || 'Unknown';
      document.getElementById('hardwareModel').value = d.hardwaremodel || d["hardwaremodel"] || 'Unknown';
    });
  }
  try{ var client = new ClientJS(); document.getElementById('fingerprint').value = client.getFingerprint(); }catch(e){}
};
</script>

<!-- GPS + nearest + client block + logging + live timer -->
<script>
(function setOffsets(){
  function apply(){
    var hdr = document.querySelector('.appHeader') || document.getElementById('appHeader');
    var btm = document.querySelector('.appBottomMenu') || document.querySelector('footer') || document.querySelector('.footer');
    var hdrH = hdr ? hdr.offsetHeight : 56;
    var btmH = btm ? btm.offsetHeight : 68;
    document.documentElement.style.setProperty('--hdr', (hdrH) + 'px');
    document.documentElement.style.setProperty('--bnav', (btmH + 8) + 'px');
  }
  window.addEventListener('load', apply);
  window.addEventListener('resize', apply);
  apply();
})();

function setRangeStatus(ok, text){
  var el = document.getElementById('rangeStatus'); if(!el) return;
  el.style.color = ok ? '#0b8b57' : '#b61f33';
  el.textContent = text || '';
}
function showPermTip(show){ var t=document.getElementById('permTip'); if(!t) return; t.style.display = show ? 'block' : 'none'; }

function getGPS(){
  return new Promise(function(resolve,reject){
    if(!navigator.geolocation) return reject('Geolocation not supported');
    navigator.geolocation.getCurrentPosition(
      function(pos){ resolve(pos); },
      function(err){ reject((err && err.message) ? err.message : 'Enable location to proceed'); },
      {enableHighAccuracy:true,maximumAge:0,timeout:15000}
    );
  });
}

async function logBlocked(pfrom, lat, lng, acc, deviceInfo){
  try{
    await fetch('?ajax=log', {
      method:'POST',
      headers:{'Content-Type':'application/x-www-form-urlencoded'},
      body:'pfrom='+encodeURIComponent(pfrom)+'&lat='+encodeURIComponent(lat)+'&lng='+encodeURIComponent(lng)+'&acc='+encodeURIComponent(acc)
           +'&hw='+encodeURIComponent(deviceInfo.hw)+'&model='+encodeURIComponent(deviceInfo.model)+'&fp='+encodeURIComponent(deviceInfo.fp)
    });
  }catch(e){ /* ignore */ }
}

async function doPunch(){
  var actionEl=document.getElementById('action'); if(!actionEl) return;
  var desired=actionEl.value;
  showPermTip(false);
  setRangeStatus(false,'Locating…');

  let pos;
  try { pos = await getGPS(); }
  catch(e){ setRangeStatus(false, e); showPermTip(true); return; }

  var lat = pos.coords.latitude, lng = pos.coords.longitude, acc = pos.coords.accuracy;
  document.getElementById('lat').value   = lat;
  document.getElementById('longt').value = lng;
  document.getElementById('acc').value   = acc;

  const deviceInfo = {
    hw: document.getElementById('hardwareName').value || 'Unknown',
    model: document.getElementById('hardwareModel').value || 'Unknown',
    fp: document.getElementById('fingerprint').value || ''
  };

  try{
    const rsp=await fetch('?ajax=nearest',{
      method:'POST',
      headers:{'Content-Type':'application/x-www-form-urlencoded'},
      body:'lat='+encodeURIComponent(lat)+'&lng='+encodeURIComponent(lng)+'&acc='+encodeURIComponent(acc)
    });
    const data=await rsp.json();
    if(!data.ok){ setRangeStatus(false, data.msg || 'Range check failed'); return; }

    var hint = (data.location||'Nearest')+' • ~'+data.meters+' m (±'+(data.accuracy||'?')+' m)';

    if(!data.inRange){
      await logBlocked(desired, lat, lng, acc, deviceInfo);
      setRangeStatus(false,'OUT-OF-RANGE • '+hint);
      return;
    }

    setRangeStatus(true, hint);
    document.getElementById('punchForm').submit();
  }catch(e){
    setRangeStatus(false,'Network error during range check');
  }
}

/* live timer */
(function(){
  const workedEl = document.getElementById('workedClock');
  const stateEl  = document.getElementById('runState');
  const ring     = document.getElementById('ring');
  const inTs  = <?php echo $inTime  ? (strtotime($inTime)  * 1000) : 'null'; ?>;
  const outTs = <?php echo $outTime ? (strtotime($outTime) * 1000) : 'null'; ?>;

  function fmt(sec){ const h=Math.floor(sec/3600), m=Math.floor((sec%3600)/60), s=Math.floor(sec%60);
    const pad=n=>(n<10?'0':'')+n; return pad(h)+':'+pad(m)+':'+pad(s); }
  function setProgress(secs){ var pct=Math.min(100, Math.round((secs/(8*3600))*100)); try{ ring.style.setProperty('--p', pct);}catch(e){} }
  function render(ms){ const secs=Math.max(0, Math.floor(ms/1000)); workedEl.textContent=fmt(secs); setProgress(secs); }

  if(!inTs){ workedEl.textContent='00:00:00'; setProgress(0); stateEl.textContent='Ready'; return; }
  if(inTs && !outTs){ stateEl.textContent='Running'; const tick=()=>render(Date.now()-inTs); tick(); setInterval(tick,1000); }
  else { stateEl.textContent='Completed'; render(outTs-inTs); }
})();
</script>
</body>
</html>
