<?php 
// guardar_tarja.php
// Guarda TARJA (tb_tarja) + incidentes (tb_incidente) desde JSON o POST.
//
// Novedades clave de esta versión:
// - Acepta "application/json" (raw body) y también form-data / x-www-form-urlencoded.
// - Si vienes con form-data y mandas 'tarja' e 'incidentes' como strings JSON, los parsea.
// - Modo diagnóstico: agrega ?_debug=1 para ver por qué el cuerpo llega vacío (no rompe el JSON normal).
//
// Reglas de negocio se mantienen:
// - Secuencia GLOBAL: numero_auto asciende 1,2,3,... (sin año).
// - siglas = 'D' + sigla de tb_bodega (por id_datadai).
// - numerotarja = siglas + numero_auto(4 dígitos) -> p.ej. DQ0003.
// - fechatarja = fecha sistema 'Y-m-d'.
// - ae14 y ae15: ENTERO 0..9; ae1..ae13 y ai1..ai14: banderas 0/1.
// - INCIDENTE: acepta y guarda 'grave' (0/1).

declare(strict_types=1);

// ======= CONFIG =======
const NUM_AUTO_PAD = 4;   // 4 dígitos para numero_auto con ceros
const SIGLA_PREFIX = 'D'; // Prefijo para siglas finales

// ---------- Encabezados CORS / JSON ----------
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; }

date_default_timezone_set('America/Guayaquil');
session_start();
$id_usuario = $_SESSION['idusuario'] ?? null;

// ---------- Carga conexión ----------
$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;

// Detectar handler mysqli ($conn o $db)
$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 la base de datos']); exit; }

// mysqli: errores como excepciones
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$db->set_charset('utf8mb4');

// ---------- Utilidades ----------
function get_req_header(string $name): ?string {
  $key = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
  return $_SERVER[$key] ?? null;
}

/**
 * Lee el cuerpo del request.
 * 1) Si Content-Type es JSON => decodifica php://input.
 * 2) Si no hay JSON, intenta armar desde $_POST:
 *    - Si existen 'tarja' e 'incidentes' como strings JSON, los decodifica.
 *    - Si vienen campos sueltos de tarja (ej. id_datadai, ae1...), arma ['tarja'=>..., 'incidentes'=>[]].
 */
function body_json(): array {
  $ct = get_req_header('Content-Type') ?? '';
  $raw = file_get_contents('php://input') ?: '';

  // Caso 1: JSON crudo declarado en header
  if (stripos($ct, 'application/json') !== false) {
    $data = json_decode($raw, true);
    if (is_array($data)) return $data;
    throw new RuntimeException('JSON inválido o vacío (application/json declarado)');
  }

  // Caso 2: Intentar JSON aunque no se declaró correctamente el header
  if ($raw !== '') {
    $try = json_decode($raw, true);
    if (is_array($try)) return $try;
  }

  // Caso 3: Form-data o x-www-form-urlencoded
  if (!empty($_POST)) {
    $data = [];

    // ¿Llegaron como strings JSON?
    if (isset($_POST['tarja'])) {
      $t = $_POST['tarja'];
      $data['tarja'] = is_string($t) ? json_decode($t, true) : $t;
      if (!is_array($data['tarja'])) { throw new RuntimeException('Campo "tarja" no es JSON válido'); }
    }
    if (isset($_POST['incidentes'])) {
      $i = $_POST['incidentes'];
      // puede venir como JSON o como '[]' / cadena vacía
      $tmp = is_string($i) ? json_decode($i, true) : $i;
      if ($tmp === null && $_POST['incidentes'] !== 'null') { throw new RuntimeException('Campo "incidentes" no es JSON válido'); }
      $data['incidentes'] = is_array($tmp) ? $tmp : [];
    }

    // Si no vinieron como strings JSON, armar tarja desde claves planas
    if (!isset($data['tarja'])) {
      $tarja = [];
      foreach ($_POST as $k => $v) {
        // sólo mapear posibles campos de tarja; si no estás seguro, mapea todo
        $tarja[$k] = $v;
      }
      $data['tarja'] = $tarja;
    }
    if (!isset($data['incidentes'])) {
      $data['incidentes'] = []; // si no vinieron, lista vacía
    }

    return $data;
  }

  // Nada útil
  throw new RuntimeException('JSON inválido o vacío');
}

function getv(array $a, string $k, $default=null) { return array_key_exists($k, $a) ? $a[$k] : $default; }
function toInt($v): ?int { return ($v === null || $v === '') ? null : (int)$v; }
function toStr($v): ?string { if ($v === null) return null; $s = trim((string)$v); return ($s === '') ? null : $s; }
function toBoolInt($v): ?int {
  if ($v === null || $v === '') return null;
  if (is_bool($v)) return $v ? 1 : 0;
  $s = strtolower((string)$v);
  return in_array($s, ['1','true','si','sí','yes','y','on'], true) ? 1 : 0;
}

/** Guarda imagen base64 en /uploads/incidentes/YYYY/MM/ y retorna ruta relativa. */
function save_base64_image(?string $base64, string $prefix='inc'): ?string {
  if (!$base64) return null;
  $mime = 'image/jpeg';
  if (strpos($base64, 'data:') === 0) {
    if (preg_match('#^data:(image/\w+);base64,#', $base64, $m)) { $mime = $m[1]; }
    $base64 = preg_replace('#^data:image/\w+;base64,#', '', $base64);
  }
  $bin = base64_decode($base64, true);
  if ($bin === false) return null;

  $ext = 'jpg';
  if ($mime === 'image/png') $ext = 'png';
  elseif ($mime === 'image/webp') $ext = 'webp';

  $subdir = date('Y') . '/' . date('m');
  $baseDir = __DIR__ . '/uploads/incidentes/' . $subdir;
  if (!is_dir($baseDir)) { if (!@mkdir($baseDir, 0775, true) && !is_dir($baseDir)) { return null; } }
  $fname = $prefix . '_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
  $pathAbs = $baseDir . '/' . $fname;
  if (file_put_contents($pathAbs, $bin) === false) return null;

  return 'uploads/incidentes/' . $subdir . '/' . $fname;
}

// ---------- Validación mínima ----------
function validar_tarja(array $t): void {
  $oblig = ['id_datadai'];
  foreach ($oblig as $k) {
    if (!isset($t[$k]) || $t[$k] === '' || $t[$k] === null) {
      throw new InvalidArgumentException("Falta campo obligatorio en tarja: $k");
    }
  }
}

// ae1..ae13 y ai1..ai14: banderas 0/1. ae14/ae15: ENTERO clamp 0..9
function normalizar_ae_ai(array &$t): void {
  if (array_key_exists('e12', $t) && !array_key_exists('ae12', $t)) { $t['ae12'] = $t['e12']; }

  for ($i=1; $i<=13; $i++) {
    $k = "ae{$i}";
    $t[$k] = toBoolInt(getv($t, $k, null));
  }

  for ($i=14; $i<=15; $i++) {
    $k = "ae{$i}";
    $v = toInt(getv($t, $k, null));
    if ($v !== null) {
      if ($v < 0) $v = 0;
      if ($v > 9) $v = 9;
    }
    $t[$k] = $v;
  }

  for ($i=1; $i<=14; $i++) {
    $k = "ai{$i}";
    $t[$k] = toBoolInt(getv($t, $k, null));
  }
}

// ---------- Lógica principal ----------
$inTransaction = false;

try {
  $in = body_json();

  // modo diagnóstico opcional
  if (isset($_GET['_debug']) && $_GET['_debug'] == '1') {
    echo json_encode([
      'success'=>true,
      'debug'=>[
        'content_type'=> get_req_header('Content-Type'),
        'php_input_len'=> strlen(file_get_contents('php://input') ?: ''),
        '_post_keys'=> array_keys($_POST),
        'has_tarja'=> isset($in['tarja']),
        'has_incidentes'=> isset($in['incidentes']),
      ]
    ], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $tarja = getv($in, 'tarja', []);
  if (!is_array($tarja)) { throw new InvalidArgumentException('Objeto "tarja" inválido'); }
  validar_tarja($tarja);
  normalizar_ae_ai($tarja);

  $incidentes = getv($in, 'incidentes', []);
  if ($incidentes !== null && !is_array($incidentes)) { throw new InvalidArgumentException('"incidentes" debe ser un arreglo o ausente'); }
  $incidentes = $incidentes ?: [];

  // Transacción
  $db->begin_transaction();
  $inTransaction = true;

  // === 1) Secuencia GLOBAL (sin año) ===
  // Requiere: tb_seq_numero_auto (id=1, val=<último>).
  $db->query("UPDATE tb_seq_numero_auto SET val = LAST_INSERT_ID(val + 1) WHERE id = 1");
  $res = $db->query("SELECT LAST_INSERT_ID() AS next_num");
  $row = $res->fetch_assoc();
  $numero_auto_generado = (int)$row['next_num'];
  $numero_auto_fmt = str_pad((string)$numero_auto_generado, NUM_AUTO_PAD, '0', STR_PAD_LEFT); // 4 dígitos

  // === 2) SIGLAS desde tb_datadai -> tb_bodega ===
  $id_datadai = toInt(getv($tarja,'id_datadai', null));
  $sqlSigla = "SELECT b.sigla
               FROM tb_datadai d
               INNER JOIN tb_bodega b ON b.idbodega = d.id_bodega
               WHERE d.condicion = 1 AND d.iddatadai = ?";
  $stmtS = $db->prepare($sqlSigla);
  $stmtS->bind_param('i', $id_datadai);
  $stmtS->execute();
  $resS = $stmtS->get_result();
  $rowS = $resS->fetch_assoc();
  $stmtS->close();

  if (!$rowS || !isset($rowS['sigla'])) {
    throw new InvalidArgumentException("No se encontró sigla para id_datadai={$id_datadai} con condicion=1");
  }

  // === 3) Construir siglas/numerotarja/fecha sistema ===
  $sigla_bodega = (string)$rowS['sigla'];             // p.ej. 'Q'
  $siglas_final = SIGLA_PREFIX . $sigla_bodega;       // p.ej. 'DQ'
  $numerotarja  = $siglas_final . $numero_auto_fmt;   // p.ej. 'DQ0003'
  $fechatarja   = date('Y-m-d');                      // 'Y-m-d'

  // -------- Insert TARJA --------
  $sqlTarja = "INSERT INTO tb_tarja (
    siglas, numero_auto, numerotarja, fechatarja, coordinador,
    id_origen, id_regimen, id_datadai, id_inspeccion, id_destino,
    kilometraje, carga, combustible,
    ae1, ae2, ae3, ae4, ae5, ae6, ae7, ae8, ae9, ae10, ae11, ae12, ae13, ae14, ae15,
    ai1, ai2, ai3, ai4, ai5, ai6, ai7, ai8, ai9, ai10, ai11, ai12, ai13, ai14,
    observacion, id_tag, sin_tag, condicion
  ) VALUES (
    ?, ?, ?, ?, ?,
    ?, ?, ?, ?, ?,
    ?, ?, ?,
    ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
    ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
    ?, ?, ?, ?
  )";

  $stmtT = $db->prepare($sqlTarja);

  $siglas        = $siglas_final;
  $numero_auto   = $numero_auto_generado;
  $coordinador   = toStr(getv($tarja,'coordinador', null));

  $id_origen     = toInt(getv($tarja,'id_origen', null));
  $id_regimen    = toInt(getv($tarja,'id_regimen', null));
  $id_inspeccion = toInt(getv($tarja,'id_inspeccion', null));
  $id_destino    = toInt(getv($tarja,'id_destino', null));
  $kilometraje   = toInt(getv($tarja,'kilometraje', null));

  $carga         = toStr(getv($tarja,'carga', null));
  $combustible   = toStr(getv($tarja,'combustible', null));

  $ae = [];
  for ($i=1; $i<=15; $i++) { $ae[$i] = toInt(getv($tarja, "ae{$i}", null)); }
  $ai = [];
  for ($i=1; $i<=14; $i++) { $ai[$i] = toInt(getv($tarja, "ai{$i}", null)); }

  $observacion = toStr(getv($tarja,'observacion', null));
  $id_tag      = toInt(getv($tarja,'id_tag', null));
  $sin_tag     = toBoolInt(getv($tarja,'sin_tag', null));
  $condicion   = toInt(getv($tarja,'condicion', 1));

  // TIPOS: (s i s s s) + 6i + 2s + 15i + 14i + (s + 3i)
  $types = 'sisss' . str_repeat('i', 6) . 'ss' . str_repeat('i', 15) . str_repeat('i', 14) . 's' . str_repeat('i', 3);

  $stmtT->bind_param(
    $types,
    $siglas, $numero_auto, $numerotarja, $fechatarja, $coordinador,
    $id_origen, $id_regimen, $id_datadai, $id_inspeccion, $id_destino, $kilometraje,
    $carga, $combustible,
    $ae[1], $ae[2], $ae[3], $ae[4], $ae[5], $ae[6], $ae[7], $ae[8], $ae[9], $ae[10], $ae[11], $ae[12], $ae[13], $ae[14], $ae[15],
    $ai[1], $ai[2], $ai[3], $ai[4], $ai[5], $ai[6], $ai[7], $ai[8], $ai[9], $ai[10], $ai[11], $ai[12], $ai[13], $ai[14],
    $observacion, $id_tag, $sin_tag, $condicion
  );
  $stmtT->execute();
  $id_tarja = (int)$db->insert_id;
  $stmtT->close();

  // -------- Insert INCIDENTES (opcional) --------
  $ids_inci = [];
  if (!empty($incidentes)) {
    $sqlInc = "INSERT INTO tb_incidente
      (id_zona, id_parte, id_novedad, id_tarja, id_datadai, observacion, id_medida, medida, foto, reponsabilidad, validar, grave, condicion)
      VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";
    $stmtI = $db->prepare($sqlInc);

    foreach ($incidentes as $ix => $inc) {
      if (!is_array($inc)) { throw new InvalidArgumentException("Incidente #$ix inválido"); }

      $id_zona       = toInt(getv($inc,'id_zona', null));
      $id_parte      = toInt(getv($inc,'id_parte', null));
      $id_novedad    = toInt(getv($inc,'id_novedad', null));
      $id_datadai_i  = toInt(getv($inc,'id_datadai', $id_datadai));
      $obs_i         = toStr(getv($inc,'observacion', null));
      $id_medida     = toInt(getv($inc,'id_medida', null));
      $medida        = toStr(getv($inc,'medida', null));
      $foto_b64      = toStr(getv($inc,'foto', null));
      $foto_path     = save_base64_image($foto_b64, 'inc_'.$id_tarja) ?? null;
      $resp          = toStr(getv($inc,'reponsabilidad', null));
      $validar       = toBoolInt(getv($inc,'validar', 0));
      $grave         = toBoolInt(getv($inc,'grave', 0)); // nuevo
      $cond_i        = toInt(getv($inc,'condicion', 1));

      // Tipos: i i i i i s i s s s i i i
      $stmtI->bind_param(
        'iiiiisisssiii',
        $id_zona, $id_parte, $id_novedad, $id_tarja, $id_datadai_i,
        $obs_i, $id_medida, $medida, $foto_path, $resp, $validar, $grave, $cond_i
      );
      $stmtI->execute();
      $ids_inci[] = (int)$db->insert_id;
    }
    $stmtI->close();
  }

  // Commit
  $db->commit();
  $inTransaction = false;

  echo json_encode([
    'success' => true,
    'message' => 'Guardado correctamente',
    'data' => [
      'id_tarja' => $id_tarja,
      'siglas' => $siglas_final,
      'numero_auto' => $numero_auto_generado,
      'numero_auto_formateado' => $numero_auto_fmt,
      'numerotarja' => $numerotarja,
      'fechatarja' => $fechatarja,
      'ids_incidentes' => $ids_inci,
    ]
  ], JSON_UNESCAPED_UNICODE);

} catch (Throwable $e) {
  if ($inTransaction) { try { $db->rollback(); } catch (Throwable $ignore) {} }
  http_response_code(400);
  echo json_encode([
    'success' => false,
    'message' => 'Error: ' . $e->getMessage()
  ], JSON_UNESCAPED_UNICODE);
}
