<?php
// absensi_api.php — Disco Smile
date_default_timezone_set('Asia/Jakarta');
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');

try {
  $pdo = new PDO('sqlite:' . __DIR__ . '/absensi.db');
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  init_db($pdo);
  upgrade_schema($pdo);
} catch (Exception $e) {
  echo json_encode(['ok'=>false, 'error'=>'DB error: '.$e->getMessage()]); exit;
}

$input  = json_decode(file_get_contents('php://input'), true) ?: [];
$action = $input['action'] ?? '';

switch ($action) {
  case 'save_checkin':  save_checkin($pdo, $input); break;
  case 'list_recent':   list_recent($pdo, $input); break;
  case 'list_by_month': list_by_month($pdo, $input); break;
  default: echo json_encode(['ok'=>false, 'error'=>'Unknown action']);
}

/* ------------------ Schema ------------------ */
function init_db(PDO $pdo){
  $pdo->exec("CREATE TABLE IF NOT EXISTS employees (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT UNIQUE,
    created_at INTEGER
  )");

  $pdo->exec("CREATE TABLE IF NOT EXISTS attendance (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    emp_id INTEGER,
    name TEXT,
    date_key TEXT,       -- YYYY-MM-DD
    time_str TEXT,       -- HH:mm:ss
    ts INTEGER,          -- unix time
    late_minutes INTEGER,
    device_model TEXT,
    ua TEXT,
    ip TEXT,
    photo_path TEXT
  )");
}

function upgrade_schema(PDO $pdo){
  // Tambah kolom signature_path jika belum ada
  $cols = $pdo->query("PRAGMA table_info(attendance)")->fetchAll(PDO::FETCH_ASSOC);
  $names = array_map(fn($c)=>$c['name'], $cols);
  if (!in_array('signature_path', $names, true)) {
    try { $pdo->exec("ALTER TABLE attendance ADD COLUMN signature_path TEXT"); } catch(Exception $e){}
  }
}

/* ------------------ Helpers ------------------ */
function ensure_employee(PDO $pdo, string $name): int {
  $st=$pdo->prepare("SELECT id FROM employees WHERE name=?");
  $st->execute([$name]);
  $id=$st->fetchColumn();
  if($id) return (int)$id;
  $st=$pdo->prepare("INSERT INTO employees(name, created_at) VALUES(?, ?)");
  $st->execute([$name, time()]);
  return (int)$pdo->lastInsertId();
}

function save_file_from_b64(string $b64, string $dir, string $baseName, string $ext): array {
  if (strpos($b64, 'base64,') !== false) $b64 = substr($b64, strpos($b64, 'base64,') + 7);
  $data = base64_decode($b64);
  if (!$data) return [false, 'Gagal decode data'];

  if (!is_dir($dir)) { if (!mkdir($dir, 0775, true)) return [false, 'Gagal membuat folder']; }
  $filename = $baseName . '-' . time() . ".$ext";
  $path = rtrim($dir, '/').'/'.$filename;

  if (file_put_contents($path, $data) === false) return [false, 'Gagal menyimpan file'];
  $public = str_replace(__DIR__.'/', '', $path);
  return [true, $public];
}

/* ------------------ Actions ------------------ */
function save_checkin(PDO $pdo, array $in){
  $name = trim($in['name'] ?? '');
  $date_key = trim($in['date_key'] ?? '');
  $time_str = trim($in['time_str'] ?? '');
  $late = (int)($in['late_minutes'] ?? 0);
  $device_model = trim($in['device_model'] ?? '');
  $ua = trim($in['ua'] ?? ($_SERVER['HTTP_USER_AGENT'] ?? ''));
  $ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? ($in['ip'] ?? '');
  $photo_b64 = $in['photo_b64'] ?? '';
  $signature_b64 = $in['signature_b64'] ?? '';

  if ($name === '' || $date_key === '' || $time_str === '') {
    echo json_encode(['ok'=>false, 'error'=>'Data wajib: name, date_key, time_str']); return;
  }

  // Foto hanya untuk Miss Natasya
  $shouldSavePhoto = (strcasecmp($name, 'Miss Natasya') === 0);
  $photo_path = null;
  if ($shouldSavePhoto && $photo_b64 !== '') {
    list($okP, $photoPathOrErr) = save_file_from_b64($photo_b64, __DIR__."/uploads/absensi/$date_key", safe_name($name), 'jpg');
    if (!$okP) { echo json_encode(['ok'=>false, 'error'=>$photoPathOrErr]); return; }
    $photo_path = $photoPathOrErr;
  }

  // Signature PNG transparan — disimpan untuk semua
  $signature_path = null;
  if ($signature_b64 !== '') {
    list($okS, $sigPathOrErr) = save_file_from_b64($signature_b64, __DIR__."/uploads/ttd/$date_key", safe_name($name), 'png');
    if (!$okS) { echo json_encode(['ok'=>false, 'error'=>$sigPathOrErr]); return; }
    $signature_path = $sigPathOrErr;
  }

  $emp_id = ensure_employee($pdo, $name);
  $ts = time();

  $pdo->beginTransaction();
  try{
    // Cek apakah sudah ada absen hari ini
    $st=$pdo->prepare("SELECT id, photo_path, signature_path FROM attendance WHERE name=? AND date_key=?");
    $st->execute([$name, $date_key]);
    $row=$st->fetch(PDO::FETCH_ASSOC);

    if($row){
      // kalau bukan Miss Natasya namun sebelumnya ada foto -> hapus
      if(!$shouldSavePhoto && !empty($row['photo_path'])){
        $old = __DIR__ . '/' . $row['photo_path'];
        if(is_file($old)) @unlink($old);
        $photo_path = null;
      }
      // update
      $stU=$pdo->prepare("UPDATE attendance
        SET emp_id=?, time_str=?, ts=?, late_minutes=?, device_model=?, ua=?, ip=?, photo_path=?, signature_path=?
        WHERE id=?");
      $stU->execute([
        $emp_id, $time_str, $ts, $late, $device_model, $ua, $ip,
        $photo_path, $signature_path ?: $row['signature_path'],
        (int)$row['id']
      ]);
    }else{
      // insert baru
      $stI=$pdo->prepare("INSERT INTO attendance(emp_id, name, date_key, time_str, ts, late_minutes, device_model, ua, ip, photo_path, signature_path)
                          VALUES (?,?,?,?,?,?,?,?,?,?,?)");
      $stI->execute([$emp_id, $name, $date_key, $time_str, $ts, $late, $device_model, $ua, $ip, $photo_path, $signature_path]);
    }

    $pdo->commit();
  }catch(Exception $e){
    $pdo->rollBack();
    echo json_encode(['ok'=>false,'error'=>'Gagal simpan: '.$e->getMessage()]); return;
  }

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

function list_recent(PDO $pdo, array $in){
  $limit = (int)($in['limit'] ?? 50);
  if($limit < 1) $limit = 50;
  if($limit > 200) $limit = 200;

  $date_key = trim($in['date_key'] ?? '');
  if($date_key !== ''){
    $st = $pdo->prepare("SELECT name, date_key, time_str, late_minutes, device_model, ts, signature_path
                         FROM attendance WHERE date_key = ? ORDER BY ts DESC LIMIT ?");
    $st->execute([$date_key, $limit]);
  }else{
    $st = $pdo->prepare("SELECT name, date_key, time_str, late_minutes, device_model, ts, signature_path
                         FROM attendance ORDER BY ts DESC LIMIT ?");
    $st->execute([$limit]);
  }
  $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
  $out = array_map(fn($r)=>[
    'name'=>$r['name'],
    'date_key'=>$r['date_key'],
    'time_str'=>$r['time_str'],
    'late_minutes'=>(int)($r['late_minutes'] ?? 0),
    'device_model'=>$r['device_model'],
    'ts'=>(int)$r['ts'],
    'signature_path'=>$r['signature_path'] ?? null
  ], $rows);

  echo json_encode(['ok'=>true, 'data'=>$out]);
}

function list_by_month(PDO $pdo, array $in){
  $month = trim($in['month'] ?? ''); // "YYYY-MM"
  if(!preg_match('~^\d{4}-\d{2}$~', $month)){
    echo json_encode(['ok'=>false, 'error'=>'Format bulan tidak valid (YYYY-MM).']); return;
  }
  $st = $pdo->prepare("SELECT name, date_key, time_str, late_minutes, device_model, ts, signature_path
                       FROM attendance
                       WHERE date_key LIKE ? || '%'
                       ORDER BY ts DESC");
  $st->execute([$month]);
  $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];

  $out = array_map(fn($r)=>[
    'name'=>$r['name'],
    'date_key'=>$r['date_key'],
    'time_str'=>$r['time_str'],
    'late_minutes'=>(int)($r['late_minutes'] ?? 0),
    'device_model'=>$r['device_model'],
    'ts'=>(int)$r['ts'],
    'signature_path'=>$r['signature_path'] ?? null
  ], $rows);

  echo json_encode(['ok'=>true, 'data'=>$out]);
}

/* ------------------ Utils ------------------ */
function safe_name(string $s): string {
  return preg_replace('~[^a-zA-Z0-9_-]+~', '_', strtolower($s));
}
