<?php
// api_app/incidente_guardar.php — Crea o actualiza incidentes (INSERT/UPDATE según incident_id)
// Respuestas JSON claras. Acepta JSON o form-data/x-www-form-urlencoded.
// Requiere una conexión mysqli en conex.php (ej. $conn o $conex).

declare(strict_types=1);

/* ===== Encabezados y CORS ===== */
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;
}

/* ===== (Opcional) Sesión / Auth ===== */
// session_start();
// if (!isset($_SESSION['ingreso']) || $_SESSION['ingreso'] !== 'YES') {
//   http_response_code(401);
//   echo json_encode(['success'=>false,'message'=>'No autorizado']);
//   exit;
// }

/* ===== Conexión BD ===== */
$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 = $conn ?? ($conex ?? null);
if (!$db || !($db instanceof mysqli)) {
  http_response_code(500);
  echo json_encode(['success'=>false,'message'=>'Conexión BD no disponible']);
  exit;
}
mysqli_set_charset($db, 'utf8mb4');
@mysqli_query($db, "SET time_zone = '-05:00'");

/* ===== Util: leer input flexible ===== */
function read_request_payload(): array {
  $ctype = $_SERVER['CONTENT_TYPE'] ?? $_SERVER['HTTP_CONTENT_TYPE'] ?? '';
  if (stripos($ctype, 'application/json') !== false) {
    $raw = file_get_contents('php://input');
    $data = json_decode($raw, true);
    return is_array($data) ? $data : [];
  }
  // Soporta form-data / x-www-form-urlencoded
  return $_POST + $_GET;
}

/* ===== Campos permitidos/normalización ===== */
$INPUT = read_request_payload();

/* Alias para compatibilidad: algunos códigos usan "reponsabilidad" (con typo).
   Normalizamos a "responsabilidad" si llega con ese nombre. */
if (!isset($INPUT['responsabilidad']) && isset($INPUT['reponsabilidad'])) {
  $INPUT['responsabilidad'] = $INPUT['reponsabilidad'];
}

$incident_id = (int)($INPUT['incident_id'] ?? 0);  // 0 => crear, >0 => actualizar

// Whitelist de columnas (nombre => tipo mysqli: i=int, s=string)
$COLUMNS = [
  'id_zona'          => 'i',
  'id_parte'         => 'i',
  'id_novedad'       => 'i',
  'id_tarja'         => 'i',
  'id_datadai'       => 'i',
  'observacion'      => 's',
  'id_medida'        => 'i',
  'medida'           => 's',
  'foto'             => 's',
  'responsabilidad'  => 's',
  'validar'          => 's', // si es 0/1 o 'S'/'N', ajústalo a int si aplica
  'condicion'        => 'i', // normalmente 1=activo, 0=inactivo
];

// Construye arreglo de datos válidos (omite null/'' si quieres)
$payload = [];
foreach ($COLUMNS as $key => $type) {
  if (array_key_exists($key, $INPUT)) {
    $val = $INPUT[$key];
    if ($type === 'i') {
      // Normaliza enteros (null vacíos -> null)
      if ($val === '' || $val === null) {
        $payload[$key] = null;
      } else {
        $payload[$key] = (int)$val;
      }
    } else {
      // strings: permite vacío, trim
      $payload[$key] = is_null($val) ? null : trim((string)$val);
    }
  }
}

/* ===== Validaciones mínimas =====
   - Para INSERT puedes exigir ciertos campos.
   - Para UPDATE solo se actualizarán los campos enviados. */
if ($incident_id <= 0) {
  // Reglas mínimas recomendadas (ajusta a tu negocio):
  $faltantes = [];
  foreach (['id_zona','id_parte','id_novedad'] as $req) {
    if (!array_key_exists($req, $payload)) { $faltantes[] = $req; }
  }
  if ($faltantes) {
    http_response_code(422);
    echo json_encode([
      'success' => false,
      'message' => 'Faltan campos obligatorios para crear',
      'missing' => $faltantes
    ]);
    exit;
  }
} else {
  // Para UPDATE, si no se envía ningún campo a actualizar, es error
  if (!$payload) {
    http_response_code(400);
    echo json_encode([
      'success' => false,
      'message' => 'No hay campos para actualizar. Envía al menos un campo válido de la whitelist.'
    ]);
    exit;
  }
}

/* ===== Helper para bind dinámico ===== */
function build_bind_params(array $types, array $values): array {
  // Retorna array: [string $typeString, array $refs] para usar con call_user_func_array
  $typeStr = implode('', $types);
  $refs = [];
  $refs[] = &$typeStr;
  foreach ($values as $i => $v) {
    $refs[] = &$values[$i];
  }
  return [$typeStr, $refs];
}

/* ===== Inserción o Actualización ===== */
try {
  if ($incident_id <= 0) {
    // INSERT
    $cols = array_keys($payload);
    $types = [];
    $values = [];
    foreach ($cols as $c) {
      $types[] = $COLUMNS[$c]; // tipo
      $values[] = $payload[$c]; // valor
    }

    if (!$cols) {
      http_response_code(400);
      echo json_encode(['success'=>false,'message'=>'Nada que insertar']);
      exit;
    }

    $placeholders = implode(',', array_fill(0, count($cols), '?'));
    $colList = implode(',', $cols);
    $sql = "INSERT INTO tb_incidente ($colList) VALUES ($placeholders)";
    $stmt = $db->prepare($sql);
    if (!$stmt) { throw new RuntimeException('Prepare failed: '.$db->error); }

    // bind
    [$typeStr, $bindRefs] = build_bind_params($types, $values);
    call_user_func_array([$stmt, 'bind_param'], $bindRefs);

    if (!$stmt->execute()) {
      throw new RuntimeException('Execute failed: '.$stmt->error);
    }

    $newId = (int)$db->insert_id;
    $stmt->close();

    echo json_encode([
      'success' => true,
      'mode'    => 'created',
      'id'      => $newId,
      'data'    => $payload
    ]);
    exit;

  } else {
    // UPDATE (solo columnas enviadas)
    $cols = array_keys($payload);
    $sets = [];
    $types = [];
    $values = [];

    foreach ($cols as $c) {
      $sets[] = "$c = ?";
      $types[] = $COLUMNS[$c];
      $values[] = $payload[$c];
    }
    $types[] = 'i';          // para el WHERE idincidente = ?
    $values[] = $incident_id;

    $setStr = implode(', ', $sets);
    $sql = "UPDATE tb_incidente SET $setStr WHERE idincidente = ?";
    $stmt = $db->prepare($sql);
    if (!$stmt) { throw new RuntimeException('Prepare failed: '.$db->error); }

    [$typeStr, $bindRefs] = build_bind_params($types, $values);
    call_user_func_array([$stmt, 'bind_param'], $bindRefs);

    if (!$stmt->execute()) {
      throw new RuntimeException('Execute failed: '.$stmt->error);
    }

    $affected = $stmt->affected_rows;
    $stmt->close();

    echo json_encode([
      'success'  => true,
      'mode'     => 'updated',
      'id'       => $incident_id,
      'affected' => $affected,
      'data'     => $payload
    ]);
    exit;
  }

} catch (Throwable $e) {
  http_response_code(500);
  echo json_encode([
    'success' => false,
    'message' => 'Error en el servidor',
    'error'   => $e->getMessage()
  ]);
  exit;
}
