<?php
/**
 * POST /modules/turnero/api/guardar_toma.php
 * Guarda una firma parcial en formularios de tomas prolongadas.
 * Calcula el próximo intervalo y actualiza estado + siguiente_toma_at.
 *
 * Body JSON:
 *   turno_id       int     requerido
 *   formulario_id  int     requerido
 *   campo_id       string  requerido  (id del campo firma_profesional firmado)
 *   svg            string  requerido  (data URI)
 *   datos_respuestas object requerido (todos los valores actuales del form)
 */
require_once __DIR__ . '/_helpers.php';
requireMethod('POST');
requireTurnero();

$body         = inputJson();
$turnoId      = (int)($body['turno_id']      ?? 0);
$formularioId = (int)($body['formulario_id'] ?? 0);
$campoId      = trim($body['campo_id']       ?? '');
$svg          = $body['svg']                 ?? '';
$datosInput   = is_array($body['datos_respuestas'] ?? null) ? $body['datos_respuestas'] : [];

if (!$turnoId)      jsonError('turno_id requerido.');
if (!$formularioId) jsonError('formulario_id requerido.');
if (!$campoId)      jsonError('campo_id requerido.');
if (strlen($svg) < 100) jsonError('Firma requerida.');
if (!preg_match('/^data:image\/(svg\+xml|png|jpeg|webp);base64,/i', $svg)) {
    jsonError('Formato de firma no válido.');
}

$pdo = db();

// ── Cargar consentimiento y esquema ──────────────────────────
$stmt = $pdo->prepare(
    "SELECT tc.id, tc.estado, tc.datos_respuestas, tc.toma_inicio_at, t.sesion_id,
            f.esquema
       FROM turnero_consentimientos tc
       JOIN turnero_turnos t ON t.id = tc.turno_id
       JOIN lab_formularios f ON f.id = tc.formulario_id
      WHERE tc.turno_id = ? AND tc.formulario_id = ?"
);
$stmt->execute([$turnoId, $formularioId]);
$tc = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$tc) jsonError('Consentimiento no encontrado.', 404);

$esquema = json_decode($tc['esquema'] ?? '[]', true);
if (!is_array($esquema)) $esquema = [];

// ── Merge datos_respuestas existentes + nuevos ───────────────
$datosActuales = [];
if ($tc['datos_respuestas']) {
    $d = json_decode($tc['datos_respuestas'], true);
    if (is_array($d)) $datosActuales = $d;
}
// Guardar svg en el campo firmado
$datosInput[$campoId] = $svg;
$datosMerge = array_merge($datosActuales, $datosInput);

// ── Analizar esquema: campos firma_profesional en orden ──────
// Construir mapa: campo_id → minuto (o hora fija) leyendo el separador previo
$firmasCampos  = [];   // [ [id, minutos|null, hora_fija|null], ... ] en orden
$separadorLabel = null;

foreach ($esquema as $campo) {
    $tipo = $campo['tipo'] ?? '';
    if ($tipo === 'separador') {
        $separadorLabel = $campo['label'] ?? '';
    }
    if ($tipo === 'firma_profesional') {
        $minutos   = null;
        $horaFija  = null;
        if ($separadorLabel !== null) {
            // "Taukit · Minuto 10" → 10; "Toma · Minuto 60" → 60
            if (preg_match('/Minuto\s+(\d+)/i', $separadorLabel, $m)) {
                $minutos = (int)$m[1];
            }
            // "3:00 p.m." / "4:00 p.m." → hora fija
            elseif (preg_match('/(\d+):(\d+)\s*(a\.?m\.?|p\.?m\.?)/i', $separadorLabel, $m)) {
                $h = (int)$m[1];
                $min = (int)$m[2];
                $pm  = strtolower(preg_replace('/[^apm]/i', '', $m[3])) === 'pm';
                if ($pm && $h < 12) $h += 12;
                $horaFija = sprintf('%02d:%02d:00', $h, $min);
            }
        }
        $firmasCampos[] = ['id' => $campo['id'], 'minutos' => $minutos, 'hora_fija' => $horaFija];
    }
}

// ── Determinar estado y siguiente_toma_at ────────────────────
$firmados      = array_filter($firmasCampos, fn($f) => isset($datosMerge[$f['id']]) && strlen($datosMerge[$f['id']]) > 10);
$pendientes    = array_filter($firmasCampos, fn($f) => !isset($datosMerge[$f['id']]) || strlen($datosMerge[$f['id']]) <= 10);
$pendientes    = array_values($pendientes);

$todasFirmadas    = empty($pendientes);
$siguienteToma    = null;
$nuevoEstado      = 'en_progreso';
$tomaInicioAt     = $tc['toma_inicio_at'];

if (empty($tc['toma_inicio_at'])) {
    $tomaInicioAt = date('Y-m-d H:i:s');
}

if ($todasFirmadas) {
    $nuevoEstado = 'firmado';
} else {
    // Calcular cuándo es la siguiente toma
    $next = $pendientes[0];
    if ($next['hora_fija'] !== null) {
        // Hora fija en el día actual
        $siguienteToma = date('Y-m-d') . ' ' . $next['hora_fija'];
    } elseif ($next['minutos'] !== null && $tomaInicioAt) {
        // Minuto relativo desde el inicio de la toma
        $siguienteToma = date('Y-m-d H:i:s', strtotime($tomaInicioAt) + $next['minutos'] * 60);
    }
}

// ── Persistir ────────────────────────────────────────────────
$pdo->prepare(
    "UPDATE turnero_consentimientos
        SET datos_respuestas  = ?,
            estado            = ?,
            siguiente_toma_at = ?,
            toma_inicio_at    = COALESCE(toma_inicio_at, ?),
            firmado_at        = IF(? = 'firmado', NOW(), firmado_at),
            firmado_profesional_at = IF(? = 'firmado', NOW(), firmado_profesional_at)
      WHERE turno_id = ? AND formulario_id = ?"
)->execute([
    json_encode($datosMerge, JSON_UNESCAPED_UNICODE),
    $nuevoEstado,
    $siguienteToma,
    date('Y-m-d H:i:s'),
    $nuevoEstado,
    $nuevoEstado,
    $turnoId,
    $formularioId,
]);

notificarSSE((int)$tc['sesion_id']);

$totalFirmas   = count($firmasCampos);
$firmadasCount = count($firmados) + ($todasFirmadas ? 0 : 1); // incluye la recién guardada

jsonOk([
    'estado'           => $nuevoEstado,
    'siguiente_toma_at'=> $siguienteToma,
    'tomas_firmadas'   => min($firmadasCount, $totalFirmas),
    'tomas_total'      => $totalFirmas,
    'completado'       => $todasFirmadas,
], $todasFirmadas ? 'Formulario completado.' : 'Toma guardada. Próxima: ' . ($siguienteToma ?? 'pendiente'));
