<?php
declare(strict_types=1);

// /php/busqueda/search.php
// Buscador global (Personas/Familias/Viviendas) con filtros desde busqueda.js
// Frontend NO se toca.

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

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

if (!isset($pdo) || !($pdo instanceof PDO)) {
  json_response(['ok'=>false,'message'=>'No se detectó $pdo en conexion.php'], 500);
}
fp_ensure_percapita_columns($pdo);

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$in = [];
if ($method === 'POST') $in = read_json_body();

$qRaw = trim((string)($in['q'] ?? ($_GET['q'] ?? '')));

$types = $in['types'] ?? null;

// filtros (nombres iguales a tu JS)
$szRaw      = (string)($in['sz'] ?? ($_GET['sz'] ?? ''));
$secRaw     = (string)($in['sec'] ?? ($_GET['sec'] ?? ''));
$inscrito   = (string)($in['inscrito'] ?? ($_GET['inscrito'] ?? ''));
$percapitado = (string)($in['percapitado'] ?? ($_GET['percapitado'] ?? ''));
$migrante   = (string)($in['migrante'] ?? ($_GET['migrante'] ?? ''));
$genero     = (string)($in['genero'] ?? ($_GET['genero'] ?? '')); // f/m/o
$geo        = (string)($in['geo'] ?? ($_GET['geo'] ?? ''));       // 1/0

$limitP = (int)($in['limitP'] ?? 250);
$limitF = (int)($in['limitF'] ?? 250);
$limitV = (int)($in['limitV'] ?? 250);

$limitP = max(1, min(250, $limitP));
$limitF = max(1, min(250, $limitF));
$limitV = max(1, min(250, $limitV));

$toBool = function($v, bool $def=true): bool {
  if ($v === null) return $def;
  if (is_bool($v)) return $v;
  $s = strtolower(trim((string)$v));
  if ($s === '') return $def;
  if (in_array($s, ['1','true','si','sí','yes','y'], true)) return true;
  if (in_array($s, ['0','false','no','n'], true)) return false;
  return $def;
};

$incP = true; $incF = true; $incV = true;
if (is_array($types)) {
  $incP = $toBool($types['p'] ?? null, true);
  $incF = $toBool($types['f'] ?? null, true);
  $incV = $toBool($types['v'] ?? null, true);
}

// ints
$toIntOrNull = function($v): ?int {
  $v = trim((string)$v);
  if ($v === '' || !is_numeric($v)) return null;
  $i = (int)$v;
  return $i > 0 ? $i : null;
};

$sz  = $toIntOrNull($szRaw);
$sec = $toIntOrNull($secRaw);

try {
  // ===== base totals (sin filtros) =====
  $baseP = (int)$pdo->query("SELECT COUNT(*) FROM usuarios")->fetchColumn();
  $baseF = (int)$pdo->query("SELECT COUNT(*) FROM familias")->fetchColumn();
  $baseV = (int)$pdo->query("SELECT COUNT(*) FROM vivienda")->fetchColumn();

  $out = [
    'ok' => true,
    'base' => [
      'p' => $baseP,
      'f' => $baseF,
      'v' => $baseV,
      'all' => ($baseP + $baseF + $baseV),
    ],
    'counts' => ['p'=>0,'f'=>0,'v'=>0,'all'=>0],
    'data' => ['p'=>[],'f'=>[],'v'=>[]],
  ];

  // ===== PERSONAS =====
  if ($incP) {
    $where = [];
    $params = [];

    if ($qRaw !== '') {
      $where[] = "(u.rut LIKE :q OR u.apellidos LIKE :q OR u.nombres LIKE :q OR u.direccion LIKE :q OR u.celular LIKE :q OR u.telefonos LIKE :q)";
      $params[':q'] = '%' . $qRaw . '%';
    }
    if ($sz !== null)  { $where[] = "u.sectorizacion = :sz"; $params[':sz'] = $sz; }
    if ($sec !== null) { $where[] = "u.sector = :sec";       $params[':sec'] = $sec; }

    if ($inscrito === '1' || $inscrito === '0') {
      $where[] = "u.inscrito_cesfam = :ins";
      $params[':ins'] = (int)$inscrito;
    }

    if ($percapitado === '1' || $percapitado === '0') {
      $where[] = "u.percapitado = :percapitado";
      $params[':percapitado'] = (int)$percapitado;
    }

    if ($migrante === '1' || $migrante === '0') {
      $where[] = "u.migrante = :mig";
      $params[':mig'] = (int)$migrante;
    } elseif ($migrante === 'n') {
      $where[] = "u.migrante IS NULL";
    }

    $g = strtolower(trim($genero));
    if (in_array($g, ['f','m','o'], true)) {
      if ($g === 'f') $where[] = "(u.genero IS NOT NULL AND TRIM(u.genero) <> '' AND LOWER(TRIM(u.genero)) LIKE 'f%')";
      if ($g === 'm') $where[] = "(u.genero IS NOT NULL AND TRIM(u.genero) <> '' AND LOWER(TRIM(u.genero)) LIKE 'm%')";
      if ($g === 'o') $where[] = "(u.genero IS NOT NULL AND TRIM(u.genero) <> '' AND LOWER(TRIM(u.genero)) NOT LIKE 'f%' AND LOWER(TRIM(u.genero)) NOT LIKE 'm%')";
    }

    if ($geo === "1") {
      $where[] = "(u.latitud IS NOT NULL AND TRIM(u.latitud) <> '' AND u.longitud IS NOT NULL AND TRIM(u.longitud) <> '')";
    } elseif ($geo === "0") {
      $where[] = "((u.latitud IS NULL OR TRIM(u.latitud) = '') OR (u.longitud IS NULL OR TRIM(u.longitud) = ''))";
    }

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

    // count
    $stC = $pdo->prepare("SELECT COUNT(*) FROM usuarios u $whereSql");
    foreach ($params as $k=>$v) {
      $stC->bindValue($k, $v, is_int($v) ? PDO::PARAM_INT : PDO::PARAM_STR);
    }
    $stC->execute();
    $cntP = (int)$stC->fetchColumn();

    // data (campos suficientes para lista + swal)
    $sql = "
      SELECT
        u.rut, u.nombres, u.apellidos, u.genero, u.inscrito_cesfam, u.percapitado, u.fecha_actualizacion_percapita, u.migrante,
        u.direccion, u.sectorizacion, u.sector,
        z.nombre_sectorizacion AS sectorizacion_nombre,
        s.nombre_sector AS sector_nombre,
        u.latitud, u.longitud,
        u.celular, u.telefonos, u.nacionalidad, u.prevision, u.profesion, u.escolaridad,
        u.ultima_actualizacion
      FROM usuarios u
      LEFT JOIN sectorizacion z ON z.id = u.sectorizacion
      LEFT JOIN sectores s ON s.id = u.sector
      $whereSql
      ORDER BY u.ultima_actualizacion DESC
      LIMIT :lim
    ";
    $st = $pdo->prepare($sql);
    foreach ($params as $k=>$v) {
      $st->bindValue($k, $v, is_int($v) ? PDO::PARAM_INT : PDO::PARAM_STR);
    }
    $st->bindValue(':lim', $limitP, PDO::PARAM_INT);
    $st->execute();
    $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];

    $out['counts']['p'] = $cntP;
    $out['data']['p'] = $rows;
  }

  // ===== FAMILIAS =====
  if ($incF) {
    $where = [];
    $params = [];

    if ($qRaw !== '') {
      $where[] = "(f.codigo_familia LIKE :q OR f.apellido_familia LIKE :q OR f.direccion LIKE :q)";
      $params[':q'] = '%' . $qRaw . '%';
    }
    if ($sz !== null)  { $where[] = "f.sectorizacion = :sz"; $params[':sz'] = $sz; }
    if ($sec !== null) { $where[] = "f.sector = :sec";       $params[':sec'] = $sec; }

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

    $stC = $pdo->prepare("SELECT COUNT(*) FROM familias f $whereSql");
    foreach ($params as $k=>$v) {
      $stC->bindValue($k, $v, is_int($v) ? PDO::PARAM_INT : PDO::PARAM_STR);
    }
    $stC->execute();
    $cntF = (int)$stC->fetchColumn();

    $sql = "
      SELECT
        f.codigo_familia AS cod_familia,
        f.apellido_familia,
        f.direccion,
        f.sectorizacion,
        f.sector,
        z.nombre_sectorizacion AS sectorizacion_nombre,
        s.nombre_sector AS sector_nombre,
        COUNT(u.rut) AS total_integrantes,
        f.ultima_actualizacion
      FROM familias f
      LEFT JOIN usuarios u ON u.familia = f.codigo_familia
      LEFT JOIN sectorizacion z ON z.id = f.sectorizacion
      LEFT JOIN sectores s ON s.id = f.sector
      $whereSql
      GROUP BY
        f.codigo_familia, f.apellido_familia, f.direccion,
        f.sectorizacion, f.sector,
        z.nombre_sectorizacion, s.nombre_sector,
        f.ultima_actualizacion
      ORDER BY f.ultima_actualizacion DESC
      LIMIT :lim
    ";
    $st = $pdo->prepare($sql);
    foreach ($params as $k=>$v) {
      $st->bindValue($k, $v, is_int($v) ? PDO::PARAM_INT : PDO::PARAM_STR);
    }
    $st->bindValue(':lim', $limitF, PDO::PARAM_INT);
    $st->execute();
    $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];

    $out['counts']['f'] = $cntF;
    $out['data']['f'] = $rows;
  }

  // ===== VIVIENDAS =====
  if ($incV) {
    $where = [];
    $params = [];

    if ($qRaw !== '') {
      $where[] = "(v.cod_vivienda LIKE :q OR v.direccion LIKE :q)";
      $params[':q'] = '%' . $qRaw . '%';
    }
    if ($sz !== null)  { $where[] = "v.sectorizacion = :sz"; $params[':sz'] = $sz; }
    if ($sec !== null) { $where[] = "v.sector = :sec";       $params[':sec'] = $sec; }

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

    $stC = $pdo->prepare("SELECT COUNT(*) FROM vivienda v $whereSql");
    foreach ($params as $k=>$v) {
      $stC->bindValue($k, $v, is_int($v) ? PDO::PARAM_INT : PDO::PARAM_STR);
    }
    $stC->execute();
    $cntV = (int)$stC->fetchColumn();

    $sql = "
      SELECT
        v.id, v.cod_vivienda, v.direccion, v.sectorizacion, v.sector,
        z.nombre_sectorizacion AS sectorizacion_nombre,
        s.nombre_sector AS sector_nombre,
        v.latitud, v.longitud,
        v.tipo_vivienda, v.tenencia, v.conservacion, v.calefaccion,
        v.numero_piezas, v.numero_dormitorios, v.numero_camas,
        v.ultima_actualizacion
      FROM vivienda v
      LEFT JOIN sectorizacion z ON z.id = v.sectorizacion
      LEFT JOIN sectores s ON s.id = v.sector
      $whereSql
      ORDER BY v.id DESC
      LIMIT :lim
    ";
    $st = $pdo->prepare($sql);
    foreach ($params as $k=>$v) {
      $st->bindValue($k, $v, is_int($v) ? PDO::PARAM_INT : PDO::PARAM_STR);
    }
    $st->bindValue(':lim', $limitV, PDO::PARAM_INT);
    $st->execute();
    $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];

    $out['counts']['v'] = $cntV;
    $out['data']['v'] = $rows;
  }

  $out['counts']['all'] = (int)$out['counts']['p'] + (int)$out['counts']['f'] + (int)$out['counts']['v'];

  json_response($out);

} catch (Throwable $e) {
  error_log("BUSQUEDA SEARCH ERROR: " . $e->getMessage());
  json_response(['ok'=>false,'message'=>'Error buscando.'], 500);
}
