<?php
// api_app_guardar_impronta.php
// Inserta en tb_impronta (id, id_datadai, fecha, usuario, foto, observacion, condicion=1)
// Acepta: multipart (foto/image), JSON foto_base64, o JSON 'foto' (ruta ya existente)

declare(strict_types=1);
date_default_timezone_set('America/Guayaquil');

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }

$pathConex = realpath(__DIR__ . '/conex.php') ?: realpath(__DIR__ . '/../conex.php') ?: realpath(__DIR__ . '/../../conex.php');
if (!$pathConex) { http_response_code(500); echo json_encode(['success'=>false,'message'=>'No se encontró conex.php']); exit; }
require_once $pathConex;

$db = null;
if (isset($conn) && $conn instanceof mysqli) { $db = $conn; }
elseif (isset($db) && $db instanceof mysqli) { /* ok */ }
else { $db = $db ?? ($conn ?? null); }
if (!$db instanceof mysqli) { http_response_code(500); echo json_encode(['success'=>false,'message'=>'Sin conexión a BD']); exit; }
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$db->set_charset('utf8mb4');

// ---- Config subida ----
const IMPRONTA_DIR_REL = 'uploads/improntas';
const MAX_BYTES = 10 * 1024 * 1024;
const ALLOWED_MIMES = ['image/jpeg','image/png','image/webp','image/gif'];

function fail(int $code, string $msg, array $extra = []): void {
  http_response_code($code);
  echo json_encode(['success'=>false,'message'=>$msg,'data'=>$extra], JSON_UNESCAPED_UNICODE);
  exit;
}
function ensure_dir(string $abs): void {
  if (!is_dir($abs) && !@mkdir($abs, 0775, true) && !is_dir($abs)) {
    fail(500, 'No se pudo crear el directorio de subida', ['dir'=>$abs]);
  }
}
function finfo_mime(string $fileAbs): string {
  $finfo = new finfo(FILEINFO_MIME_TYPE);
  return $finfo->file($fileAbs) ?: 'application/octet-stream';
}
function ext_by_mime(string $mime): string {
  return match ($mime) {
    'image/jpeg' => 'jpg',
    'image/png'  => 'png',
    'image/webp' => 'webp',
    'image/gif'  => 'gif',
    default      => 'bin',
  };
}
function unique_name(string $dirAbs, string $ext): string {
  $ext = ltrim($ext, '.');
  do {
    $n = 'imp_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
  } while (file_exists($dirAbs . DIRECTORY_SEPARATOR . $n));
  return $n;
}
function save_base64_image(string $payload, string $dirAbs): string {
  $mimeClaim = 'image/jpeg';
  if (strpos($payload, 'data:') === 0) {
    if (preg_match('#^data:(image/\w+);base64,#', $payload, $m)) { $mimeClaim = strtolower($m[1]); }
    $payload = preg_replace('#^data:image/\w+;base64,#', '', $payload);
  }
  $bin = base64_decode($payload, true);
  if ($bin === false) { fail(400, 'Base64 inválido'); }
  if (strlen($bin) > MAX_BYTES) { fail(413, 'Imagen demasiado grande'); }

  $tmp = $dirAbs . DIRECTORY_SEPARATOR . 'tmp_' . bin2hex(random_bytes(3));
  file_put_contents($tmp, $bin);

  $realMime = finfo_mime($tmp);
  if (!in_array($realMime, ALLOWED_MIMES, true)) { @unlink($tmp); fail(415, 'Tipo no permitido: '.$realMime); }

  $ext = ext_by_mime($realMime);
  $final = $dirAbs . DIRECTORY_SEPARATOR . unique_name($dirAbs, $ext);
  if (!rename($tmp, $final)) { @unlink($tmp); fail(500, 'No se pudo guardar la imagen'); }
  return $final;
}

try {
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') { fail(405, 'Usa POST'); }

  // Carpeta destino: /uploads/improntas/YYYY/MM
  $subdir = date('Y') . '/' . date('m');
  $dirRel = rtrim(IMPRONTA_DIR_REL, '/\\') . '/' . $subdir;
  $dirAbs = __DIR__ . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $dirRel);
  ensure_dir($dirAbs);

  $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
  $isMultipart = stripos($contentType, 'multipart/form-data') !== false;

  $id_datadai = null;
  $usuario = null;
  $observacion = null;

  $fotoAbs = null; // ruta absoluta del archivo guardado (si se sube)
  $fotoRel = null; // ruta relativa que irá a BD (puede venir del cliente)

  if ($isMultipart) {
    // Campos
    $id_datadai  = isset($_POST['id_datadai']) ? (int)$_POST['id_datadai'] : null;
    $usuario     = isset($_POST['usuario']) ? trim((string)$_POST['usuario']) : null;
    $observacion = isset($_POST['observacion']) ? trim((string)$_POST['observacion']) : null;

    // 1) archivo en 'foto' o 'image'
    $fileField = null;
    if (!empty($_FILES['foto']['tmp_name']))   { $fileField = 'foto'; }
    if (!empty($_FILES['image']['tmp_name']))  { $fileField = $fileField ?: 'image'; }

    if ($fileField) {
      $err  = (int)($_FILES[$fileField]['error'] ?? UPLOAD_ERR_NO_FILE);
      if ($err !== UPLOAD_ERR_OK) { fail(400, 'Error de subida (código '.$err.')'); }
      $size = (int)($_FILES[$fileField]['size'] ?? 0);
      if ($size <= 0) { fail(400, 'Archivo vacío'); }
      if ($size > MAX_BYTES) { fail(413, 'Imagen demasiado grande'); }

      $tmp = $_FILES[$fileField]['tmp_name'];
      $realMime = finfo_mime($tmp);
      if (!in_array($realMime, ALLOWED_MIMES, true)) { fail(415, 'Tipo no permitido: '.$realMime); }
      $ext = ext_by_mime($realMime);
      $final = $dirAbs . DIRECTORY_SEPARATOR . unique_name($dirAbs, $ext);
      if (!move_uploaded_file($tmp, $final)) { fail(500, 'No se pudo mover la imagen'); }
      $fotoAbs = $final;
    }

    // 2) base64 (opcional)
    if (!$fotoAbs && !empty($_POST['foto_base64'])) {
      $fotoAbs = save_base64_image((string)$_POST['foto_base64'], $dirAbs);
    }

    // 3) ruta ya existente (opcional) -> se guarda tal cual
    if (!$fotoAbs && empty($_POST['foto_base64']) && !empty($_POST['foto'])) {
      $ruta = str_replace('\\','/', trim((string)$_POST['foto']));
      if (strpos($ruta, '..') !== false) { fail(400, 'Ruta de foto inválida'); }
      $fotoRel = $ruta; // se guardará directo
    }

  } else {
    // JSON
    $raw = file_get_contents('php://input') ?: '';
    $data = json_decode($raw, true);
    if (!is_array($data)) { fail(400, 'JSON inválido'); }

    $id_datadai  = isset($data['id_datadai']) ? (int)$data['id_datadai'] : null;
    $usuario     = isset($data['usuario']) ? trim((string)$data['usuario']) : null;
    $observacion = isset($data['observacion']) ? trim((string)$data['observacion']) : null;

    if (!empty($data['foto_base64'])) {
      $fotoAbs = save_base64_image((string)$data['foto_base64'], $dirAbs);
    } elseif (!empty($data['foto'])) {
      // usar ruta ya existente
      $ruta = str_replace('\\','/', trim((string)$data['foto']));
      if (strpos($ruta, '..') !== false) { fail(400, 'Ruta de foto inválida'); }
      $fotoRel = $ruta;
    }
  }

  if (!$id_datadai) { fail(400, 'id_datadai es obligatorio'); }
  if (!$usuario && isset($_SESSION['idusuario'])) { $usuario = (string)$_SESSION['idusuario']; }
  if ($usuario === null) { $usuario = ''; } // evita problemas de NULL si la columna no acepta NULL

  $fecha = date('Y-m-d');
  $condicion = 1;

  // Si se subió imagen, construir la ruta relativa final
  if ($fotoAbs && !$fotoRel) {
    $fotoRel = str_replace(['\\'], '/', $dirRel . '/' . basename($fotoAbs));
  }

  // INSERT
  $sql = "INSERT INTO tb_impronta (id_datadai, fecha, usuario, foto, observacion, condicion)
          VALUES (?, ?, ?, ?, ?, ?)";
  $stmt = $db->prepare($sql);
  $stmt->bind_param('issssi', $id_datadai, $fecha, $usuario, $fotoRel, $observacion, $condicion);
  $stmt->execute();

  $idNew = (int)$db->insert_id;
  $rows  = $stmt->affected_rows;
  $stmt->close();

  echo json_encode([
    'success' => true,
    'message' => 'Impronta guardada correctamente',
    'data' => [
      'id' => $idNew,
      'rows_affected' => $rows,
      'id_datadai' => $id_datadai,
      'fecha' => $fecha,
      'usuario' => $usuario,
      'foto' => $fotoRel, // puede ser null si no enviaste nada
      'observacion' => $observacion,
      'condicion' => $condicion
    ]
  ], JSON_UNESCAPED_UNICODE);

} catch (Throwable $e) {
  fail(400, 'Error: ' . $e->getMessage());
}
