<?php

declare(strict_types=1);

namespace App\Controllers;

use Exception;

/**
 * Controller para receber webhooks da Shipay
 */
class ShipayWebhookController extends BaseController
{
    /**
     * Recebe notificações de webhook da Shipay
     */
    public function receive(): void
    {
        try {
            // Ler payload do webhook
            $rawPayload = file_get_contents('php://input');
            $payload = json_decode($rawPayload, true);

            if (empty($payload)) {
                error_log("Shipay Webhook: Payload vazio");
                http_response_code(400);
                echo json_encode(['error' => 'Payload inválido']);
                return;
            }

            // Log do webhook recebido
            error_log("Shipay Webhook recebido: " . json_encode($payload, JSON_PRETTY_PRINT));

            // Validar assinatura do webhook (se configurado)
            $webhookSecret = $_ENV['SHIPAY_WEBHOOK_SECRET'] ?? '';
            if (!empty($webhookSecret)) {
                $signature = $_SERVER['HTTP_X_SHIPAY_SIGNATURE'] ?? '';
                if (empty($signature) || !$this->validateSignature($rawPayload, $signature, $webhookSecret)) {
                    error_log("Shipay Webhook: Assinatura inválida");
                    http_response_code(401);
                    echo json_encode(['error' => 'Assinatura inválida']);
                    return;
                }
            }

            // Extrair dados do evento
            $eventType = $payload['event'] ?? $payload['type'] ?? 'unknown';
            // Shipay pode enviar charge_id, id ou order_id (verificar todos os possíveis campos)
            $chargeId = $payload['charge_id'] ?? $payload['id'] ?? $payload['order_id'] ?? $payload['data']['charge_id'] ?? $payload['data']['id'] ?? $payload['data']['order_id'] ?? null;
            $status = $payload['status'] ?? $payload['data']['status'] ?? null;

            error_log("[ShipayWebhook] Evento recebido - Tipo: {$eventType}, Charge ID: " . ($chargeId ?? 'NULL') . ", Status: " . ($status ?? 'NULL'));

            if (empty($chargeId)) {
                error_log("Shipay Webhook: charge_id não encontrado no payload");
                http_response_code(400);
                echo json_encode(['error' => 'charge_id não encontrado']);
                return;
            }

            // Primeiro, verificar se é uma venda do PDV (vendas_pagamentos)
            $stmtVenda = $this->db->prepare("
                SELECT vp.*, v.id as venda_id, v.company_id, v.status as venda_status, v.modulo_origem
                FROM vendas_pagamentos vp
                INNER JOIN vendas v ON vp.venda_id = v.id
                WHERE vp.shipay_order_id = :charge_id
                LIMIT 1
            ");
            $stmtVenda->execute(['charge_id' => $chargeId]);
            $pagamentoVenda = $stmtVenda->fetch();

            if (!empty($pagamentoVenda)) {
                // É uma venda do PDV
                error_log("Shipay Webhook: Pagamento de venda PDV encontrado - Venda ID: {$pagamentoVenda['venda_id']}, Status: {$status}");
                $this->processarPagamentoVendaPDV($pagamentoVenda, $status, $payload);
                http_response_code(200);
                echo json_encode(['success' => true, 'message' => 'Webhook processado - Venda PDV']);
                return;
            }

            // Se não for venda PDV, buscar conta a receber
            // Verificar quais colunas existem na tabela
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'shipay_%'");
            $shipayColumns = $stmtCheck->fetchAll();
            $shipayColumnNames = array_column($shipayColumns, 'Field');
            $hasShipayChargeId = in_array('shipay_charge_id', $shipayColumnNames);
            $hasShipayOrderId = in_array('shipay_order_id', $shipayColumnNames);

            error_log("[ShipayWebhook] Buscando conta - charge_id: {$chargeId}, Colunas disponíveis: " . json_encode($shipayColumnNames));

            // Tentar buscar por shipay_charge_id primeiro, depois por shipay_order_id se não encontrar
            $conta = null;

            if ($hasShipayChargeId) {
                $stmt = $this->db->prepare("
                    SELECT cr.*
                    FROM contas_receber cr
                    WHERE cr.shipay_charge_id = :charge_id
                    LIMIT 1
                ");
                $stmt->execute(['charge_id' => $chargeId]);
                $conta = $stmt->fetch();
                if ($conta) {
                    error_log("[ShipayWebhook] Conta encontrada por shipay_charge_id: #{$conta['id']}");
                }
            }

            // Se não encontrou e existe coluna shipay_order_id, tentar buscar por ela
            if (empty($conta) && $hasShipayOrderId) {
                $stmt = $this->db->prepare("
                    SELECT cr.*
                    FROM contas_receber cr
                    WHERE cr.shipay_order_id = :charge_id
                    LIMIT 1
                ");
                $stmt->execute(['charge_id' => $chargeId]);
                $conta = $stmt->fetch();
                if ($conta) {
                    error_log("[ShipayWebhook] Conta encontrada por shipay_order_id: #{$conta['id']}");
                }
            }

            if (empty($conta)) {
                error_log("[ShipayWebhook] ❌ Conta a receber não encontrada para charge_id/order_id: {$chargeId}");
                error_log("[ShipayWebhook] Payload completo: " . json_encode($payload, JSON_PRETTY_PRINT));
                // Retorna 200 para não gerar retry desnecessário
                http_response_code(200);
                echo json_encode(['message' => 'Conta não encontrada']);
                return;
            }

            // Log do status recebido para debug
            error_log("[ShipayWebhook] Status recebido do webhook: " . ($status ?? 'NULL') . " para conta #{$conta['id']}");

            // Atualizar status da conta
            $this->atualizarStatusConta($conta, $status, $payload);

            // Se status for "paid" ou "pago", marcar conta como recebida
            // Verificar também outros possíveis status de pagamento confirmado
            $statusLower = strtolower($status ?? '');
            $statusPagamentoConfirmado = ['paid', 'pago', 'paid_out', 'approved', 'confirmado', 'pago_confirmado'];

            if (in_array($statusLower, $statusPagamentoConfirmado)) {
                error_log("[ShipayWebhook] Status identificado como PAGO - Marcando conta #{$conta['id']} como recebida");
                $this->marcarContaComoRecebida($conta);
            } else {
                error_log("[ShipayWebhook] Status '{$status}' não é considerado como pagamento confirmado. Status válidos: " . implode(', ', $statusPagamentoConfirmado));
            }

            // Retornar sucesso
            http_response_code(200);
            echo json_encode(['success' => true, 'message' => 'Webhook processado']);

        } catch (Exception $e) {
            error_log("Erro ao processar webhook Shipay: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            http_response_code(500);
            echo json_encode(['error' => 'Erro ao processar webhook']);
        }
    }

    /**
     * Valida assinatura do webhook
     */
    private function validateSignature(string $payload, string $signature, string $secret): bool
    {
        $expectedSignature = hash_hmac('sha256', $payload, $secret);
        return hash_equals($expectedSignature, $signature);
    }

    /**
     * Atualiza status da conta a receber com dados do webhook
     */
    private function atualizarStatusConta(array $conta, ?string $status, array $payload): void
    {
        try {
            $updateFields = [];
            $updateValues = [
                'id' => $conta['id'],
                'company_id' => $conta['company_id']
            ];

            // Verificar colunas disponíveis
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'shipay_%'");
            $columns = $stmtCheck->fetchAll();
            $columnNames = array_column($columns, 'Field');

            // Determinar tipo (pix/boleto) a partir do payload
            $tipoShipay = null;
            $metodoPayload = strtolower($payload['payment_method'] ?? $payload['type'] ?? '');
            if (strpos($metodoPayload, 'boleto') !== false) {
                $tipoShipay = 'boleto';
            } elseif (!empty($metodoPayload)) {
                $tipoShipay = 'pix';
            }

            if (in_array('shipay_status', $columnNames) && $status) {
                $updateFields[] = 'shipay_status = :status';
                $updateValues['status'] = $status;
            }

            if (in_array('shipay_tipo', $columnNames) && $tipoShipay) {
                $updateFields[] = 'shipay_tipo = :tipo_shipay';
                $updateValues['tipo_shipay'] = $tipoShipay;
            }

            if (in_array('shipay_charge_id', $columnNames) && empty($conta['shipay_charge_id'] ?? null)) {
                $chargeIdPayload = $payload['charge_id'] ?? $payload['id'] ?? $payload['order_id'] ?? null;
                if ($chargeIdPayload) {
                    $updateFields[] = 'shipay_charge_id = :charge_id';
                    $updateValues['charge_id'] = $chargeIdPayload;
                }
            }

            if (in_array('shipay_linha_digitavel', $columnNames) && !empty($payload['linha_digitavel'] ?? $payload['digitable_line'] ?? null)) {
                $updateFields[] = 'shipay_linha_digitavel = :linha';
                $updateValues['linha'] = $payload['linha_digitavel'] ?? $payload['digitable_line'];
            }

            if (in_array('shipay_pdf_url', $columnNames) && !empty($payload['pdf_url'] ?? $payload['boleto_url'] ?? null)) {
                $updateFields[] = 'shipay_pdf_url = :pdf_url';
                $updateValues['pdf_url'] = $payload['pdf_url'] ?? $payload['boleto_url'];
            }

            if (in_array('shipay_qr_code', $columnNames) && !empty($payload['qr_code'] ?? $payload['pix_copia_cola'] ?? null)) {
                $updateFields[] = 'shipay_qr_code = :qr';
                $updateValues['qr'] = $payload['qr_code'] ?? $payload['pix_copia_cola'];
            }

            if (in_array('shipay_payload', $columnNames)) {
                $updateFields[] = 'shipay_payload = :payload';
                $updateValues['payload'] = json_encode($payload, JSON_UNESCAPED_UNICODE);
            }

            if (!empty($updateFields)) {
                $updateFields[] = 'updated_at = NOW()';
                $sql = "UPDATE contas_receber SET " . implode(', ', $updateFields) . " WHERE id = :id AND company_id = :company_id";
                $stmt = $this->db->prepare($sql);
                $stmt->execute($updateValues);
            }

        } catch (Exception $e) {
            error_log("Erro ao atualizar status da conta: " . $e->getMessage());
        }
    }

    /**
     * Marca conta como recebida e cria lançamento no fluxo de caixa
     */
    private function marcarContaComoRecebida(array $conta): void
    {
        try {
            // Verificar se já está marcada como paga
            if (($conta['status'] ?? '') === 'pago') {
                return;
            }

            $this->db->beginTransaction();

            error_log("[ShipayWebhook] Marcando conta #{$conta['id']} como recebida");

            // Verificar colunas disponíveis
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber");
            $columns = $stmtCheck->fetchAll();
            $columnNames = array_column($columns, 'Field');

            // Calcular valores
            $amount = (float) ($conta['amount'] ?? 0);
            $amountReceived = (float) ($conta['amount_received'] ?? 0);
            $amountRemaining = (float) ($conta['amount_remaining'] ?? $amount);

            // Verificar se existe coluna status_id (módulo de status)
            $temStatusId = in_array('status_id', $columnNames);
            $statusIdPago = null;

            if ($temStatusId) {
                // Buscar o ID do status "pago" no módulo de status
                $stmtStatus = $this->db->prepare("
                    SELECT id FROM modulo_status
                    WHERE company_id = :company_id
                    AND modulo IN ('entradas', 'contas_receber')
                    AND codigo = 'pago'
                    LIMIT 1
                ");
                $stmtStatus->execute(['company_id' => $conta['company_id']]);
                $statusPago = $stmtStatus->fetch();
                if ($statusPago) {
                    $statusIdPago = $statusPago['id'];
                    error_log("[ShipayWebhook] Status ID 'pago' encontrado: {$statusIdPago}");
                } else {
                    error_log("[ShipayWebhook] Aviso: Coluna status_id existe mas status 'pago' não encontrado no módulo_status");
                }
            }

            // Construir UPDATE
            $sets = ["status = 'pago'", "updated_at = NOW()"];

            // Adicionar status_id se encontrado
            if ($statusIdPago) {
                $sets[] = 'status_id = :status_id';
            }

            if (in_array('payment_date', $columnNames)) {
                $sets[] = 'payment_date = CURDATE()';
            }

            if (in_array('amount_received', $columnNames)) {
                $sets[] = 'amount_received = :amount_received';
            }

            if (in_array('amount_remaining', $columnNames)) {
                $sets[] = 'amount_remaining = 0';
            }

            if (in_array('amount_paid', $columnNames)) {
                $sets[] = 'amount_paid = :amount_paid';
            }

            // Atualizar status da conta
            $params = ['id' => $conta['id'], 'company_id' => $conta['company_id']];

            if ($statusIdPago) {
                $params['status_id'] = $statusIdPago;
            }

            if (in_array('amount_received', $columnNames)) {
                $params['amount_received'] = $amount;
            }
            if (in_array('amount_paid', $columnNames)) {
                $params['amount_paid'] = $amount;
            }

            $sql = "UPDATE contas_receber SET " . implode(', ', $sets) . " WHERE id = :id AND company_id = :company_id";
            $stmt = $this->db->prepare($sql);
            $resultado = $stmt->execute($params);
            $linhasAfetadas = $stmt->rowCount();

            error_log("[ShipayWebhook] UPDATE executado: resultado=" . ($resultado ? 'true' : 'false') . ", linhas_afetadas={$linhasAfetadas}");
            error_log("[ShipayWebhook] Conta #{$conta['id']} atualizada para status 'pago'" . ($statusIdPago ? ", status_id={$statusIdPago}" : ""));

            // Atualizar shipay_status para paid se a coluna existir
            if (in_array('shipay_status', $columnNames)) {
                $stmtStatus = $this->db->prepare("UPDATE contas_receber SET shipay_status = 'paid' WHERE id = :id AND company_id = :company_id");
                $stmtStatus->execute(['id' => $conta['id'], 'company_id' => $conta['company_id']]);
            }

            // Buscar conta atualizada para passar para inserirFluxoCaixa
            $stmtContaAtualizada = $this->db->prepare("
                SELECT * FROM contas_receber
                WHERE id = :id AND company_id = :company_id
            ");
            $stmtContaAtualizada->execute(['id' => $conta['id'], 'company_id' => $conta['company_id']]);
            $contaAtualizada = $stmtContaAtualizada->fetch();

            if ($contaAtualizada) {
                // Criar lançamento no fluxo de caixa usando método completo
                $this->criarLancamentoFluxoCaixaCompleto($contaAtualizada);
            } else {
                // Fallback: usar método simples se não conseguir buscar conta atualizada
                $this->criarLancamentoFluxoCaixa($conta['id'], $amount, date('Y-m-d'), $conta['description'] ?? '', $conta['company_id']);
            }

            $this->db->commit();
            error_log("[ShipayWebhook] Conta #{$conta['id']} processada com sucesso - Status: pago, Fluxo de caixa criado");

        } catch (Exception $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log("Erro ao marcar conta como recebida via webhook: " . $e->getMessage());
        }
    }

    /**
     * Processa pagamento de venda do PDV quando webhook confirma pagamento
     */
    private function processarPagamentoVendaPDV(array $pagamentoVenda, ?string $status, array $payload): void
    {
        try {
            $vendaId = $pagamentoVenda['venda_id'];
            $companyId = $pagamentoVenda['company_id'];
            $pagamentoId = $pagamentoVenda['id'];
            $statusLower = strtolower($status ?? '');

            error_log("[ShipayWebhook] Processando pagamento venda PDV - Venda ID: {$vendaId}, Status: {$status}");

            $this->db->beginTransaction();

            // Atualizar status do pagamento
            $stmtUpdate = $this->db->prepare("
                UPDATE vendas_pagamentos
                SET status = :status, updated_at = NOW()
                WHERE id = :id AND company_id = :company_id
            ");
            $stmtUpdate->execute([
                'status' => $statusLower === 'paid' || $statusLower === 'pago' || $statusLower === 'paid_out' ? 'pago' : $statusLower,
                'id' => $pagamentoId,
                'company_id' => $companyId
            ]);

            // Se pagamento foi confirmado (paid/pago), finalizar a venda
            if (in_array($statusLower, ['paid', 'pago', 'paid_out'])) {
                error_log("[ShipayWebhook] Pagamento PIX confirmado para venda PDV #{$vendaId} - Finalizando venda");

                // Finalizar a venda (atualizar de 'orcamento' para 'finalizado')
                $stmtFinalizarVenda = $this->db->prepare("
                    UPDATE vendas
                    SET status = 'finalizado', updated_at = NOW()
                    WHERE id = :venda_id AND company_id = :company_id
                ");
                $stmtFinalizarVenda->execute(['venda_id' => $vendaId, 'company_id' => $companyId]);

                // Baixar estoque dos produtos (se ainda não foi baixado)
                $stmtItens = $this->db->prepare("
                    SELECT product_id, quantity
                    FROM vendas_itens
                    WHERE venda_id = :venda_id AND company_id = :company_id
                ");
                $stmtItens->execute(['venda_id' => $vendaId, 'company_id' => $companyId]);
                $itensVenda = $stmtItens->fetchAll();

                foreach ($itensVenda as $item) {
                    $this->db->prepare("
                        UPDATE produtos
                        SET stock_quantity = stock_quantity - :qtd
                        WHERE id = :id AND company_id = :company_id
                    ")->execute([
                                'qtd' => $item['quantity'],
                                'id' => $item['product_id'],
                                'company_id' => $companyId
                            ]);
                }

                // Verificar se já existe movimento PDV para este pagamento
                $stmtMovimento = $this->db->prepare("
                    SELECT id FROM pdv_movimentos
                    WHERE venda_id = :venda_id AND company_id = :company_id
                    LIMIT 1
                ");
                $stmtMovimento->execute(['venda_id' => $vendaId, 'company_id' => $companyId]);

                if (!$stmtMovimento->fetch()) {
                    // Buscar sessão PDV ativa para esta empresa (ou a última sessão)
                    $stmtSessao = $this->db->prepare("
                        SELECT id FROM pdv_sessoes
                        WHERE company_id = :company_id
                        ORDER BY created_at DESC
                        LIMIT 1
                    ");
                    $stmtSessao->execute(['company_id' => $companyId]);
                    $sessao = $stmtSessao->fetch();

                    if ($sessao) {
                        $sessaoId = $sessao['id'];
                        $valorPagamento = (float) ($pagamentoVenda['valor_parcela'] ?? $pagamentoVenda['valor_pago'] ?? 0);
                        $metodoId = (int) ($pagamentoVenda['metodo_pagamento_id'] ?? 1);

                        // Criar movimento PDV
                        $stmtInsertMov = $this->db->prepare("
                            INSERT INTO pdv_movimentos
                            (company_id, sessao_id, venda_id, tipo, valor, metodo_pagamento_id, created_by, created_at)
                            VALUES
                            (:company_id, :sessao_id, :venda_id, 'venda', :valor, :metodo_id, NULL, NOW())
                        ");
                        $stmtInsertMov->execute([
                            'company_id' => $companyId,
                            'sessao_id' => $sessaoId,
                            'venda_id' => $vendaId,
                            'valor' => $valorPagamento,
                            'metodo_id' => $metodoId
                        ]);

                        // Atualizar saldo da sessão
                        $stmtUpdateSessao = $this->db->prepare("
                            UPDATE pdv_sessoes
                            SET saldo_atual = saldo_atual + :valor, updated_at = NOW()
                            WHERE id = :sessao_id AND company_id = :company_id
                        ");
                        $stmtUpdateSessao->execute([
                            'valor' => $valorPagamento,
                            'sessao_id' => $sessaoId,
                            'company_id' => $companyId
                        ]);

                        error_log("[ShipayWebhook] Movimento PDV criado para venda #{$vendaId} - Valor: {$valorPagamento}");
                    }
                }
            }

            $this->db->commit();
            error_log("[ShipayWebhook] Pagamento venda PDV processado com sucesso");

        } catch (Exception $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log("Erro ao processar pagamento venda PDV via webhook: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
        }
    }

    /**
     * Cria lançamento de entrada no fluxo de caixa (método completo)
     */
    private function criarLancamentoFluxoCaixaCompleto(array $conta): void
    {
        try {
            $companyId = $conta['company_id'];
            $contaId = $conta['id'];

            // Verificar se já existe lançamento para esta conta
            $stmtCheck = $this->db->prepare("
                SELECT id FROM fluxo_caixa
                WHERE reference_type = 'contas_receber'
                AND reference_id = :reference_id
                AND company_id = :company_id
            ");
            $stmtCheck->execute([
                'reference_id' => $contaId,
                'company_id' => $companyId
            ]);

            if ($stmtCheck->fetch()) {
                error_log("[ShipayWebhook] Lançamento de fluxo de caixa já existe para conta ID: {$contaId}");
                return; // Já existe lançamento, não criar duplicado
            }

            // Buscar valores da conta
            $peopleId = $conta['customer_id'] ?? $conta['pessoa_id'] ?? null;
            $amount = (float) ($conta['amount'] ?? $conta['valor'] ?? 0);
            $description = $conta['description'] ?? $conta['descricao'] ?? 'Recebimento de conta via Shipay';
            $planoContasId = $conta['plano_contas_id'] ?? $conta['plano_conta_id'] ?? null;
            $centroCustoId = $conta['centro_custo_id'] ?? null;

            // Calcular saldo atual (último saldo do fluxo de caixa)
            $stmtSaldo = $this->db->prepare("
                SELECT balance FROM fluxo_caixa
                WHERE company_id = :company_id
                ORDER BY date DESC, id DESC
                LIMIT 1
            ");
            $stmtSaldo->execute(['company_id' => $companyId]);
            $ultimoSaldo = (float) ($stmtSaldo->fetchColumn() ?: 0);

            // Calcular novo saldo (entrada aumenta o saldo)
            $novoSaldo = $ultimoSaldo + $amount;

            // Verificar colunas disponíveis na tabela fluxo_caixa
            $stmtCols = $this->db->query("SHOW COLUMNS FROM fluxo_caixa");
            $columns = $stmtCols->fetchAll();
            $columnNames = array_column($columns, 'Field');

            // Construir INSERT dinamicamente
            $campos = ['company_id', 'date', 'type', 'category', 'description', 'amount', 'balance', 'reference_type', 'reference_id', 'created_at'];
            $valores = [':company_id', 'CURDATE()', ':type', ':category', ':description', ':amount', ':balance', "'contas_receber'", ':reference_id', 'NOW()'];
            $params = [
                'company_id' => $companyId,
                'type' => 'entrada',
                'category' => 'Recebimento',
                'description' => $description,
                'amount' => $amount,
                'balance' => $novoSaldo,
                'reference_id' => $contaId
            ];

            if (in_array('people_id', $columnNames) && $peopleId) {
                $campos[] = 'people_id';
                $valores[] = ':people_id';
                $params['people_id'] = $peopleId;
            }

            if (in_array('plano_contas_id', $columnNames) && $planoContasId) {
                $campos[] = 'plano_contas_id';
                $valores[] = ':plano_contas_id';
                $params['plano_contas_id'] = $planoContasId;
            }

            if (in_array('centro_custo_id', $columnNames) && $centroCustoId) {
                $campos[] = 'centro_custo_id';
                $valores[] = ':centro_custo_id';
                $params['centro_custo_id'] = $centroCustoId;
            }

            // Inserir no fluxo de caixa
            $sql = "INSERT INTO fluxo_caixa (" . implode(', ', $campos) . ") VALUES (" . implode(', ', $valores) . ")";
            $stmt = $this->db->prepare($sql);
            $stmt->execute($params);

            error_log("[ShipayWebhook] Fluxo de caixa inserido - Tipo: entrada, Valor: {$amount}, Saldo: {$novoSaldo}, Conta ID: {$contaId}");

        } catch (Exception $e) {
            error_log("[ShipayWebhook] Erro ao criar lançamento completo no fluxo de caixa: " . $e->getMessage());
            error_log("[ShipayWebhook] Stack trace: " . $e->getTraceAsString());
        }
    }

    /**
     * Cria lançamento de entrada no fluxo de caixa (método simples - fallback)
     */
    private function criarLancamentoFluxoCaixa(int $contaId, float $valor, string $data, string $descricao, int $companyId): void
    {
        try {
            // Verificar se já existe lançamento para esta conta
            $stmtCheck = $this->db->prepare("
                SELECT id FROM fluxo_caixa
                WHERE reference_type = 'contas_receber'
                AND reference_id = :reference_id
                AND company_id = :company_id
            ");
            $stmtCheck->execute([
                'reference_id' => $contaId,
                'company_id' => $companyId
            ]);

            if ($stmtCheck->fetch()) {
                return; // Já existe lançamento
            }

            // Calcular saldo atual
            $stmtSaldo = $this->db->prepare("
                SELECT balance FROM fluxo_caixa
                WHERE company_id = :company_id
                ORDER BY date DESC, id DESC
                LIMIT 1
            ");
            $stmtSaldo->execute(['company_id' => $companyId]);
            $ultimoSaldo = $stmtSaldo->fetchColumn() ?: 0;

            $novoSaldo = $ultimoSaldo + $valor;

            // Inserir lançamento
            $stmtInsert = $this->db->prepare("
                INSERT INTO fluxo_caixa (
                    company_id,
                    date,
                    type,
                    category,
                    description,
                    amount,
                    balance,
                    reference_type,
                    reference_id,
                    created_at
                ) VALUES (
                    :company_id,
                    :date,
                    'entrada',
                    'Contas a Receber',
                    :description,
                    :amount,
                    :balance,
                    'contas_receber',
                    :reference_id,
                    NOW()
                )
            ");

            $stmtInsert->execute([
                'company_id' => $companyId,
                'date' => $data,
                'description' => $descricao,
                'amount' => $valor,
                'balance' => $novoSaldo,
                'reference_id' => $contaId
            ]);

        } catch (Exception $e) {
            error_log("[ShipayWebhook] Erro ao criar lançamento no fluxo de caixa: " . $e->getMessage());
        }
    }
}

