<?php
/**
 * Helper de Financeiro - Checkout Pro 2025
 * 
 * Funções auxiliares para cálculo de comissões, atualização de saldos e gestão financeira
 */

require_once __DIR__ . '/../config/config_db.php';
require_once __DIR__ . '/settings_helper.php';

/**
 * Calcula e registra comissões de uma venda aprovada
 * 
 * @param int $transacao_id ID da transação
 * @param int $produto_id ID do produto
 * @param int $produtor_id ID do produtor
 * @param int|null $afiliado_id ID do afiliado (null se não houver)
 * @param float $valor_total Valor total da transação
 * @return array|false Retorna array com valores calculados ou false em caso de erro
 */
function calcular_e_registrar_comissoes($transacao_id, $produto_id, $produtor_id, $afiliado_id, $valor_total) {
    global $pdo;
    
    try {
        // Buscar comissão do afiliado (se houver)
        $comissao_afiliado_percentual = 0;
        if ($afiliado_id) {
            try {
                $sql_comissao = "SELECT comissao_valor, comissao_tipo 
                                FROM afiliacoes 
                                WHERE produto_id = :produto_id 
                                AND usuario_id = :afiliado_id 
                                AND status = 'ativo' 
                                LIMIT 1";
                $stmt_comissao = $pdo->prepare($sql_comissao);
                $stmt_comissao->execute([
                    ':produto_id' => $produto_id,
                    ':afiliado_id' => $afiliado_id
                ]);
                $afiliacao = $stmt_comissao->fetch(PDO::FETCH_ASSOC);
                
                if ($afiliacao && $afiliacao['comissao_tipo'] === 'percentual') {
                    $comissao_afiliado_percentual = floatval($afiliacao['comissao_valor']);
                }
            } catch (PDOException $e) {
                error_log("Erro ao buscar comissão do afiliado: " . $e->getMessage());
                // Continua sem comissão de afiliado
            }
        }
        
        // Calcular taxa da plataforma (dinâmica)
        $taxa_tipo = getSystemSetting('taxa_plataforma_venda_tipo', 'percentual');
        $taxa_valor = floatval(getSystemSetting('taxa_plataforma_venda_valor', 0));
        $valor_plataforma = 0;
        
        if ($taxa_valor > 0) {
            if ($taxa_tipo === 'percentual') {
                $valor_plataforma = round($valor_total * ($taxa_valor / 100), 2);
            } else {
                // Taxa fixa
                $valor_plataforma = round($taxa_valor, 2);
            }
        }
        
        // Calcular valores (descontar taxa da plataforma primeiro)
        $valor_restante = round($valor_total - $valor_plataforma, 2);
        $valor_afiliado = 0;
        $valor_produtor = $valor_restante;
        
        // Calcular comissão do afiliado sobre o valor restante (após desconto da plataforma)
        if ($afiliado_id && $comissao_afiliado_percentual > 0) {
            $valor_afiliado = round($valor_restante * ($comissao_afiliado_percentual / 100), 2);
            $valor_produtor = round($valor_restante - $valor_afiliado, 2);
        }
        
        // Registrar comissões
        try {
            $sql_comissao = "INSERT INTO vendas_comissoes (transacao_id, produtor_id, afiliado_id, valor_produtor, valor_afiliado, valor_plataforma, created_at) 
                           VALUES (:transacao_id, :produtor_id, :afiliado_id, :valor_produtor, :valor_afiliado, :valor_plataforma, NOW())";
            $stmt_comissao = $pdo->prepare($sql_comissao);
            $stmt_comissao->execute([
                ':transacao_id' => $transacao_id,
                ':produtor_id' => $produtor_id,
                ':afiliado_id' => $afiliado_id ?: null,
                ':valor_produtor' => $valor_produtor,
                ':valor_afiliado' => $valor_afiliado,
                ':valor_plataforma' => $valor_plataforma
            ]);
        } catch (PDOException $e) {
            // Se a tabela não existir, apenas loga o erro
            if (strpos($e->getMessage(), "vendas_comissoes") !== false) {
                error_log("Tabela vendas_comissoes não existe. Execute a migração 2025_08_vendas_comissoes.sql");
                return false;
            }
            throw $e;
        }
        
        // Atualizar saldos (adicionar em saldo_pendente)
        atualizar_saldo_usuario($produtor_id, $valor_produtor, 'pendente', 'adicionar');
        
        if ($afiliado_id && $valor_afiliado > 0) {
            atualizar_saldo_usuario($afiliado_id, $valor_afiliado, 'pendente', 'adicionar');
        }
        
        return [
            'valor_produtor' => $valor_produtor,
            'valor_afiliado' => $valor_afiliado,
            'valor_plataforma' => $valor_plataforma
        ];
        
    } catch (Exception $e) {
        error_log("Erro ao calcular comissões: " . $e->getMessage());
        return false;
    }
}

/**
 * Atualiza o saldo de um usuário
 * 
 * @param int $usuario_id ID do usuário
 * @param float $valor Valor a adicionar/subtrair
 * @param string $tipo Tipo: 'disponivel', 'pendente', 'bloqueado'
 * @param string $operacao Operação: 'adicionar' ou 'subtrair'
 * @return bool
 */
function atualizar_saldo_usuario($usuario_id, $valor, $tipo = 'pendente', $operacao = 'adicionar') {
    global $pdo;
    
    try {
        // Verificar se o registro existe
        $sql_check = "SELECT id FROM saldos_usuarios WHERE usuario_id = :usuario_id LIMIT 1";
        $stmt_check = $pdo->prepare($sql_check);
        $stmt_check->execute([':usuario_id' => $usuario_id]);
        $existe = $stmt_check->fetch(PDO::FETCH_ASSOC);
        
        if (!$existe) {
            // Criar registro inicial
            $sql_insert = "INSERT INTO saldos_usuarios (usuario_id, saldo_disponivel, saldo_pendente, saldo_bloqueado, updated_at) 
                          VALUES (:usuario_id, 0, 0, 0, NOW())";
            $stmt_insert = $pdo->prepare($sql_insert);
            $stmt_insert->execute([':usuario_id' => $usuario_id]);
        }
        
        // Atualizar saldo
        $campo = 'saldo_' . $tipo;
        $operador = $operacao === 'adicionar' ? '+' : '-';
        
        $sql_update = "UPDATE saldos_usuarios 
                      SET {$campo} = {$campo} {$operador} :valor, updated_at = NOW() 
                      WHERE usuario_id = :usuario_id";
        $stmt_update = $pdo->prepare($sql_update);
        $stmt_update->execute([
            ':valor' => $valor,
            ':usuario_id' => $usuario_id
        ]);
        
        return true;
    } catch (PDOException $e) {
        // Se a tabela não existir, apenas loga o erro
        if (strpos($e->getMessage(), "saldos_usuarios") !== false) {
            error_log("Tabela saldos_usuarios não existe. Execute a migração 2025_07_saldos_saques.sql");
            return false;
        }
        error_log("Erro ao atualizar saldo: " . $e->getMessage());
        return false;
    }
}

/**
 * Move saldo de pendente para disponível após período de garantia
 * 
 * @param int|null $dias_garantia Número de dias de garantia (null para usar configuração do sistema)
 * @return int Número de registros atualizados
 */
function liberar_saldos_pendentes($dias_garantia = null) {
    global $pdo;
    
    try {
        // Se não foi informado, buscar da configuração do sistema
        if ($dias_garantia === null) {
            $dias_garantia = intval(getSystemSetting('prazo_liberacao_dias', 30));
        }
        
        // Buscar comissões pendentes que já passaram do período de garantia
        $sql = "SELECT vc.produtor_id, vc.afiliado_id, vc.valor_produtor, vc.valor_afiliado, vc.created_at
                FROM vendas_comissoes vc
                INNER JOIN transacoes t ON t.id = vc.transacao_id
                WHERE t.status = 'Aprovado'
                AND DATE_ADD(vc.created_at, INTERVAL :dias DAY) <= NOW()
                AND NOT EXISTS (
                    SELECT 1 FROM saldos_usuarios su 
                    WHERE su.usuario_id = vc.produtor_id 
                    AND su.saldo_pendente >= vc.valor_produtor
                )";
        
        // Nota: Esta função é preparada para uso futuro via cron job ou interface admin
        // Por enquanto, está comentada para não executar automaticamente
        
        return 0;
    } catch (PDOException $e) {
        error_log("Erro ao liberar saldos pendentes: " . $e->getMessage());
        return 0;
    }
}

/**
 * Obtém o saldo de um usuário
 * 
 * @param int $usuario_id ID do usuário
 * @return array|false Retorna array com saldos ou false se não existir
 */
function obter_saldo_usuario($usuario_id) {
    global $pdo;
    
    try {
        $sql = "SELECT saldo_disponivel, saldo_pendente, saldo_bloqueado 
                FROM saldos_usuarios 
                WHERE usuario_id = :usuario_id 
                LIMIT 1";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([':usuario_id' => $usuario_id]);
        $saldo = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$saldo) {
            // Retornar valores zerados se não existir
            return [
                'saldo_disponivel' => 0.00,
                'saldo_pendente' => 0.00,
                'saldo_bloqueado' => 0.00
            ];
        }
        
        return $saldo;
    } catch (PDOException $e) {
        error_log("Erro ao obter saldo: " . $e->getMessage());
        return [
            'saldo_disponivel' => 0.00,
            'saldo_pendente' => 0.00,
            'saldo_bloqueado' => 0.00
        ];
    }
}

/**
 * Processa estorno de comissões quando uma transação é reembolsada
 * 
 * @param int $transacao_id ID da transação reembolsada
 * @return bool Retorna true se o estorno foi processado, false caso contrário
 */
function processar_estorno_comissoes($transacao_id) {
    global $pdo;
    
    try {
        // Buscar comissão registrada para essa transação
        $sql_comissao = "SELECT id, produtor_id, afiliado_id, valor_produtor, valor_afiliado 
                        FROM vendas_comissoes 
                        WHERE transacao_id = :transacao_id 
                        LIMIT 1";
        $stmt_comissao = $pdo->prepare($sql_comissao);
        $stmt_comissao->execute([':transacao_id' => $transacao_id]);
        $comissao = $stmt_comissao->fetch(PDO::FETCH_ASSOC);
        
        // Se não existe comissão, não há nada para estornar
        if (!$comissao) {
            return false;
        }
        
        // Verificar se já foi estornado (usando uma flag lógica: se o valor foi subtraído do saldo)
        // Como não temos campo de status na tabela, vamos verificar se o saldo foi ajustado
        // Por segurança, vamos sempre processar o estorno e subtrair do saldo
        
        // Subtrair saldo do produtor
        if ($comissao['produtor_id'] && $comissao['valor_produtor'] > 0) {
            atualizar_saldo_usuario(
                intval($comissao['produtor_id']), 
                floatval($comissao['valor_produtor']), 
                'pendente', 
                'subtrair'
            );
        }
        
        // Subtrair saldo do afiliado (se houver)
        if ($comissao['afiliado_id'] && $comissao['valor_afiliado'] > 0) {
            atualizar_saldo_usuario(
                intval($comissao['afiliado_id']), 
                floatval($comissao['valor_afiliado']), 
                'pendente', 
                'subtrair'
            );
        }
        
        // Marcar a transação como reembolsada (atualizar status na tabela transacoes)
        // O status será atualizado pelo webhook, mas garantimos que as comissões foram estornadas
        
        error_log("Estorno de comissões processado para transação ID: {$transacao_id}");
        return true;
        
    } catch (PDOException $e) {
        error_log("Erro ao processar estorno de comissões: " . $e->getMessage());
        return false;
    }
}


