<?php
declare(strict_types=1);

require_once __DIR__ . '/../conexion.php';
require_once __DIR__ . '/../_helpers.php';
require_once __DIR__ . '/../auth/guard.php';

$u = require_login();
require_module_access($u, "usuarios");

if (!function_exists('safe_read_json')) {
  function safe_read_json(): array {
    $raw = file_get_contents('php://input');
    if ($raw === false || trim($raw) === '') return [];
    $j = json_decode($raw, true);
    return is_array($j) ? $j : [];
  }
}

function s($v): string { return trim((string)($v ?? '')); }
function i_or_null($v): ?int {
  if ($v === '' || $v === null) return null;
  if (!is_numeric($v)) return null;
  return (int)$v;
}

function rut_clean(string $v): string {
  $v = strtoupper($v);
  $v = preg_replace('/[^0-9K]/', '', $v) ?? '';
  return substr($v, 0, 15);
}

try {
  $method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');
  $src = ($method === 'POST') ? safe_read_json() : $_GET;

  $qRaw = s($src['q'] ?? '');
  $qRut = rut_clean($qRaw);
  $qTxt = trim($qRaw);
  $hasLetters = $qTxt !== '' && preg_match('/[A-Za-zÁÉÍÓÚÜÑáéíóúüñ]/u', $qTxt) === 1;

  $inscrito = s($src['inscrito_cesfam'] ?? '');
  $percapitado = s($src['percapitado'] ?? '');
  $migrante = s($src['migrante'] ?? '');
  $sectorizacion = s($src['sectorizacion'] ?? '');
  $sector = s($src['sector'] ?? '');
  $estratificacion = strtoupper(s($src['estratificacion_riesgo'] ?? ''));
  $diagnosticoQ = s($src['diagnostico_q'] ?? '');

  $limit = i_or_null($src['limit'] ?? null) ?? 200;
  $page = i_or_null($src['page'] ?? null) ?? 1;
  $offset = i_or_null($src['offset'] ?? null);
  if ($limit < 1) $limit = 1;
  if ($limit > 500) $limit = 500;
  if ($page < 1) $page = 1;
  if ($offset === null) {
    $offset = ($page - 1) * $limit;
  }
  if ($offset < 0) $offset = 0;
  $page = (int)floor($offset / $limit) + 1;

  $db = null;
  if (isset($pdo) && $pdo instanceof PDO) $db = $pdo;
  elseif (isset($conexion) && $conexion instanceof PDO) $db = $conexion;
  elseif (isset($conn) && $conn instanceof PDO) $db = $conn;

  if (!$db) {
    throw new RuntimeException('No hay conexión PDO disponible.');
  }

  fp_ensure_percapita_columns($db);
  // Mantiene la consistencia: si fue actualizado por Percápita FONASA, también queda inscrito CESFAM.
  $db->exec("UPDATE usuarios SET inscrito_cesfam = 1 WHERE percapitado = 1 AND fecha_actualizacion_percapita IS NOT NULL AND COALESCE(inscrito_cesfam, 0) <> 1");

  $where = [];
  $params = [];

  if ($qRut !== '' || ($qTxt !== '' && $hasLetters)) {
    $ors = [];
    if ($qRut !== '') {
      $ors[] = 'rut LIKE :rut';
      $params[':rut'] = $qRut . '%';
    }
    if ($qTxt !== '' && $hasLetters) {
      $ors[] = '(
        nombres LIKE :q1
        OR apellidos LIKE :q2
        OR CONCAT(nombres, " ", apellidos) LIKE :q3
        OR CONCAT(apellidos, " ", nombres) LIKE :q4
      )';
      $like = '%' . $qTxt . '%';
      $params[':q1'] = $like;
      $params[':q2'] = $like;
      $params[':q3'] = $like;
      $params[':q4'] = $like;
    }
    $where[] = '(' . implode(' OR ', $ors) . ')';
  }

  if ($inscrito !== '' && ($inscrito === '0' || $inscrito === '1')) {
    $where[] = 'inscrito_cesfam = :inscrito';
    $params[':inscrito'] = (int)$inscrito;
  }

  if ($percapitado !== '' && ($percapitado === '0' || $percapitado === '1')) {
    $where[] = 'percapitado = :percapitado';
    $params[':percapitado'] = (int)$percapitado;
  }

  if ($migrante !== '' && ($migrante === '0' || $migrante === '1')) {
    $where[] = 'migrante = :migrante';
    $params[':migrante'] = (int)$migrante;
  }

  if ($sectorizacion !== '' && ctype_digit($sectorizacion)) {
    $where[] = 'sectorizacion = :sectorizacion';
    $params[':sectorizacion'] = (int)$sectorizacion;
  }

  if ($sector !== '' && ctype_digit($sector)) {
    $where[] = 'sector = :sector';
    $params[':sector'] = (int)$sector;
  }

  // Regla solicitada: si no hay dato, se considera G0
  if ($estratificacion !== '' && in_array($estratificacion, ['G0','G1','G2','G3'], true)) {
    $where[] = "COALESCE(NULLIF(estratificacion_riesgo, ''), 'G0') = :estratificacion";
    $params[':estratificacion'] = $estratificacion;
  }

  if ($diagnosticoQ !== '') {
    $where[] = "(
      COALESCE(detalle_diagnosticos_cronicos, '') LIKE :diag
      OR EXISTS (
        SELECT 1
        FROM usuario_diagnosticos_cronicos ud
        WHERE ud.usuario_rut = usuarios.rut
          AND (
            COALESCE(ud.codigo_diagnostico, '') LIKE :diag
            OR COALESCE(ud.nombre_diagnostico, '') LIKE :diag
            OR COALESCE(ud.diagnostico_completo, '') LIKE :diag
          )
      )
    )";
    $params[':diag'] = '%' . $diagnosticoQ . '%';
  }

  $countSql = "SELECT COUNT(*) FROM usuarios";
  if ($where) $countSql .= ' WHERE ' . implode(' AND ', $where);

  $countStmt = $db->prepare($countSql);
  foreach ($params as $k => $v) $countStmt->bindValue($k, $v);
  $countStmt->execute();
  $total = (int)$countStmt->fetchColumn();

  $totalPages = max(1, (int)ceil($total / $limit));
  if ($total > 0 && $offset >= $total) {
    $page = $totalPages;
    $offset = ($page - 1) * $limit;
  }

  $sql = "
    SELECT
      usuarios.rut,
      usuarios.nombres,
      usuarios.apellidos,
      CASE
        WHEN (usuarios.edad IS NULL OR usuarios.edad = 0)
          AND NULLIF(usuarios.fecha_nacimiento,'0000-00-00') IS NOT NULL
          AND usuarios.fecha_nacimiento >= '1900-01-01'
          AND usuarios.fecha_nacimiento <= CURDATE()
        THEN TIMESTAMPDIFF(YEAR, usuarios.fecha_nacimiento, CURDATE())
        ELSE usuarios.edad
      END AS edad,
      usuarios.inscrito_cesfam,
      usuarios.percapitado,
      usuarios.fecha_actualizacion_percapita,
      usuarios.migrante,
      usuarios.sectorizacion,
      usuarios.sector,
      COALESCE(NULLIF(usuarios.estratificacion_riesgo, ''), 'G0') AS estratificacion_riesgo,
      COALESCE(
        usuarios.cantidad_condiciones_cronicas,
        diag.diag_count,
        CASE
          WHEN COALESCE(TRIM(usuarios.detalle_diagnosticos_cronicos), '') = '' THEN 0
          ELSE (LENGTH(usuarios.detalle_diagnosticos_cronicos) - LENGTH(REPLACE(usuarios.detalle_diagnosticos_cronicos, '|', '')) + 1)
        END,
        0
      ) AS cantidad_condiciones_cronicas,
      usuarios.fecha_actualizacion_estratificacion,
      COALESCE(usuarios.detalle_diagnosticos_cronicos, '') AS detalle_diagnosticos_cronicos
    FROM usuarios
    LEFT JOIN (
      SELECT usuario_rut, COUNT(*) AS diag_count
      FROM usuario_diagnosticos_cronicos
      GROUP BY usuario_rut
    ) diag ON diag.usuario_rut = usuarios.rut
  ";

  if ($where) $sql .= ' WHERE ' . implode(' AND ', $where);
  $sql .= ' ORDER BY apellidos ASC, nombres ASC LIMIT :limit OFFSET :offset';

  $stmt = $db->prepare($sql);
  foreach ($params as $k => $v) $stmt->bindValue($k, $v);
  $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
  $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
  $stmt->execute();

  $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  $from = $total > 0 ? ($offset + 1) : 0;
  $to = $offset + count($rows);

  json_response([
    'ok' => true,
    'data' => $rows,
    'meta' => [
      'limit' => $limit,
      'offset' => $offset,
      'page' => $page,
      'total' => $total,
      'total_pages' => $totalPages,
      'from' => $from,
      'to' => $to,
      'has_prev' => $page > 1,
      'has_next' => $page < $totalPages
    ]
  ]);
} catch (Throwable $e) {
  error_log('PERSONAS LIST ERROR: ' . $e->getMessage());
  $isLocal = in_array($_SERVER['REMOTE_ADDR'] ?? '', ['127.0.0.1', '::1'], true);
  json_response([
    'ok' => false,
    'message' => $isLocal ? $e->getMessage() : 'Error listando personas.'
  ], 500);
}
