<?php
// /sbm/public/attendance_submit.php
declare(strict_types=1);

ini_set('display_errors','1');   // staging: 1
error_reporting(E_ALL);
date_default_timezone_set('Asia/Kolkata');

require __DIR__ . '/session_boot.php';
if (empty($_SESSION['user_id'])) { http_response_code(403); exit('Not logged in'); }

require __DIR__ . '/../includes/db.php';
try { $pdo->exec("SET time_zone = '+05:30'"); } catch (Throwable $e) {}

header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');

$DEBUG = isset($_GET['debug']) && $_GET['debug'] === '1';

/* helpers */
function cleanN(?string $s, int $n): ?string {
  if ($s === null) return null;
  $s = trim($s);
  if ($s === '') return '';
  return function_exists('mb_substr') ? mb_substr($s, 0, $n) : substr($s, 0, $n);
}
function getCols(PDO $pdo, string $table): array {
  $sql = "SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, CHARACTER_SET_NAME
          FROM information_schema.columns
          WHERE table_schema = DATABASE() AND table_name = :t";
  $st = $pdo->prepare($sql); $st->execute([':t'=>$table]);
  $out = [];
  foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $r) {
    $k = strtolower($r['COLUMN_NAME']); $out[$k] = $r;
  }
  return $out;
}

/* inputs */
$eid    = (int)$_SESSION['user_id'];
$action = strtolower(trim((string)($_POST['action'] ?? '')));

$latRaw = trim((string)($_POST['lat'] ?? ''));
$lngRaw = trim((string)($_POST['lng'] ?? ''));
$accRaw = trim((string)($_POST['acc'] ?? ''));
$addr   = cleanN((string)($_POST['addr'] ?? ''), 255);

$lat = ($latRaw === '' ? null : (float)$latRaw);
$lng = ($lngRaw === '' ? null : (float)$lngRaw);
$acc = ($accRaw === '' ? null : (float)$accRaw);

/* validate */
if (!in_array($action, ['checkin','checkout'], true)) { http_response_code(400); exit('Invalid action'); }
if ($lat === null || $lng === null) { http_response_code(422); exit('Location required'); }
if ($lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) { http_response_code(422); exit('Invalid coordinates'); }

/* server-side reverse geocode if address empty */
if (($addr === null || $addr === '') && $lat !== null && $lng !== null) {
  $cfg = @require __DIR__ . '/../includes/config.php';
  $googleKey = (string)($cfg['google_key'] ?? '');

  if ($googleKey !== '') {
    $url = "https://maps.googleapis.com/maps/api/geocode/json?latlng={$lat},{$lng}&key={$googleKey}";
    try {
      $ctx = stream_context_create(['http'=>['timeout'=>6]]);
      $resp = @file_get_contents($url, false, $ctx);
      if ($resp) {
        $j = json_decode($resp, true);
        $got = $j['results'][0]['formatted_address'] ?? '';
        if (!empty($got)) $addr = $got;
      }
    } catch (Throwable $e) {}
  }
  if ($addr === null || $addr === '') {
    $url = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat={$lat}&lon={$lng}";
    $opts = ['http'=>[
      'method'=>'GET',
      'header'=>"Accept-Language: en\r\nUser-Agent: WS-Attendance/1.0 (+bizorm.com)\r\n",
      'timeout'=>6
    ]];
    try {
      $resp = @file_get_contents($url, false, stream_context_create($opts));
      if ($resp) {
        $j = json_decode($resp, true);
        $got = (string)($j['display_name'] ?? '');
        if (!empty($got)) $addr = $got;
      }
    } catch (Throwable $e) {}
  }
  $addr = cleanN($addr ?? '', 255);
  if ($addr === '') $addr = null;
}

/* fetch executive name */
$ename = null;
try {
  $q = $pdo->prepare("SELECT full_name FROM executives WHERE id = :id");
  $q->execute([':id'=>$eid]);
  $ename = $q->fetchColumn() ?: null;
} catch (Throwable $e) { $ename = null; }

/* build INSERT from real columns */
$cols = getCols($pdo, 'attendance_logs');

$fields = [];
$params = [];
$bind   = [];

$fields[]='executive_id'; $params[]=':eid'; $bind[':eid']=$eid;
$fields[]='action';       $params[]=':act'; $bind[':act']=$action;

if (isset($cols['executive_name'])) { $fields[]='executive_name'; $params[]=':ename'; $bind[':ename']=$ename; }
if (isset($cols['lat']))            { $fields[]='lat';            $params[]=':lat';   $bind[':lat']=$lat; }
if (isset($cols['lng']))            { $fields[]='lng';            $params[]=':lng';   $bind[':lng']=$lng; }
if (isset($cols['accuracy_m']))     { $fields[]='accuracy_m';     $params[]=':acc';   $bind[':acc']=$acc; }
elseif (isset($cols['accuracy']))   { $fields[]='accuracy';       $params[]=':acc';   $bind[':acc']=$acc; }
if (isset($cols['address']))        { $fields[]='address';        $params[]=':addr';  $bind[':addr']=($addr!=='' ? $addr : null); }
if (isset($cols['created_at']))     { $fields[]='created_at';     $params[]='NOW()'; }

$fieldsSql = '`' . implode('`,`', $fields) . '`';
$paramsSql = implode(',', $params);
$sql = "INSERT INTO `attendance_logs` ($fieldsSql) VALUES ($paramsSql)";

try {
  $st = $pdo->prepare($sql);
  $st->execute($bind);

$_SESSION['flash'] = ($action === 'checkin')
  ? 'Check-in successful ✅'
  : 'Check-out successful ✅';

session_write_close();

if ($action === 'checkin') {
  // go back where the user came from
  $target = $_SESSION['redirect_target'] ?? 'index.php';
  unset($_SESSION['redirect_target']);
  header("Location: /sbm/public/{$target}");
} else {
  header('Location: /sbm/public/attendance.php');
}
exit;


} catch (Throwable $e) {
  error_log('ATTENDANCE_INSERT_FAIL: '.$e->getMessage()
    .' | SQL: '.$sql
    .' | BIND: '.json_encode($bind, JSON_UNESCAPED_UNICODE));

  http_response_code(500);
  if ($DEBUG) {
    header('Content-Type: text/plain; charset=UTF-8');
    echo "Attendance insert failed (debug mode)\n\n";
    echo "Error: ".$e->getMessage()."\n\n";
    echo "SQL:\n$sql\n\n";
    echo "BIND:\n".json_encode($bind, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE)."\n\n";
    echo "Detected columns:\n";
    foreach ($cols as $k=>$r) {
      echo " - $k  type={$r['DATA_TYPE']}  nullable={$r['IS_NULLABLE']}  charset={$r['CHARACTER_SET_NAME']}\n";
    }
    exit;
  } else {
    exit('Attendance insert failed');
  }
}
