<?php
// admin/procesar_pago_proveedor.php
// Procesa el alta de pagos a proveedores, con soporte de cheques y conversión ARS→USD.
// Caja/bancos y cheques: ARS. Proveedor/factura: USD.

session_start();

$HAS_INIT = file_exists(__DIR__ . '/../_init.php');
if ($HAS_INIT) {
  include __DIR__ . '/../_init.php';
  if (function_exists('is_loggedin') && !is_loggedin()) {
    die('No autenticado.');
  }
}

include __DIR__ . '/conexion3.php';

// ---------- Helpers ----------
function current_user_id_safe() {
  if (function_exists('user_id')) {
    $u = user_id();
    if ($u) return (int)$u;
  }
  return 0;
}
function safe_float($v, $default = 0.0) {
  if ($v === null || $v === '') return (float)$default;
  return (float)$v;
}

// ---------- Validación método ----------
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  http_response_code(405);
  die('Método inválido.');
}

// ---------- Inputs ----------
$sup_id      = isset($_POST['sup_id']) ? (int)$_POST['sup_id'] : 0;
$fecha       = isset($_POST['fecha']) ? $_POST['fecha'] : date('Y-m-d');
$factura_id  = (isset($_POST['factura_id']) && $_POST['factura_id'] !== '') ? (int)$_POST['factura_id'] : null;
$account_id  = isset($_POST['account_id']) ? (int)$_POST['account_id'] : 0;
$forma_pago  = isset($_POST['forma_pago']) ? $_POST['forma_pago'] : 'efectivo';
$cotizacion  = isset($_POST['cotizacion']) ? (float)$_POST['cotizacion'] : 0.0; // *** Relevante (USD) ***
$importe_ars = isset($_POST['importe_ars']) ? safe_float($_POST['importe_ars']) : 0.0; // Caja/cheques
$nota        = trim($_POST['nota'] ?? '');

$sin_caja  = isset($_POST['sin_caja']) ? (int)$_POST['sin_caja'] : 0;

$selected_cheques = (isset($_POST['selected_cheques']) && is_array($_POST['selected_cheques'])) ? $_POST['selected_cheques'] : [];

// ---------- Validaciones básicas ----------
if ($sup_id <= 0)          die('Proveedor inválido.');
if ($account_id <= 0)      die('Cuenta/caja inválida.');
if ($cotizacion <= 0)      die('Cotización inválida.');

try {
  if (!$conn->begin_transaction()) {
    throw new Exception('No se pudo iniciar la transacción.');
  }

  // Si es cheque, el importe ARS = suma cheques seleccionados
  if ($forma_pago === 'cheque') {
    if (empty($selected_cheques)) {
      throw new Exception('Debe seleccionar al menos un cheque.');
    }
    $ids = array_map('intval', $selected_cheques);
    $ids = array_filter($ids, function($x){ return $x > 0; });
    if (empty($ids)) throw new Exception('Cheques inválidos.');

    $idlist = implode(',', $ids);
    $rsC = $conn->query("
      SELECT cheque_id, importe
      FROM cheques
      WHERE cheque_id IN($idlist) AND status='in' AND caja_id = $account_id
      FOR UPDATE
    ");
    if (!$rsC) throw new Exception('Error consultando cheques: ' . $conn->error);
    if ($rsC->num_rows !== count($ids)) throw new Exception('Uno o más cheques no están disponibles en esta caja.');

    $suma = 0.0;
    while ($r = $rsC->fetch_assoc()) $suma += (float)$r['importe'];
    $importe_ars = $suma;
  } else {
    if ($importe_ars <= 0) throw new Exception('El importe debe ser mayor a 0.');
  }

  // Verificar saldo de caja (ARS)
  $saldoQ = $conn->query("
    SELECT (ba.initial_balance + bast.deposit + bast.transfer_from_other - bast.withdraw - bast.transfer_to_other) AS balance
    FROM bank_accounts ba
    JOIN bank_account_to_store bast ON bast.account_id = ba.id
    WHERE bast.store_id = 1 AND bast.status = 1 AND ba.id = $account_id
    FOR UPDATE
  ");
  if (!$saldoQ || !$saldoQ->num_rows) throw new Exception('La cuenta/caja no está disponible.');
  $saldoRow = $saldoQ->fetch_assoc();
  $saldo = isset($saldoRow['balance']) ? (float)$saldoRow['balance'] : 0.0;
  if ($saldo < $importe_ars) throw new Exception('Saldo insuficiente en la caja seleccionada.');

  // ARS → USD (para proveedor/factura)
  $importe_usd = $importe_ars / $cotizacion;

  // Nombre de caja
  $caja_nombre = '';
  $cn = $conn->query("SELECT account_name FROM bank_accounts WHERE id = $account_id");
  if ($cn && $cn->num_rows) $caja_nombre = (string)$cn->fetch_assoc()['account_name'];

  // Insert en pagos_facturas (guardamos ARS, + cotización + USD)
  $fecha_emision = $fecha;

  if ($factura_id === null) {
    // SIN factura (NULL en SQL)
    $sqlPago = "INSERT INTO pagos_facturas
      (proveedor_id, factura_id, fecha, fecha_emision, caja, importe, nota, num_cheque, cotizacion, importe_usd)
      VALUES (?, NULL, ?, ?, ?, ?, ?, 0, ?, ?)";
    $stmtPago = $conn->prepare($sqlPago);
    if (!$stmtPago) throw new Exception('Error preparando pagos_facturas (sin factura): ' . $conn->error);

    // tipos: i s s s d s d d
    $pp_sup_id        = $sup_id;
    $pp_fecha         = $fecha;
    $pp_fecha_emision = $fecha_emision;
    $pp_caja_nombre   = $caja_nombre;
    $pp_importe_ars   = $importe_ars;
    $pp_nota          = $nota;
    $pp_cotizacion    = $cotizacion;
    $pp_importe_usd   = $importe_usd;

    if (!$stmtPago->bind_param(
      "isssdsdd",
      $pp_sup_id,
      $pp_fecha,
      $pp_fecha_emision,
      $pp_caja_nombre,
      $pp_importe_usd,
      $pp_nota,
      $pp_cotizacion,
      $pp_importe_usd
    )) { throw new Exception('Error bind pagos_facturas (sin factura): '.$stmtPago->error); }

  } else {
    // CON factura
    $sqlPago = "INSERT INTO pagos_facturas
      (proveedor_id, factura_id, fecha, fecha_emision, caja, importe, nota, num_cheque, cotizacion, importe_usd)
      VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?)";
    $stmtPago = $conn->prepare($sqlPago);
    if (!$stmtPago) throw new Exception('Error preparando pagos_facturas: ' . $conn->error);

    // tipos: i i s s s d s d d
    $pp_sup_id        = $sup_id;
    $pp_factura_id    = $factura_id;
    $pp_fecha         = $fecha;
    $pp_fecha_emision = $fecha_emision;
    $pp_caja_nombre   = $caja_nombre;
    $pp_importe_ars   = $importe_usd;
    $pp_nota          = $nota;
    $pp_cotizacion    = $cotizacion;
    $pp_importe_usd   = $importe_usd;

    if (!$stmtPago->bind_param(
      "iisssdsdd",
      $pp_sup_id,
      $pp_factura_id,
      $pp_fecha,
      $pp_fecha_emision,
      $pp_caja_nombre,
      $pp_importe_usd,
      $pp_nota,
      $pp_cotizacion,
      $pp_importe_usd
    )) { throw new Exception('Error bind pagos_facturas: '.$stmtPago->error); }
  }

  if (!$stmtPago->execute()) throw new Exception('Error insertando en pagos_facturas: ' . $stmtPago->error);
  $pago_id = $stmtPago->insert_id;
  $stmtPago->close();

  // Si es cheque: registrar cheques_proveedores + marcar OUT (todo en ARS)
  if ($forma_pago === 'cheque') {
    $ids = array_map('intval', $selected_cheques);
    $ids = array_filter($ids, function($x){ return $x>0; });
    $idlist = implode(',', $ids);

    $rsCh = $conn->query("
      SELECT cheque_id, numero, fecha AS fecha_emision, fecha_pago AS fecha_cobro,
             importe, cuit, banco, tipo_cheque
      FROM cheques
      WHERE cheque_id IN($idlist) AND status='in' AND caja_id = $account_id
      FOR UPDATE
    ");
    if (!$rsCh) throw new Exception('Error leyendo cheques: ' . $conn->error);

    $insCh = $conn->prepare("
      INSERT INTO cheques_proveedores
        (pago_id, importe_cheque, fecha_emision, fecha_cobro, titular_cuenta,
         tipo_cheque, origen_cheque, numero_cheque, cuit, beneficiario, tipo_pago, banco, factura_id,sup_id)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    if (!$insCh) throw new Exception('Error preparando cheques_proveedores: ' . $conn->error);

    while ($c = $rsCh->fetch_assoc()) {
      $imp   = (float)$c['importe'];
      $num   = (string)$c['numero'];
      $fe    = (string)$c['fecha_emision'];
      $fc    = (string)$c['fecha_cobro'];
      $cuitv = (string)$c['cuit'];
      $ban   = (string)$c['banco'];
      $tcheq = $c['tipo_cheque'] ? (string)$c['tipo_cheque'] : 'cheque físico';
      $fid   = $factura_id ? (int)$factura_id : 0;
      $prov_id  = $sup_id ? (int)$sup_id : 0;

      $titular      = '';
      $origen       = 'tercero';
      $beneficiario = '';
      $tipo_pago    = 'común';

      if (!$insCh->bind_param(
        "idssssssssssii",
        $pago_id, $imp, $fe, $fc, $titular, $tcheq, $origen, $num, $cuitv, $beneficiario, $tipo_pago, $ban, $fid, $prov_id
      )) throw new Exception('Error set params cheques_proveedores: '.$insCh->error);

      if (!$insCh->execute()) throw new Exception('Error insertando cheques_proveedores: '.$insCh->error);
    }
    $insCh->close();

    if (!$conn->query("
      UPDATE cheques
      SET status='out', ref_id = '$pago_id',
          observaciones = CONCAT(IFNULL(observaciones,''),' | aplicado en pago_id=$pago_id')
      WHERE cheque_id IN($idlist)
    ")) throw new Exception('Error actualizando cheques: ' . $conn->error);
  }

  // Actualiza withdraw ARS de la caja
  $importe_ars_round4 = round($importe_ars, 4);
  $upd = $conn->query("
    UPDATE bank_account_to_store
    SET withdraw = withdraw + $importe_ars_round4
    WHERE store_id = 1 AND account_id = $account_id
  ");
  if (!$upd) throw new Exception('Error actualizando withdraw: ' . $conn->error);
  if ($conn->affected_rows <= 0) {
    $ins = $conn->query("
      INSERT INTO bank_account_to_store
        (store_id, account_id, deposit, withdraw, transfer_from_other, transfer_to_other, status, sort_order)
      VALUES (1, $account_id, 0, $importe_ars_round4, 0, 0, 1, 0)
    ");
    if (!$ins) throw new Exception('No se pudo crear línea de bank_account_to_store: ' . $conn->error);
  }

   // Asiento bank_transaction_info (ARS, con cotización informativa)
  $ref_no        = 'PAGPROV-' . $pago_id;
  $title         = 'Pago a proveedor #' . $sup_id;
  $details       = ($nota !== '') ? $nota : 'Pago a proveedor';
  $numero_cheque = ($forma_pago === 'cheque' && !empty($selected_cheques)) ? implode(',', array_map('intval', $selected_cheques)) : '';
  $fecha_cheque  = ($forma_pago === 'cheque') ? $fecha : null; // puede ser NULL
  $importe_cheque= ($forma_pago === 'cheque') ? $importe_ars : 0.00;
  $created_by    = current_user_id_safe();

  $insInfo = $conn->prepare("
    INSERT INTO bank_transaction_info
      (store_id, transaction_type, is_substract, is_hide, account_id, source_id, exp_category_id,
       ref_no, invoice_id, title, details, numero_cheque, fecha_cheque, importe_cheque,
       cotizacion_dolar, from_account_id, status, image, created_by, created_at, customer_id, updated_at)
    VALUES
      (1, 'withdraw', 1, 0, ?, NULL, NULL,
       ?, ?, ?, ?, ?, ?, ?,
       ?, NULL, 1, NULL, ?, NOW(), ?, NULL)
  ");
  if (!$insInfo) { throw new Exception('Error preparando bank_transaction_info: ' . $conn->error); }

  // VARIABLES (por referencia) EXACTAS QUE SE VAN A ENLAZAR
  $bt_account_id      = (int)$account_id;                          // i
  $bt_ref_no          = (string)$ref_no;                           // s
  $bt_invoice_id_str  = ($factura_id !== null) ? (string)$factura_id : NULL; // s (acepta NULL)
  $bt_title           = (string)$title;                            // s
  $bt_details         = (string)$details;                          // s
  $bt_numero_cheque   = (string)$numero_cheque;                    // s
  $bt_fecha_cheque    = $fecha_cheque !== null ? (string)$fecha_cheque : NULL; // s (acepta NULL)
  $bt_importe_cheque  = (float)$importe_cheque;                    // d
  $bt_cotiz_str       = (string)$cotizacion;                       // s
  $bt_created_by      = (int)$created_by;                          // i
  $bt_customer_id     = (int)$sup_id;                              // i

  // TIPOS:  i s s s s s s d s i i   (11 parámetros)
  if (!$insInfo->bind_param(
    "issssssdsii",
    $bt_account_id,
    $bt_ref_no,
    $bt_invoice_id_str,
    $bt_title,
    $bt_details,
    $bt_numero_cheque,
    $bt_fecha_cheque,
    $bt_importe_cheque,
    $bt_cotiz_str,
    $bt_created_by,
    $bt_customer_id
  )) { throw new Exception('Error seteando parámetros bank_transaction_info: ' . $insInfo->error); }

  if (!$insInfo->execute()) { throw new Exception('Error insertando bank_transaction_info: ' . $insInfo->error); }
  $info_id = $insInfo->insert_id;
  $insInfo->close();

   // Asiento bank_transaction_price (USD informativo del asiento)
  $usd_amount = $importe_usd; // claridad

  $insPrice = $conn->prepare("
    INSERT INTO bank_transaction_price
      (store_id, info_id, ref_no, amount, account_id_, cotizacion_billete, numero_comprobante)
    VALUES (1, ?, ?, ?, ?, ?, ?)
  ");
  if (!$insPrice) {
    throw new Exception('Error preparando bank_transaction_price: ' . $conn->error);
  }

  // Variables por referencia (6 parámetros)
  $btp_info_id        = (int)$info_id;          // i
  $btp_ref_no         = (string)$ref_no;        // s
  $btp_amount         = (float)$importe_ars;     // d
  $btp_account_id_    = (int)$account_id;       // i
  $btp_cotiz_billete  = (string)$cotizacion;    // s
  $btp_num_comp       = (string)$ref_no;        // s

  // Tipos: isdiss  (¡sin espacios!)
  if (!$insPrice->bind_param(
    "isdiss",
    $btp_info_id,
    $btp_ref_no,
    $btp_amount,
    $btp_account_id_,
    $btp_cotiz_billete,
    $btp_num_comp
  )) {
    throw new Exception('Error seteando parámetros bank_transaction_price: ' . $insPrice->error);
  }

  if (!$insPrice->execute()) {
    throw new Exception('Error insertando bank_transaction_price: ' . $insPrice->error);
  }
  $insPrice->close();


  // Recalcular pagado de la factura EN USD (sum de pagos_facturas.importe_usd)
  if ($factura_id !== null) {
    $upd = $conn->prepare("
      UPDATE facturas
      SET pagado = (SELECT IFNULL(SUM(importe_usd),0) FROM pagos_facturas WHERE factura_id = ?)
      WHERE id = ?
    ");
    if (!$upd) throw new Exception('Error preparando actualización de factura: ' . $conn->error);
    $pf_factura_id1 = $factura_id;
    $pf_factura_id2 = $factura_id;
    $upd->bind_param("ii", $pf_factura_id1, $pf_factura_id2);
    if (!$upd->execute()) throw new Exception('Error actualizando pagado en factura: ' . $upd->error);
    $upd->close();
  }

  if (!$conn->commit()) throw new Exception('No se pudo confirmar la transacción.');

  header("Location: cuenta_proveedor.php?proveedor_id=" . $sup_id);
  exit;

} catch (Exception $e) {
  @ $conn->rollback();
  http_response_code(500);
  echo "<div style='padding:12px; font-family:Arial; color:#a94442; background:#f2dede; border:1px solid #ebccd1;'>
          <strong>Error:</strong> " . htmlspecialchars($e->getMessage()) . "
        </div>";
  exit;
}
