<?php
/**
 * asignar_update.php — API para actualizar múltiples filas en tb_asignar (SIN TOKEN, SIN SESIÓN y SIN LINKS)
 * Entrada soportada: JSON (body), POST (form) o GET (query string).
 *
 * Parámetros:
 *  - ids: [int,int,...]   | id_gestion: "1,2,3" | ids="43"
 *  - tipo_transporte, agrup_movimiento, placa, cedula, nombre
 *  - fecha_carga (YYYY-MM-DD HH:MM[:SS] o YYYY-MM-DD)
 *  - fecha_descarga (YYYY-MM-DD HH:MM[:SS] o YYYY-MM-DD)
 *  - guias
 *
 * Efecto:
 *  UPDATE tb_asignar SET ... , status='COORDINADO' WHERE id=?
 *
 * ⚠️ Este endpoint queda abierto: protégelo con firewall, IP o una clave simple si lo expones públicamente.
 */

declare(strict_types=1);

// ===== Encabezados / 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');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }

// ===== Errores como JSON =====
ini_set('display_errors', '0');
mysqli_report(MYSQLI_REPORT_OFF);
set_error_handler(function($n,$s,$f,$l){
  http_response_code(400);
  echo json_encode(['success'=>false,'stage'=>'php_error','message'=>"PHP:$n $s @ $f:$l"]); exit;
});
set_exception_handler(function($e){
  http_response_code(400);
  echo json_encode(['success'=>false,'stage'=>'exception','message'=>$e->getMessage()]); exit;
});

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

$db = $conn ?? ($conex ?? null);
if (!$db instanceof mysqli) { http_response_code(500); echo json_encode(['success'=>false,'stage'=>'conn','message'=>'Sin conexión BD']); exit; }
mysqli_set_charset($db, 'utf8mb4');
@$db->query("SET time_zone='-05:00'");

// ===== Método =====
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  http_response_code(405);
  echo json_encode(['success'=>false,'stage'=>'method','message'=>'Método no permitido; usa POST']); exit;
}

// ===== Utilidades =====
function str_t(string $v): string { return trim($v); }

function normalizeDate(?string $v): ?string {
  $v = is_null($v) ? null : trim($v);
  if ($v === null || $v === '') return null;
  if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $v)) $v .= ' 00:00:00';
  if (preg_match('/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}$/', $v)) $v .= ':00';
  $dt = DateTime::createFromFormat('Y-m-d H:i:s', $v);
  return $dt ? $dt->format('Y-m-d H:i:s') : null;
}

function ints_from_csv_or_array($src): array {
  if (is_array($src)) return array_values(array_filter(array_map('intval', $src), fn($i)=>$i>0));
  if (is_string($src) || is_numeric($src)) {
    $txt = (string)$src;
    if (strpos($txt, ',') !== false) return array_values(array_filter(array_map('intval', explode(',', $txt)), fn($i)=>$i>0));
    $val = (int)$txt; return $val>0 ? [$val] : [];
  }
  return [];
}

// ===== Leer JSON (si hay) =====
$RAW = file_get_contents('php://input');
$IN_JSON = json_decode($RAW ?: '[]', true);
if (!is_array($IN_JSON)) $IN_JSON = [];

// ===== param() toma de JSON -> POST -> GET =====
function param($key, $default=null) {
  global $IN_JSON;
  if (array_key_exists($key, $IN_JSON)) return $IN_JSON[$key];
  if (isset($_POST[$key])) return $_POST[$key];
  if (isset($_GET[$key]))  return $_GET[$key];
  return $default;
}

// ===== IDs =====
$ids = [];
$ids = array_merge($ids, ints_from_csv_or_array(param('ids', [])));
$ids = array_merge($ids, ints_from_csv_or_array(param('id_gestion', '')));
$ids = array_values(array_unique($ids));
if (!$ids) { echo json_encode(['success'=>false,'stage'=>'validate','message'=>'Sin IDs a actualizar']); exit; }

// ===== Campos =====
$tipo  = str_t((string)param('tipo_transporte',''));
$grupo = str_t((string)param('agrup_movimiento',''));
$placa = str_t((string)param('placa',''));
$cedu  = str_t((string)param('cedula',''));
$nom   = str_t((string)param('nombre',''));
$fc    = normalizeDate((string)param('fecha_carga',''));
$fd    = normalizeDate((string)param('fecha_descarga',''));
$guia  = str_t((string)param('guias',''));

// ===== Validaciones =====
if ($tipo === '' || $grupo === '') { echo json_encode(['success'=>false,'stage'=>'validate','message'=>'Falta tipo_transporte o agrup_movimiento']); exit; }
if ($placa === '' || $nom === '')  { echo json_encode(['success'=>false,'stage'=>'validate','message'=>'Placa o nombre (conductor) vacíos']); exit; }
if (!$fc || !$fd)                  { echo json_encode(['success'=>false,'stage'=>'validate','message'=>'Fechas inválidas o ausentes']); exit; }
if (strtotime($fd) < strtotime($fc)) { echo json_encode(['success'=>false,'stage'=>'validate','message'=>'fecha_descarga < fecha_carga']); exit; }

// ===== SQL y Transacción =====
$sql = "UPDATE tb_asignar
          SET tipo=?,
              grupo=?,
              placa=?,
              numero_doc=?,
              conductor=?,
              fecha_carga=?,
              fecha_descarga=?,
              guia=?,
              status='COORDINADO'
        WHERE id = ?";

$stmt = $db->prepare($sql);
if (!$stmt) { http_response_code(500); echo json_encode(['success'=>false,'stage'=>'prepare','message'=>$db->error]); exit; }

$db->begin_transaction();
$updated   = 0;
$unchanged = [];
$not_found = [];
$failed    = [];

try {
  foreach ($ids as $id) {
    if (!$stmt->bind_param('ssssssssi', $tipo, $grupo, $placa, $cedu, $nom, $fc, $fd, $guia, $id)) {
      throw new RuntimeException('bind_param falló');
    }
    if (!$stmt->execute()) {
      $failed[] = ['id'=>$id, 'error'=>$stmt->error];
      continue;
    }
    if ($stmt->affected_rows > 0) {
      $updated += $stmt->affected_rows;
    } else {
      // Verificar existencia
      $chk = $db->prepare("SELECT id FROM tb_asignar WHERE id=? LIMIT 1");
      if ($chk) {
        $chk->bind_param('i', $id);
        $chk->execute();
        $res = $chk->get_result();
        if ($res->num_rows === 0) $not_found[] = $id;
        else $unchanged[] = $id;
        $chk->close();
      }
    }
  }

  if (!empty($failed)) {
    $db->rollback();
    http_response_code(500);
    echo json_encode([
      'success'   => false,
      'stage'     => 'execute',
      'message'   => 'Fallo al actualizar uno o más IDs',
      'failed'    => $failed,
      'not_found' => $not_found,
      'unchanged' => $unchanged,
      'updated'   => $updated
    ]); exit;
  }

  $db->commit();
  echo json_encode([
    'success'   => true,
    'message'   => 'Asignaciones procesadas.',
    'updated'   => $updated,
    'unchanged' => $unchanged,
    'not_found' => $not_found
  ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} catch (Throwable $e) {
  $db->rollback();
  http_response_code(500);
  echo json_encode(['success'=>false,'stage'=>'transaction','message'=>$e->getMessage()]);
} finally {
  $stmt->close();
}
