<?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_write($u, "usuarios");

$in = read_json_body();

fp_ensure_percapita_columns($pdo);

$rut = normalize_rut((string)($in['rut'] ?? ''));
if ($rut === '') {
  json_response(["ok" => false, "message" => "RUT es obligatorio."], 400);
}

$cleanStr = fn($v) => ($v === null) ? null : (($s = trim((string)$v)) === '' ? null : $s);

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

$toBigIdOrNull = function($v) {
  if ($v === null || $v === '') return null;
  if (!is_numeric($v)) return null;
  $i = (int)$v;
  return $i > 0 ? $i : null;
};

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

$fecha_nacimiento = $cleanStr($in['fecha_nacimiento'] ?? null);
if ($fecha_nacimiento !== null && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha_nacimiento)) {
  json_response(["ok" => false, "message" => "fecha_nacimiento inválida. Usa YYYY-MM-DD."], 400);
}

$edad = $toIntOrNull($in['edad'] ?? null);

$sectorizacion = $toBigIdOrNull($in['sectorizacion'] ?? null);
$sector = $toBigIdOrNull($in['sector'] ?? null);
$familia = $toBigIdOrNull($in['familia'] ?? null);

$lat = $in['latitud'] ?? null;
$lon = $in['longitud'] ?? null;
$latitud  = ($lat === '' || $lat === null) ? null : (is_numeric($lat) ? (float)$lat : null);
$longitud = ($lon === '' || $lon === null) ? null : (is_numeric($lon) ? (float)$lon : null);

if (($lat !== null && $lat !== '' && $latitud === null) || ($lon !== null && $lon !== '' && $longitud === null)) {
  json_response(["ok" => false, "message" => "Latitud/Longitud inválidas."], 400);
}

$registrado_por = normalize_rut((string)($u['rut'] ?? ''));
if ($registrado_por === '') $registrado_por = null;

// Validación FK (evita 500 por constraint)
try {
  if ($sectorizacion !== null) {
    $st = $pdo->prepare("SELECT 1 FROM sectorizacion WHERE id = ? LIMIT 1");
    $st->execute([$sectorizacion]);
    if (!$st->fetchColumn()) json_response(["ok" => false, "message" => "sectorizacion no existe."], 409);
  }
  if ($sector !== null) {
    $st = $pdo->prepare("SELECT 1 FROM sectores WHERE id = ? LIMIT 1");
    $st->execute([$sector]);
    if (!$st->fetchColumn()) json_response(["ok" => false, "message" => "sector no existe."], 409);
  }
  if ($familia !== null) {
    $st = $pdo->prepare("SELECT 1 FROM familias WHERE cod_familia = ? LIMIT 1");
    $st->execute([$familia]);
    if (!$st->fetchColumn()) json_response(["ok" => false, "message" => "familia no existe."], 409);
  }

  if ($registrado_por !== null) {
    $st = $pdo->prepare("SELECT 1 FROM funcionario WHERE rut = ? LIMIT 1");
    $st->execute([$registrado_por]);
    if (!$st->fetchColumn()) $registrado_por = null; // evita FK
  }
} catch (Throwable $e) {
  error_log("PERSONAS FK PRECHECK ERROR: " . $e->getMessage());
  json_response(["ok" => false, "message" => "Error validando referencias."], 500);
}

$detalleDiagnosticos = $cleanStr($in['detalle_diagnosticos_cronicos'] ?? null);
$cantidadCronicos = $toIntOrNull($in['cantidad_condiciones_cronicas'] ?? null);
if ($cantidadCronicos === null && $detalleDiagnosticos !== null) {
  $cantidadCronicos = count(fp_parse_diagnosticos_cronicos($detalleDiagnosticos));
}
$estratificacionPayload = strtoupper((string)$cleanStr($in['estratificacion_riesgo'] ?? null));
if ($estratificacionPayload === '') {
  $estratificacionPayload = 'G0';
}

$payload = [
  'rut' => $rut,
  'fecha_nacimiento' => $fecha_nacimiento,
  'edad' => $edad,
  'apellidos' => $cleanStr($in['apellidos'] ?? null),
  'nombres' => $cleanStr($in['nombres'] ?? null),
  'genero' => $cleanStr($in['genero'] ?? null),
  'estado_civil' => $cleanStr($in['estado_civil'] ?? null),
  'escolaridad' => $cleanStr($in['escolaridad'] ?? null),
  'profesion' => $cleanStr($in['profesion'] ?? null),
  'prevision' => $cleanStr($in['prevision'] ?? null),
  'inscrito_cesfam' => $toBool01OrNull($in['inscrito_cesfam'] ?? null),
  'percapitado' => $toBool01OrNull($in['percapitado'] ?? 1) ?? 1,
  'fecha_actualizacion_percapita' => fp_parse_excel_date_or_null($in['fecha_actualizacion_percapita'] ?? null),
  'migrante' => $toBool01OrNull($in['migrante'] ?? null),
  'nacionalidad' => $cleanStr($in['nacionalidad'] ?? null),
  'pueblo_originario' => $cleanStr($in['pueblo_originario'] ?? null),
  'direccion' => $cleanStr($in['direccion'] ?? null),
  'latitud' => $latitud,
  'longitud' => $longitud,
  'sector' => $sector,
  'sectorizacion' => $sectorizacion,
  'celular' => $cleanStr($in['celular'] ?? null),
  'telefonos' => $cleanStr($in['telefonos'] ?? null),
  'participacion_ciudadana' => $cleanStr($in['participacion_ciudadana'] ?? null),
  'parentezco' => $cleanStr($in['parentezco'] ?? null),
  'familia' => $familia,
  'estratificacion_riesgo' => $estratificacionPayload,
  'cantidad_condiciones_cronicas' => $cantidadCronicos,
  'fecha_actualizacion_estratificacion' => fp_parse_excel_date_or_null($in['fecha_actualizacion_estratificacion'] ?? null),
  'detalle_diagnosticos_cronicos' => $detalleDiagnosticos,
  'registrado_por' => $registrado_por,
];

// Regla de negocio: si una persona queda marcada como percapitada,
// necesariamente debe quedar inscrita en CESFAM.
if ((int)$payload['percapitado'] === 1) {
  $payload['inscrito_cesfam'] = 1;
}

try {
  $sql = "
    INSERT INTO usuarios (
      rut, fecha_nacimiento, edad, apellidos, nombres, genero, estado_civil, escolaridad, profesion, prevision,
      inscrito_cesfam, percapitado, fecha_actualizacion_percapita, migrante, nacionalidad, pueblo_originario, direccion, latitud, longitud,
      sector, sectorizacion, celular, telefonos, participacion_ciudadana, parentezco, familia,
      estratificacion_riesgo, cantidad_condiciones_cronicas, fecha_actualizacion_estratificacion, detalle_diagnosticos_cronicos,
      registrado_por
    ) VALUES (
      :rut, :fecha_nacimiento, :edad, :apellidos, :nombres, :genero, :estado_civil, :escolaridad, :profesion, :prevision,
      :inscrito_cesfam, :percapitado, :fecha_actualizacion_percapita, :migrante, :nacionalidad, :pueblo_originario, :direccion, :latitud, :longitud,
      :sector, :sectorizacion, :celular, :telefonos, :participacion_ciudadana, :parentezco, :familia,
      :estratificacion_riesgo, :cantidad_condiciones_cronicas, :fecha_actualizacion_estratificacion, :detalle_diagnosticos_cronicos,
      :registrado_por
    )
    ON DUPLICATE KEY UPDATE
      fecha_nacimiento = VALUES(fecha_nacimiento),
      edad = VALUES(edad),
      apellidos = VALUES(apellidos),
      nombres = VALUES(nombres),
      genero = VALUES(genero),
      estado_civil = VALUES(estado_civil),
      escolaridad = VALUES(escolaridad),
      profesion = VALUES(profesion),
      prevision = VALUES(prevision),
      inscrito_cesfam = CASE WHEN VALUES(percapitado) = 1 THEN 1 ELSE VALUES(inscrito_cesfam) END,
      percapitado = VALUES(percapitado),
      fecha_actualizacion_percapita = VALUES(fecha_actualizacion_percapita),
      migrante = VALUES(migrante),
      nacionalidad = VALUES(nacionalidad),
      pueblo_originario = VALUES(pueblo_originario),
      direccion = VALUES(direccion),
      latitud = VALUES(latitud),
      longitud = VALUES(longitud),
      sector = VALUES(sector),
      sectorizacion = VALUES(sectorizacion),
      celular = VALUES(celular),
      telefonos = VALUES(telefonos),
      participacion_ciudadana = VALUES(participacion_ciudadana),
      parentezco = VALUES(parentezco),
      familia = VALUES(familia),
      estratificacion_riesgo = VALUES(estratificacion_riesgo),
      cantidad_condiciones_cronicas = VALUES(cantidad_condiciones_cronicas),
      fecha_actualizacion_estratificacion = VALUES(fecha_actualizacion_estratificacion),
      detalle_diagnosticos_cronicos = VALUES(detalle_diagnosticos_cronicos),
      registrado_por = VALUES(registrado_por)
  ";

  $stmt = $pdo->prepare($sql);
  $stmt->execute($payload);

  fp_sync_usuario_diagnosticos($pdo, $rut, $payload['detalle_diagnosticos_cronicos']);

  fp_log_activity($pdo, $u, 'Personas', 'Guardar persona', 'Se guardó/actualizó la persona RUT ' . $rut, 'persona', $rut);

  json_response(["ok" => true, "data" => ["rut" => $rut]]);
} catch (Throwable $e) {
  // FK constraint
  if ((int)($e->errorInfo[1] ?? 0) === 1452) {
    json_response(["ok" => false, "message" => "Referencia inválida (sector/sectorización/familia)."], 409);
  }
  error_log("PERSONAS SAVE ERROR: " . $e->getMessage());
  json_response(["ok" => false, "message" => "Error guardando persona."], 500);
}
