<?php
declare(strict_types=1);
require_once dirname(__FILE__) . '/../config.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    jsonErr(405, 'Metodo no permitido.');
}

$jwt   = auth();
$idinv = (int)$jwt['idinv'];
$b     = body();
$db    = getDB();

/*
 * Payload esperado:
 * {
 *   "referencia_destino": "GOML850101AB1",
 *   "items": [
 *     { "idnsalida": 12, "cantidad": 2 },
 *     { "idnsalida": 15, "cantidad": 1 }
 *   ]
 * }
 */
$refDestino = trim($b['referencia_destino'] ?? '');
$items      = $b['items'] ?? [];

if (!$refDestino) {
    jsonErr(400, 'Se requiere referencia_destino.');
}
if (!is_array($items) || count($items) === 0) {
    jsonErr(400, 'Se requiere al menos un item en el arreglo items.');
}

try {
    // Buscar distribuidor destino por referencia
    $stmtDest = $db->prepare(
        "SELECT id_inver, nombre, appat, apmat, referencia
         FROM inversionista WHERE referencia = ? LIMIT 1"
    );
    $stmtDest->execute([$refDestino]);
    $destino = $stmtDest->fetch(PDO::FETCH_ASSOC);
    if (!$destino) {
        jsonErr(404, 'No se encontro distribuidor con la referencia: ' . $refDestino);
    }
    $idinvDest = (int)$destino['id_inver'];

    // Centro de distribución del usuario logueado
    $stmtCd = $db->prepare("SELECT COALESCE(centros_idcd, 1) AS cdId FROM inversionista WHERE id_inver = ? LIMIT 1");
    $stmtCd->execute([$idinv]);
    $cdRow = $stmtCd->fetch(PDO::FETCH_ASSOC);
    $cdId  = (int)($cdRow['cdId'] ?? 1);

    // Validar todos los ítems antes de iniciar la transacción
    $lineasValidadas = [];
    foreach ($items as $item) {
        $idnsalida = (int)($item['idnsalida'] ?? 0);
        $cantidad  = (int)($item['cantidad']  ?? 0);
        if (!$idnsalida || $cantidad < 1) continue; // ignorar ítems con cantidad 0

        $stmtNS = $db->prepare(
            "SELECT ns.id, ns.productos_idprod, ns.cant, ns.asignar,
                    (ns.cant - ns.asignar) AS pendiente,
                    t.inversionista_id_inver, t.tipostr_idtipostr
             FROM nsalida ns
             JOIN transacciones t ON t.idtransacciones = ns.transacciones_idtransacciones
             WHERE ns.id = ? LIMIT 1"
        );
        $stmtNS->execute([$idnsalida]);
        $ns = $stmtNS->fetch(PDO::FETCH_ASSOC);

        if (!$ns) {
            jsonErr(404, "Linea nsalida $idnsalida no encontrada.");
        }
        if ((int)$ns['inversionista_id_inver'] !== $idinv) {
            jsonErr(403, "Sin permiso para asignar la linea $idnsalida.");
        }
        if ((int)$ns['tipostr_idtipostr'] !== 11) {
            jsonErr(400, "La linea $idnsalida no pertenece a una nota por asignar.");
        }
        $pendiente = (int)$ns['pendiente'];
        if ($pendiente <= 0) {
            jsonErr(400, "La linea $idnsalida no tiene unidades pendientes.");
        }
        if ($cantidad > $pendiente) {
            jsonErr(400, "La linea $idnsalida solo tiene $pendiente unidades pendientes.");
        }

        // Puntos del producto/promoción
        $idProd  = (int)$ns['productos_idprod'];
        $ptsUnit = 0.0;
        if ($idProd) {
            if ($idProd > 1000) {
                $stmtPts = $db->prepare("SELECT COALESCE(puntos, 0) FROM promod WHERE id_promo = ? LIMIT 1");
            } else {
                $stmtPts = $db->prepare("SELECT COALESCE(puntos, 0) FROM productos WHERE id_prod = ? LIMIT 1");
            }
            $stmtPts->execute([$idProd]);
            $ptsUnit = (float)($stmtPts->fetchColumn() ?: 0);
        }

        $lineasValidadas[] = [
            'idnsalida'  => $idnsalida,
            'id_prod'    => $idProd,
            'cantidad'   => $cantidad,
            'pts_total'  => $ptsUnit * $cantidad,
        ];
    }

    if (count($lineasValidadas) === 0) {
        jsonErr(400, 'No hay items validos con cantidad mayor a 0.');
    }

    // Calcular puntos totales de la asignación
    $ptsGrandTotal = array_sum(array_column($lineasValidadas, 'pts_total'));

    $db->beginTransaction();

    $fecha = date('Y-m-d');
    $hora  = date('H:i:s');

    // Crear UNA SOLA transacción tipo 12 para todos los ítems
    $db->prepare(
        "INSERT INTO transacciones
         (inversionista_id_inver, tipostr_idtipostr, fechat, horat,
          usuarios_ci_idusuarios_ci, statusentrega)
         VALUES (?, 12, ?, ?, ?, 'ENTREGADO')"
    )->execute([$idinvDest, $fecha, $hora, $cdId]);
    $idTxAsig = (int)$db->lastInsertId();

    // depositos con puntos totales
    $db->prepare(
        "INSERT INTO depositos (centros_idcd, transacciones_idtransacciones, cantidad, puntos)
         VALUES (?, ?, 0, ?)"
    )->execute([$cdId, $idTxAsig, $ptsGrandTotal]);

    // Insertar cada línea
    foreach ($lineasValidadas as $linea) {
        // pedido_real (solo esta tabla, NO pedido)
        $db->prepare("INSERT INTO pedido_real (transacciones, id_prod, cant) VALUES (?, ?, ?)")
           ->execute([$idTxAsig, $linea['id_prod'], $linea['cantidad']]);

        // Actualizar contador en nsalida
        $db->prepare("UPDATE nsalida SET asignar = asignar + ? WHERE id = ?")
           ->execute([$linea['cantidad'], $linea['idnsalida']]);
    }

    // asignaciones: UNA SOLA vez por toda la transacción
    // nsalida       = transacción original (nota padre de la que se asigna)
    // idtransacciones = nueva transacción recién creada (tipo 12)
    $idTxOriginal = (int)$lineasValidadas[0]['idnsalida']; // todas las líneas pertenecen a la misma nota
    // Obtener la transacción original a partir del primer nsalida
    $stmtTxOrig = $db->prepare(
        "SELECT transacciones_idtransacciones FROM nsalida WHERE id = ? LIMIT 1"
    );
    $stmtTxOrig->execute([$lineasValidadas[0]['idnsalida']]);
    $txOriginal = (int)($stmtTxOrig->fetchColumn() ?: 0);

    $db->prepare("INSERT INTO asignaciones (nsalida, idtransacciones) VALUES (?, ?)")
       ->execute([$txOriginal, $idTxAsig]);

    $db->commit();

    jsonOk([
        'idtransaccion_asignacion' => $idTxAsig,
        'idinv_destino'            => $idinvDest,
        'nombre_destino'           => trim(
            ($destino['nombre'] ?? '') . ' ' .
            ($destino['appat']  ?? '') . ' ' .
            ($destino['apmat']  ?? '')
        ),
        'referencia_destino'       => $refDestino,
        'items_asignados'          => count($lineasValidadas),
        'puntos_totales'           => $ptsGrandTotal,
        'mensaje'                  => 'Asignacion realizada correctamente.',
    ]);

} catch (Throwable $e) {
    if ($db->inTransaction()) $db->rollBack();
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Error en asignacion: ' . $e->getMessage(),
    ], JSON_UNESCAPED_UNICODE);
    exit;
}
