<?php
// api_ia/generar_analisis.php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// ✅ CORS (igual a tu estilo)
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Content-Type: application/json; charset=utf-8");

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

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

require_once(__DIR__ . '/../config1.php'); // Aquí se define $mysqli

// ✅ Leer JSON del body
$inputRaw = file_get_contents('php://input');
$input = json_decode($inputRaw, true);

if (!$input) {
  http_response_code(400);
  echo json_encode([
    "success" => false,
    "message" => "No se recibió información válida (JSON inválido o vacío)."
  ]);
  exit;
}

// Helper para obtener valores (null si no existen)
function get_value($array, $key) {
  return (isset($array[$key]) && $array[$key] !== '') ? $array[$key] : null;
}

// =============================
// CONFIG IA (RECOMENDADO: ENV)
// =============================
$OPENAI_API_KEY = "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"; // ⚠️ Recomendado: revoca la anterior si la publicaste
if (!$OPENAI_API_KEY) {
  http_response_code(500);
  echo json_encode([
    "success" => false,
    "message" => "OPENAI_API_KEY no configurada."
  ]);
  exit;
}

$OPENAI_ENDPOINT = "https://api.openai.com/v1/chat/completions";
$OPENAI_MODEL    = "gpt-4o-mini";

// =============================
// INPUT (filtros)
// =============================
$tipo = get_value($input, 'TIPO_ANALISIS') ?? 'resumen_general'; // resumen_general | por_dpto | por_zona | alertas
$dpto = get_value($input, 'DPTO');                               // ej: NARINO
$zona = get_value($input, 'ZONA');                               // ej: 21

// Normalizaciones simples
if ($dpto) $dpto = strtoupper(trim($dpto));
if ($zona !== null) $zona = intval($zona);

// =============================
// 0) Resolver nombre legible de zona (sin mostrar "21")
// =============================
$zonaLabel = null;        // ej: "NARINO"
$zonaLugar = null;        // ej: "Pasto" (si existe en los datos)

try {
  // Si mandan ZONA, buscamos el nombre en NODO_DPTO
  if ($zona !== null) {
    $sqlZona = "SELECT NOMBRE_DPTO FROM NODO_DPTO WHERE ID_DPTO = ? LIMIT 1";
    $stmtZ = $mysqli->prepare($sqlZona);
    if ($stmtZ) {
      $stmtZ->bind_param("i", $zona);
      $stmtZ->execute();
      $resZ = $stmtZ->get_result();
      $rowZ = $resZ->fetch_assoc();
      $stmtZ->close();
      if ($rowZ && !empty($rowZ['NOMBRE_DPTO'])) {
        $zonaLabel = strtoupper(trim($rowZ['NOMBRE_DPTO']));
      }
    }
  }

  // Tomamos un municipio representativo (top por cantidad)
  $whereTmp = [];
  $paramsTmp = [];
  $typesTmp = "";

  if ($dpto) { $whereTmp[] = "dp.NOMBRE_DPTO = ?"; $typesTmp .= "s"; $paramsTmp[] = $dpto; }
  if ($zona !== null) { $whereTmp[] = "vt.ID_ZONA_ASIGNADA = ?"; $typesTmp .= "i"; $paramsTmp[] = $zona; }

  $whereTmpSql = count($whereTmp) ? ("WHERE " . implode(" AND ", $whereTmp)) : "";

  $sqlTopMunicipio1 = "
    SELECT vt.MUNICIPIO AS municipio, COUNT(*) AS total
    FROM VOTANTE vt
    LEFT JOIN NODO_DPTO dp ON vt.ID_ZONA_ASIGNADA = dp.ID_DPTO
    $whereTmpSql
    GROUP BY vt.MUNICIPIO
    ORDER BY total DESC
    LIMIT 1
  ";

  $stmtTM = $mysqli->prepare($sqlTopMunicipio1);
  if ($stmtTM) {
    if (!empty($typesTmp)) $stmtTM->bind_param($typesTmp, ...$paramsTmp);
    $stmtTM->execute();
    $resTM = $stmtTM->get_result();
    $rowTM = $resTM->fetch_assoc();
    $stmtTM->close();
    if ($rowTM && !empty($rowTM['municipio'])) {
      $zonaLugar = trim($rowTM['municipio']);
    }
  }
} catch (Exception $e) {
  // no bloquea
}

// =============================
// 1) CONSULTAR RESUMEN AGREGADO
// =============================
try {
  $where = [];
  $params = [];
  $types = "";

  if ($dpto) {
    $where[] = "dp.NOMBRE_DPTO = ?";
    $types .= "s";
    $params[] = $dpto;
  }

  if ($zona !== null) {
    $where[] = "vt.ID_ZONA_ASIGNADA = ?";
    $types .= "i";
    $params[] = $zona;
  }

  $whereSql = count($where) ? ("WHERE " . implode(" AND ", $where)) : "";

  // Totales
  $sqlTot = "
    SELECT
      COUNT(*) AS total_votantes,
      COUNT(DISTINCT vt.ID_ZONA_ASIGNADA) AS zonas,
      COUNT(DISTINCT dp.NOMBRE_DPTO) AS dptos,
      COUNT(DISTINCT vt.MUNICIPIO) AS municipios,
      COUNT(DISTINCT vt.LUGAR_VOTACION) AS colegios,
      SUM(CASE WHEN vt.DIRECCION IS NULL OR vt.DIRECCION='' THEN 1 ELSE 0 END) AS sin_direccion,
      SUM(CASE WHEN vt.LUGAR_VOTACION IS NULL OR vt.LUGAR_VOTACION='' THEN 1 ELSE 0 END) AS sin_colegio,
      SUM(CASE WHEN (vt.PUESTO IS NULL OR vt.PUESTO='' OR vt.PUESTO='0') THEN 1 ELSE 0 END) AS sin_mesa
    FROM VOTANTE vt
    LEFT JOIN NODO_DPTO dp ON vt.ID_ZONA_ASIGNADA = dp.ID_DPTO
    $whereSql
  ";

  $stmtTot = $mysqli->prepare($sqlTot);
  if ($stmtTot === false) throw new Exception("Error prepare totales: " . $mysqli->error);

  if (!empty($types)) $stmtTot->bind_param($types, ...$params);
  if (!$stmtTot->execute()) throw new Exception("Error execute totales: " . $stmtTot->error);

  $resTot = $stmtTot->get_result();
  $totales = $resTot->fetch_assoc();
  $stmtTot->close();

  if (!$totales || intval($totales['total_votantes']) <= 0) {
    http_response_code(200);
    echo json_encode([
      "success" => false,
      "message" => "No hay datos para analizar con esos filtros."
    ]);
    exit;
  }

  // Top colegios
  $sqlTopC = "
    SELECT
      dp.NOMBRE_DPTO AS dpto,
      vt.MUNICIPIO AS municipio,
      vt.LUGAR_VOTACION AS colegio,
      COUNT(*) AS total
    FROM VOTANTE vt
    LEFT JOIN NODO_DPTO dp ON vt.ID_ZONA_ASIGNADA = dp.ID_DPTO
    $whereSql
    GROUP BY dp.NOMBRE_DPTO, vt.MUNICIPIO, vt.LUGAR_VOTACION
    ORDER BY total DESC
    LIMIT 10
  ";

  $stmtC = $mysqli->prepare($sqlTopC);
  if ($stmtC === false) throw new Exception("Error prepare top colegios: " . $mysqli->error);
  if (!empty($types)) $stmtC->bind_param($types, ...$params);
  if (!$stmtC->execute()) throw new Exception("Error execute top colegios: " . $stmtC->error);
  $resC = $stmtC->get_result();
  $topColegios = [];
  while ($r = $resC->fetch_assoc()) $topColegios[] = $r;
  $stmtC->close();

  // Top municipios
  $sqlTopM = "
    SELECT
      dp.NOMBRE_DPTO AS dpto,
      vt.MUNICIPIO AS municipio,
      COUNT(*) AS total
    FROM VOTANTE vt
    LEFT JOIN NODO_DPTO dp ON vt.ID_ZONA_ASIGNADA = dp.ID_DPTO
    $whereSql
    GROUP BY dp.NOMBRE_DPTO, vt.MUNICIPIO
    ORDER BY total DESC
    LIMIT 10
  ";

  $stmtM = $mysqli->prepare($sqlTopM);
  if ($stmtM === false) throw new Exception("Error prepare top municipios: " . $mysqli->error);
  if (!empty($types)) $stmtM->bind_param($types, ...$params);
  if (!$stmtM->execute()) throw new Exception("Error execute top municipios: " . $stmtM->error);
  $resM = $stmtM->get_result();
  $topMunicipios = [];
  while ($r = $resM->fetch_assoc()) $topMunicipios[] = $r;
  $stmtM->close();

  $metricas = [
    "filtro" => [
      "tipo" => $tipo,
      "dpto" => $dpto,
      "zona_id" => $zona,
      "zona_nombre" => $zonaLabel,
      "zona_lugar" => $zonaLugar
    ],
    "totales" => $totales,
    "top_colegios" => $topColegios,
    "top_municipios" => $topMunicipios
  ];
} catch (Exception $e) {
  http_response_code(500);
  echo json_encode([
    "success" => false,
    "message" => "Error consultando datos: " . $e->getMessage()
  ]);
  exit;
}

// =============================
// 2) LLAMAR IA (debe devolver JSON)
// =============================
function call_openai_json($endpoint, $apiKey, $model, $prompt) {
  $payload = [
    "model" => $model,
    "messages" => [
      ["role" => "system", "content" => "Responde SOLO JSON válido. Sin markdown. Sin texto extra. Sin backticks."],
      ["role" => "user", "content" => $prompt]
    ],
    "temperature" => 0.2
  ];

  $ch = curl_init($endpoint);
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
      "Content-Type: application/json",
      "Authorization: Bearer " . $apiKey
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
    CURLOPT_TIMEOUT => 90
  ]);

  $resp = curl_exec($ch);
  $err  = curl_error($ch);
  $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($resp === false) throw new Exception("cURL error: " . $err);
  if ($code < 200 || $code >= 300) throw new Exception("OpenAI HTTP $code: " . $resp);

  $data = json_decode($resp, true);
  $content = $data['choices'][0]['message']['content'] ?? null;
  if (!$content) throw new Exception("Respuesta IA inesperada: " . $resp);

  $parsed = json_decode($content, true);
  if (!$parsed || !isset($parsed['titulo'], $parsed['nivel'], $parsed['mensaje'])) {
    throw new Exception("La IA no devolvió JSON válido (faltan llaves requeridas). Content: " . $content);
  }
  return $parsed;
}

function safe_arr($v) { return is_array($v) ? $v : []; }

function build_mensaje_extendido($ai) {
  $out = trim($ai['mensaje'] ?? '');

  $insights = safe_arr($ai['insights'] ?? []);
  if (count($insights)) {
    $out .= "\n\nINSIGHTS CLAVE:";
    foreach ($insights as $i) {
      if (is_string($i) && trim($i) !== '') $out .= "\n- " . trim($i);
    }
  }

  $riesgos = safe_arr($ai['riesgos'] ?? []);
  if (count($riesgos)) {
    $out .= "\n\nRIESGOS:";
    foreach ($riesgos as $r) {
      if (is_string($r) && trim($r) !== '') $out .= "\n- " . trim($r);
    }
  }

  $oportunidades = safe_arr($ai['oportunidades'] ?? []);
  if (count($oportunidades)) {
    $out .= "\n\nOPORTUNIDADES:";
    foreach ($oportunidades as $o) {
      if (is_string($o) && trim($o) !== '') $out .= "\n- " . trim($o);
    }
  }

  $kpis = safe_arr($ai['kpis'] ?? []);
  if (count($kpis)) {
    $out .= "\n\nKPIs SUGERIDOS:";
    foreach ($kpis as $k) {
      if (is_string($k) && trim($k) !== '') $out .= "\n- " . trim($k);
    }
  }

  $plan = $ai['plan_ataque'] ?? null;
  if (is_array($plan)) {
    $out .= "\n\nPLAN DE ATAQUE:";
    foreach (["acciones_48h" => "Próximas 48h", "acciones_7d" => "Próximos 7 días", "acciones_30d" => "Próximos 30 días"] as $k => $label) {
      $arr = safe_arr($plan[$k] ?? []);
      if (count($arr)) {
        $out .= "\n$label:";
        foreach ($arr as $a) {
          if (is_string($a) && trim($a) !== '') $out .= "\n- " . trim($a);
        }
      }
    }
  }

  $copy = trim($ai['copy_whatsapp'] ?? '');
  if ($copy !== '') {
    $out .= "\n\nCOPY WHATSAPP (listo para pegar):\n" . $copy;
  }

  $preg = safe_arr($ai['preguntas_para_equipo'] ?? []);
  if (count($preg)) {
    $out .= "\n\nPREGUNTAS PARA EL EQUIPO:";
    foreach ($preg as $p) {
      if (is_string($p) && trim($p) !== '') $out .= "\n- " . trim($p);
    }
  }

  $nota = trim($ai['nota_calidad'] ?? '');
  if ($nota !== '') {
    $out .= "\n\nNOTA CALIDAD:\n" . $nota;
  }

  $hip = safe_arr($ai['hipotesis'] ?? []);
  if (count($hip)) {
    $out .= "\n\nHIPÓTESIS (verificación rápida):";
    foreach ($hip as $h) {
      if (is_string($h) && trim($h) !== '') $out .= "\n- " . trim($h);
    }
  }

  return trim($out);
}

try {
$prompt = "
Eres un coordinador senior de movilidad electoral.
Tu función es diseñar el plan operativo de transporte para garantizar el traslado efectivo de votantes y personal el día de votación.

Analiza METRICAS_JSON y genera un plan de movilidad enfocado EXCLUSIVAMENTE en:
- Traslado de votantes
- Traslado del personal operativo
- Uso de buses y otros medios de transporte
- Rutas, horarios y puntos de encuentro

REGLAS:
- NO hables de política ni discurso.
- NO menciones números de zona.
- Usa municipios, colegios y lugares reales cuando existan.
- Sé concreto, logístico y ejecutable.

Devuelve SOLO JSON con llaves OBLIGATORIAS:
- titulo (<=120 chars, enfocado en movilidad)
- nivel (ALTO|MEDIO|BAJO)
- mensaje (5-7 líneas explicando el esquema general de transporte)

Agrega OBLIGATORIAMENTE estas llaves:

- medios_transporte: array de objetos con:
   - tipo (ej: Bus, Buseta, Van, Moto, Taxi, Vehículo particular)
   - capacidad_aprox
   - uso (votantes / personal / apoyo)
   - cantidad_estimada
   - prioridad (ALTA | MEDIA | BAJA)

- plan_transporte_votantes: array de 4-6 acciones claras
- plan_transporte_personal: array de 4-6 acciones claras

- rutas_y_puntos: array de objetos con:
   - punto_encuentro
   - destino
   - horario_salida
   - medio_transporte

- recursos_necesarios: array de 4-6 ítems (vehículos, combustible, conductores, comunicaciones)

- riesgos_movilidad: array de 3-5 riesgos con mitigación

- plan_dia_votacion: objeto con:
   - antes_apertura
   - durante_jornada
   - cierre

- checklist_movilidad: array de 6-10 ítems para el coordinador

Incluye en el mensaje:
- Dónde están concentrados los votantes
- Qué medios de transporte se usarán y por qué
- Qué recursos son críticos para cumplir la movilidad

METRICAS_JSON:
" . json_encode($metricas, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);




  $ai = call_openai_json($OPENAI_ENDPOINT, $OPENAI_API_KEY, $OPENAI_MODEL, $prompt);

  $titulo = mb_substr(trim($ai['titulo']), 0, 160);
  $nivel  = strtoupper(trim($ai['nivel']));
  if (!in_array($nivel, ["ALTO","MEDIO","BAJO"], true)) $nivel = "MEDIO";
  if ($titulo === "") $titulo = "Análisis IA";

  $mensaje = build_mensaje_extendido($ai);
  if ($mensaje === "") $mensaje = "No se pudo generar el mensaje.";

  $metricasConIA = $metricas;
  $metricasConIA['ai'] = $ai;

} catch (Exception $e) {
  http_response_code(500);
  echo json_encode([
    "success" => false,
    "message" => "Error IA: " . $e->getMessage()
  ]);
  exit;
}

// =============================
// 3) UPSERT EN IA_ANALISIS (SI EXISTE, ACTUALIZA; SI NO, INSERTA)
// =============================
try {
  $metricasJson = json_encode($metricasConIA, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

  // Buscar existente por clave (TIPO_ANALISIS, DPTO, ZONA)
  $sqlFind = "
    SELECT ID_ANALISIS
    FROM IA_ANALISIS
    WHERE
      TIPO_ANALISIS = ?
      AND ((DPTO IS NULL AND ? IS NULL) OR (DPTO = ?))
      AND ((ZONA IS NULL AND ? IS NULL) OR (ZONA = ?))
    LIMIT 1
  ";

  $stmtFind = $mysqli->prepare($sqlFind);
  if ($stmtFind === false) {
    http_response_code(500);
    echo json_encode([
      "success" => false,
      "message" => "Error al preparar FIND: " . $mysqli->error
    ]);
    exit;
  }

  $stmtFind->bind_param("sssii", $tipo, $dpto, $dpto, $zona, $zona);

  if (!$stmtFind->execute()) {
    http_response_code(500);
    echo json_encode([
      "success" => false,
      "message" => "Error al ejecutar FIND: " . $stmtFind->error
    ]);
    $stmtFind->close();
    exit;
  }

  $resFind = $stmtFind->get_result();
  $rowFind = $resFind->fetch_assoc();
  $stmtFind->close();

  if ($rowFind && isset($rowFind['ID_ANALISIS'])) {
    // UPDATE
    $idExistente = intval($rowFind['ID_ANALISIS']);

    $sqlUpdate = "
      UPDATE IA_ANALISIS
      SET
        NIVEL = ?,
        TITULO = ?,
        MENSAJE = ?,
        METRICAS_JSON = ?
      WHERE ID_ANALISIS = ?
    ";

    $stmtUp = $mysqli->prepare($sqlUpdate);
    if ($stmtUp === false) {
      http_response_code(500);
      echo json_encode([
        "success" => false,
        "message" => "Error al preparar UPDATE: " . $mysqli->error
      ]);
      exit;
    }

    $stmtUp->bind_param("ssssi", $nivel, $titulo, $mensaje, $metricasJson, $idExistente);

    if (!$stmtUp->execute()) {
      http_response_code(500);
      echo json_encode([
        "success" => false,
        "message" => "Error al ejecutar UPDATE: " . $stmtUp->error
      ]);
      $stmtUp->close();
      exit;
    }

    $stmtUp->close();

    echo json_encode([
      "success" => true,
      "message" => "Análisis IA actualizado exitosamente.",
      "accion" => "actualizado",
      "id_analisis" => $idExistente,
      "data" => [
        "tipo" => $tipo,
        "dpto" => $dpto,
        "zona" => $zona,
        "zona_nombre" => $zonaLabel,
        "zona_lugar" => $zonaLugar,
        "nivel" => $nivel,
        "titulo" => $titulo,
        "mensaje" => $mensaje,
        "ai" => $ai
      ]
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;

  } else {
    // INSERT
    $sqlInsert = "
      INSERT INTO IA_ANALISIS (
        TIPO_ANALISIS,
        DPTO,
        ZONA,
        NIVEL,
        TITULO,
        MENSAJE,
        METRICAS_JSON
      ) VALUES (?, ?, ?, ?, ?, ?, ?)
    ";

    $stmtIn = $mysqli->prepare($sqlInsert);
    if ($stmtIn === false) {
      http_response_code(500);
      echo json_encode([
        "success" => false,
        "message" => "Error al preparar INSERT: " . $mysqli->error
      ]);
      exit;
    }

    $stmtIn->bind_param("ssissss", $tipo, $dpto, $zona, $nivel, $titulo, $mensaje, $metricasJson);

    if (!$stmtIn->execute()) {
      http_response_code(500);
      echo json_encode([
        "success" => false,
        "message" => "Error al ejecutar INSERT: " . $stmtIn->error
      ]);
      $stmtIn->close();
      exit;
    }

    $idInsertado = $stmtIn->insert_id;
    $stmtIn->close();

    echo json_encode([
      "success" => true,
      "message" => "Análisis IA insertado exitosamente.",
      "accion" => "insertado",
      "id_analisis" => $idInsertado,
      "data" => [
        "tipo" => $tipo,
        "dpto" => $dpto,
        "zona" => $zona,
        "zona_nombre" => $zonaLabel,
        "zona_lugar" => $zonaLugar,
        "nivel" => $nivel,
        "titulo" => $titulo,
        "mensaje" => $mensaje,
        "ai" => $ai
      ]
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
  }

} catch (Exception $e) {
  http_response_code(500);
  echo json_encode([
    "success" => false,
    "message" => "Error final: " . $e->getMessage()
  ]);
  exit;
}
