<?php

namespace App\Controllers;

use Exception;

class RelatoriosController extends BaseController
{
    /**
     * Página principal de relatórios
     */
    public function index(): void
    {
        // Verificar permissão de visualização
        if (!$this->canView('relatorios')) {
            $this->response->forbidden('Você não tem permissão para visualizar relatórios.');
            return;
        }

        $this->view('relatorios/index', [
            'pageTitle' => 'Relatórios'
        ]);
    }

    /**
     * Relatório de vendas por período
     */
    public function vendasPeriodo(): void
    {
        try {
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');

            $companyId = $this->getCompanyId();

            $stmt = $this->db->prepare("
                SELECT DATE(v.created_at) as data,
                       COUNT(*) as total_vendas,
                       SUM(v.total) as total_valor
                FROM vendas v
                WHERE v.company_id = :company_id
                AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                GROUP BY DATE(v.created_at)
                ORDER BY data ASC
            ");
            $stmt->execute([
                'company_id' => $companyId,
                'data_inicio' => $dataInicio,
                'data_fim' => $dataFim
            ]);
            $dados = $stmt->fetchAll();

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/vendas-periodo', [
                'dados' => $dados,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Vendas por Período'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao gerar relatório de vendas por período: " . $e->getMessage());
            $this->error('Erro ao gerar relatório');
        }
    }

    /**
     * Relatório de vendas por produto
     */
    public function vendasProduto(): void
    {
        try {
            $companyId = $this->getCompanyId();

            // Verificar se a tabela existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'vendas_itens'");
            if ($stmtCheck->rowCount() == 0) {
                throw new \Exception("Tabela vendas_itens não existe");
            }

            // Usar company_id diretamente de vendas_itens se existir, senão usar join com vendas
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'company_id'");
            $temCompanyId = $stmtCheck->fetch() !== false;

            if ($temCompanyId) {
                $stmt = $this->db->prepare("
                    SELECT vi.product_name,
                           SUM(vi.quantity) as total_vendido,
                           SUM(vi.total_price) as total_faturamento,
                           COUNT(DISTINCT vi.venda_id) as total_vendas
                    FROM vendas_itens vi
                    WHERE vi.company_id = :company_id
                    GROUP BY vi.product_name
                    ORDER BY total_faturamento DESC
                ");
            } else {
                $stmt = $this->db->prepare("
                    SELECT vi.product_name,
                           SUM(vi.quantity) as total_vendido,
                           SUM(vi.total_price) as total_faturamento,
                           COUNT(DISTINCT vi.venda_id) as total_vendas
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE v.company_id = :company_id
                    GROUP BY vi.product_name
                    ORDER BY total_faturamento DESC
                ");
            }

            $stmt->execute(['company_id' => $companyId]);
            $dados = $stmt->fetchAll() ?: [];

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/vendas-produto', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Vendas por Produto'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de vendas por produto: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de vendas por cliente
     */
    public function vendasCliente(): void
    {
        try {
            $companyId = $this->getCompanyId();

            $stmt = $this->db->prepare("
                SELECT v.customer_name,
                       v.customer_document,
                       COUNT(*) as total_vendas,
                       SUM(v.total) as total_gasto,
                       AVG(v.total) as ticket_medio
                FROM vendas v
                WHERE v.company_id = :company_id
                GROUP BY v.customer_name, v.customer_document
                ORDER BY total_gasto DESC
            ");
            $stmt->execute(['company_id' => $companyId]);
            $dados = $stmt->fetchAll();

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/vendas-cliente', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Vendas por Cliente'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao gerar relatório de vendas por cliente: " . $e->getMessage());
            $this->error('Erro ao gerar relatório');
        }
    }

    /**
     * Relatório de vendas por vendedor
     */
    public function vendasVendedor(): void
    {
        try {
            $companyId = $this->getCompanyId();

            // Verificar qual coluna de vendedor existe na tabela vendas
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas LIKE 'vendor_id'");
            $temVendorId = $stmtCheck->fetch() !== false;

            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas LIKE 'seller_id'");
            $temSellerId = $stmtCheck->fetch() !== false;

            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas LIKE 'vendedor_id'");
            $temVendedorId = $stmtCheck->fetch() !== false;

            // Determinar qual coluna usar
            $colunaVendedor = null;
            if ($temVendorId) {
                $colunaVendedor = 'vendor_id';
            } elseif ($temSellerId) {
                $colunaVendedor = 'seller_id';
            } elseif ($temVendedorId) {
                $colunaVendedor = 'vendedor_id';
            }

            if ($colunaVendedor) {
                $stmt = $this->db->prepare("
                    SELECT u.name as vendedor,
                           COUNT(v.id) as total_vendas,
                           SUM(v.total) as total_faturamento,
                           AVG(v.total) as ticket_medio
                    FROM vendas v
                    LEFT JOIN users u ON v.{$colunaVendedor} = u.id
                    WHERE v.company_id = :company_id
                    AND v.{$colunaVendedor} IS NOT NULL
                    GROUP BY u.name, v.{$colunaVendedor}
                    ORDER BY total_faturamento DESC
                ");
            } else {
                // Se não houver coluna de vendedor, retornar vendas sem vendedor
                $stmt = $this->db->prepare("
                    SELECT 'Não informado' as vendedor,
                           COUNT(v.id) as total_vendas,
                           SUM(v.total) as total_faturamento,
                           AVG(v.total) as ticket_medio
                    FROM vendas v
                    WHERE v.company_id = :company_id
                    GROUP BY 1
                    ORDER BY total_faturamento DESC
                ");
            }

            $stmt->execute(['company_id' => $companyId]);
            $dados = $stmt->fetchAll() ?: [];

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/vendas-vendedor', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Vendas por Vendedor'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de vendas por vendedor: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de fluxo de caixa
     */
    public function fluxoCaixa(): void
    {
        try {
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');

            $companyId = $this->getCompanyId();

            // Verificar status válidos para vendas
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas LIKE 'status'");
            $temStatus = $stmtCheck->fetch() !== false;

            $statusVendas = ['concluida', 'concluído', 'faturado', 'faturada', 'pendente'];
            $whereStatus = '';
            if ($temStatus) {
                // Tentar diferentes valores de status
                $whereStatus = "AND (status = 'concluida' OR status = 'concluído' OR status = 'faturado' OR status = 'faturada')";
            }

            // Entradas (vendas)
            $entradas = [];
            try {
                $stmt = $this->db->prepare("
                    SELECT DATE(created_at) as data,
                           SUM(total) as entradas
                    FROM vendas
                    WHERE company_id = :company_id
                    AND DATE(created_at) BETWEEN :data_inicio AND :data_fim
                    {$whereStatus}
                    GROUP BY DATE(created_at)
                    ORDER BY data ASC
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $entradas = $stmt->fetchAll() ?: [];
            } catch (\Exception $e) {
                error_log("Erro ao buscar entradas (vendas): " . $e->getMessage());
            }

            // Saídas (contas a pagar)
            $saidas = [];
            try {
                // Verificar se a tabela existe
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'contas_pagar'");
                if ($stmtCheck->rowCount() > 0) {
                    // Verificar colunas
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'company_id'");
                    $temCompanyId = $stmtCheck->fetch() !== false;

                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'due_date'");
                    $temDueDate = $stmtCheck->fetch() !== false;
                    if (!$temDueDate) {
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'data_vencimento'");
                        $temDueDate = $stmtCheck->fetch() !== false;
                    }

                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'amount'");
                    $temAmount = $stmtCheck->fetch() !== false;
                    if (!$temAmount) {
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'valor'");
                        $temAmount = $stmtCheck->fetch() !== false;
                    }

                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'status'");
                    $temStatus = $stmtCheck->fetch() !== false;

                    $colunaData = $temDueDate ? 'due_date' : 'data_vencimento';
                    $colunaValor = $temAmount ? 'amount' : 'valor';
                    $whereCompany = $temCompanyId ? 'AND company_id = :company_id' : '';
                    $whereStatusPagar = $temStatus ? "AND status = 'pago'" : '';

                    $stmt = $this->db->prepare("
                        SELECT DATE({$colunaData}) as data,
                               SUM({$colunaValor}) as saidas
                        FROM contas_pagar
                        WHERE DATE({$colunaData}) BETWEEN :data_inicio AND :data_fim
                        {$whereCompany}
                        {$whereStatusPagar}
                        GROUP BY DATE({$colunaData})
                        ORDER BY data ASC
                    ");

                    $params = [
                        'data_inicio' => $dataInicio,
                        'data_fim' => $dataFim
                    ];
                    if ($temCompanyId) {
                        $params['company_id'] = $companyId;
                    }

                    $stmt->execute($params);
                    $saidas = $stmt->fetchAll() ?: [];
                }
            } catch (\Exception $e) {
                error_log("Erro ao buscar saídas (contas a pagar): " . $e->getMessage());
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/fluxo-caixa', [
                'entradas' => $entradas,
                'saidas' => $saidas,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Fluxo de Caixa'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de fluxo de caixa: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de contas a receber
     */
    public function contasReceber(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dados = [];

            // Verificar se a tabela existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'contas_receber'");
            if ($stmtCheck->rowCount() > 0) {
                // Verificar colunas
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'company_id'");
                $temCompanyId = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'customer_name'");
                $temCustomerName = $stmtCheck->fetch() !== false;
                $temClienteNome = false;
                if (!$temCustomerName) {
                    $stmtCheck2 = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'cliente_nome'");
                    $temClienteNome = $stmtCheck2->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'description'");
                $temDescription = $stmtCheck->fetch() !== false;
                if (!$temDescription) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'descricao'");
                    $temDescription = $stmtCheck->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'amount'");
                $temAmount = $stmtCheck->fetch() !== false;
                if (!$temAmount) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'valor'");
                    $temAmount = $stmtCheck->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'due_date'");
                $temDueDate = $stmtCheck->fetch() !== false;
                if (!$temDueDate) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'data_vencimento'");
                    $temDueDate = $stmtCheck->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'status'");
                $temStatus = $stmtCheck->fetch() !== false;

                // Determinar nomes das colunas
                $colunaCliente = $temCustomerName ? 'customer_name' : ($temClienteNome ? 'cliente_nome' : "''");
                $colunaDescricao = $temDescription ? 'description' : 'descricao';
                $colunaValor = $temAmount ? 'amount' : 'valor';
                $colunaData = $temDueDate ? 'due_date' : 'data_vencimento';
                $colunaStatus = $temStatus ? 'status' : "'pendente'";
                $whereCompany = $temCompanyId ? 'WHERE company_id = :company_id' : 'WHERE 1=1';

                $stmt = $this->db->prepare("
                    SELECT {$colunaCliente} as customer_name,
                           {$colunaDescricao} as description,
                           {$colunaValor} as amount,
                           {$colunaData} as due_date,
                           {$colunaStatus} as status,
                           DATEDIFF(CURDATE(), {$colunaData}) as dias_atraso
                    FROM contas_receber
                    {$whereCompany}
                    ORDER BY {$colunaData} ASC
                ");

                $params = [];
                if ($temCompanyId) {
                    $params['company_id'] = $companyId;
                }

                $stmt->execute($params);
                $dados = $stmt->fetchAll() ?: [];
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/contas-receber', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Contas a Receber'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de contas a receber: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de contas a pagar
     */
    public function contasPagar(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dados = [];

            // Verificar se a tabela existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'contas_pagar'");
            if ($stmtCheck->rowCount() > 0) {
                // Verificar colunas
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'company_id'");
                $temCompanyId = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'supplier_name'");
                $temSupplierName = $stmtCheck->fetch() !== false;
                $temFornecedorNome = false;
                if (!$temSupplierName) {
                    $stmtCheck2 = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'fornecedor_nome'");
                    $temFornecedorNome = $stmtCheck2->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'description'");
                $temDescription = $stmtCheck->fetch() !== false;
                if (!$temDescription) {
                    $stmtCheck2 = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'descricao'");
                    $temDescription = $stmtCheck2->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'amount'");
                $temAmount = $stmtCheck->fetch() !== false;
                if (!$temAmount) {
                    $stmtCheck2 = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'valor'");
                    $temAmount = $stmtCheck2->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'due_date'");
                $temDueDate = $stmtCheck->fetch() !== false;
                if (!$temDueDate) {
                    $stmtCheck2 = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'data_vencimento'");
                    $temDueDate = $stmtCheck2->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'status'");
                $temStatus = $stmtCheck->fetch() !== false;

                // Determinar nomes das colunas
                $colunaFornecedor = $temSupplierName ? 'supplier_name' : ($temFornecedorNome ? 'fornecedor_nome' : "''");
                $colunaDescricao = $temDescription ? 'description' : 'descricao';
                $colunaValor = $temAmount ? 'amount' : 'valor';
                $colunaData = $temDueDate ? 'due_date' : 'data_vencimento';
                $colunaStatus = $temStatus ? 'status' : "'pendente'";
                $whereCompany = $temCompanyId ? 'WHERE company_id = :company_id' : 'WHERE 1=1';

                $stmt = $this->db->prepare("
                    SELECT {$colunaFornecedor} as supplier_name,
                           {$colunaDescricao} as description,
                           {$colunaValor} as amount,
                           {$colunaData} as due_date,
                           {$colunaStatus} as status,
                           DATEDIFF(CURDATE(), {$colunaData}) as dias_atraso
                    FROM contas_pagar
                    {$whereCompany}
                    ORDER BY {$colunaData} ASC
                ");

                $params = [];
                if ($temCompanyId) {
                    $params['company_id'] = $companyId;
                }

                $stmt->execute($params);
                $dados = $stmt->fetchAll() ?: [];
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/contas-pagar', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Contas a Pagar'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de contas a pagar: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * DRE (Demonstrativo de Resultado do Exercício)
     */
    public function dre(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $ano = $this->request->get('ano') ?: date('Y');

            // Verificar se a tabela fluxo_caixa existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'fluxo_caixa'");
            if ($stmtCheck->rowCount() === 0) {
                throw new \Exception("Tabela fluxo_caixa não encontrada");
            }

            // Receitas (entradas do fluxo de caixa)
            $stmt = $this->db->prepare("
                SELECT COALESCE(SUM(amount), 0) as total_receitas
                FROM fluxo_caixa
                WHERE company_id = :company_id
                AND type = 'entrada'
                AND YEAR(date) = :ano
            ");
            $stmt->execute([
                'company_id' => $companyId,
                'ano' => $ano
            ]);
            $receitas = (float) ($stmt->fetchColumn() ?: 0);

            // Custos (saídas com categoria relacionada a custos)
            // Considerando custos como saídas com categorias que contenham 'custo', 'custo produto', 'custo venda', etc.
            $stmt = $this->db->prepare("
                SELECT COALESCE(SUM(amount), 0) as total_custos
                FROM fluxo_caixa
                WHERE company_id = :company_id
                AND type = 'saida'
                AND YEAR(date) = :ano
                AND (
                    LOWER(category) LIKE '%custo%'
                    OR LOWER(category) LIKE '%custo produto%'
                    OR LOWER(category) LIKE '%custo venda%'
                    OR LOWER(category) LIKE '%cmv%'
                    OR LOWER(description) LIKE '%custo produto%'
                    OR LOWER(description) LIKE '%custo venda%'
                )
            ");
            $stmt->execute([
                'company_id' => $companyId,
                'ano' => $ano
            ]);
            $custos = (float) ($stmt->fetchColumn() ?: 0);

            // Despesas (saídas que não são custos)
            $stmt = $this->db->prepare("
                SELECT COALESCE(SUM(amount), 0) as total_despesas
                FROM fluxo_caixa
                WHERE company_id = :company_id
                AND type = 'saida'
                AND YEAR(date) = :ano
                AND NOT (
                    LOWER(category) LIKE '%custo%'
                    OR LOWER(category) LIKE '%custo produto%'
                    OR LOWER(category) LIKE '%custo venda%'
                    OR LOWER(category) LIKE '%cmv%'
                    OR LOWER(description) LIKE '%custo produto%'
                    OR LOWER(description) LIKE '%custo venda%'
                )
            ");
            $stmt->execute([
                'company_id' => $companyId,
                'ano' => $ano
            ]);
            $despesas = (float) ($stmt->fetchColumn() ?: 0);

            // Calcular lucro
            $lucroBruto = $receitas - $custos;
            $lucroLiquido = $lucroBruto - $despesas;

            // Verificar se existem campos para detalhamento
            $hasPlanoContas = false;
            $hasCentroCusto = false;

            try {
                $stmt = $this->db->query("SHOW COLUMNS FROM fluxo_caixa LIKE 'plano_contas_id'");
                $hasPlanoContas = $stmt->fetch() !== false;
            } catch (Exception $e) {
                error_log("Erro ao verificar campo plano_contas_id: " . $e->getMessage());
            }

            try {
                $stmt = $this->db->query("SHOW COLUMNS FROM fluxo_caixa LIKE 'centro_custo_id'");
                $hasCentroCusto = $stmt->fetch() !== false;
            } catch (Exception $e) {
                error_log("Erro ao verificar campo centro_custo_id: " . $e->getMessage());
            }

            // Detalhamento por Plano de Contas
            $detalhamentoPlanoContas = [];
            if ($hasPlanoContas) {
                try {
                    // Verificar se a tabela plano_contas existe
                    $stmtCheck = $this->db->query("SHOW TABLES LIKE 'plano_contas'");
                    if ($stmtCheck->fetch()) {
                        // Verificar estrutura da tabela
                        $stmtColumns = $this->db->query("SHOW COLUMNS FROM plano_contas");
                        $columns = array_column($stmtColumns->fetchAll(), 'Field');

                        $colCodigo = in_array('code', $columns) ? 'code' : (in_array('codigo', $columns) ? 'codigo' : 'id');
                        $colNome = in_array('name', $columns) ? 'name' : (in_array('nome', $columns) ? 'nome' : 'name');

                        $stmt = $this->db->prepare("
                            SELECT
                                pc.id,
                                pc.{$colCodigo} as codigo,
                                pc.{$colNome} as nome,
                                SUM(CASE WHEN fc.type = 'entrada' THEN fc.amount ELSE 0 END) as receitas,
                                SUM(CASE WHEN fc.type = 'saida' THEN fc.amount ELSE 0 END) as despesas
                            FROM fluxo_caixa fc
                            INNER JOIN plano_contas pc ON fc.plano_contas_id = pc.id
                            WHERE fc.company_id = :company_id
                            AND YEAR(fc.date) = :ano
                            AND pc.company_id = :company_id
                            GROUP BY pc.id, pc.{$colCodigo}, pc.{$colNome}
                            HAVING receitas > 0 OR despesas > 0
                            ORDER BY pc.{$colCodigo} ASC
                        ");
                        $stmt->execute([
                            'company_id' => $companyId,
                            'ano' => $ano
                        ]);
                        $detalhamentoPlanoContas = $stmt->fetchAll();
                    }
                } catch (Exception $e) {
                    error_log("Erro ao buscar detalhamento por plano de contas: " . $e->getMessage());
                }
            }

            // Detalhamento por Centro de Custos
            $detalhamentoCentroCustos = [];
            if ($hasCentroCusto) {
                try {
                    // Verificar se a tabela centro_custos existe
                    $stmtCheck = $this->db->query("SHOW TABLES LIKE 'centro_custos'");
                    if ($stmtCheck->fetch()) {
                        $stmt = $this->db->prepare("
                            SELECT
                                cc.id,
                                cc.code as codigo,
                                cc.name as nome,
                                SUM(CASE WHEN fc.type = 'entrada' THEN fc.amount ELSE 0 END) as receitas,
                                SUM(CASE WHEN fc.type = 'saida' THEN fc.amount ELSE 0 END) as despesas
                            FROM fluxo_caixa fc
                            INNER JOIN centro_custos cc ON fc.centro_custo_id = cc.id
                            WHERE fc.company_id = :company_id
                            AND YEAR(fc.date) = :ano
                            AND cc.company_id = :company_id
                            GROUP BY cc.id, cc.code, cc.name
                            HAVING receitas > 0 OR despesas > 0
                            ORDER BY cc.code ASC
                        ");
                        $stmt->execute([
                            'company_id' => $companyId,
                            'ano' => $ano
                        ]);
                        $detalhamentoCentroCustos = $stmt->fetchAll();
                    }
                } catch (Exception $e) {
                    error_log("Erro ao buscar detalhamento por centro de custos: " . $e->getMessage());
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/dre', [
                'receitas' => $receitas,
                'custos' => $custos,
                'despesas' => $despesas,
                'lucroBruto' => $lucroBruto,
                'lucroLiquido' => $lucroLiquido,
                'ano' => $ano,
                'empresa' => $empresa,
                'detalhamentoPlanoContas' => $detalhamentoPlanoContas,
                'detalhamentoCentroCustos' => $detalhamentoCentroCustos,
                'hasPlanoContas' => $hasPlanoContas,
                'hasCentroCusto' => $hasCentroCusto,
                'pageTitle' => 'DRE - Demonstrativo de Resultado do Exercício'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar DRE: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de estoque atual
     */
    public function estoqueAtual(): void
    {
        try {
            $companyId = $this->getCompanyId();
            if (!$companyId) {
                throw new \Exception("Company ID não encontrado na sessão");
            }

            $dados = [];

            // Verificar se a tabela produtos existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'produtos'");
            if ($stmtCheck->rowCount() > 0) {
                // Verificar colunas
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'company_id'");
                $temCompanyId = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'type'");
                $temType = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'stock_quantity'");
                $temStockQuantity = $stmtCheck->fetch() !== false;
                if (!$temStockQuantity) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'quantidade'");
                    $temStockQuantity = $stmtCheck->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'min_stock'");
                $temMinStock = $stmtCheck->fetch() !== false;
                $colunaMin = 'min_stock';
                if (!$temMinStock) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'estoque_minimo'");
                    $temMinStock = $stmtCheck->fetch() !== false;
                    if ($temMinStock) {
                        $colunaMin = 'estoque_minimo';
                    }
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'max_stock'");
                $temMaxStock = $stmtCheck->fetch() !== false;
                $colunaMax = 'max_stock';
                if (!$temMaxStock) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'estoque_maximo'");
                    $temMaxStock = $stmtCheck->fetch() !== false;
                    if ($temMaxStock) {
                        $colunaMax = 'estoque_maximo';
                    }
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'price'");
                $temPrice = $stmtCheck->fetch() !== false;
                $colunaPreco = 'price';
                if (!$temPrice) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'preco_venda'");
                    $temPrice = $stmtCheck->fetch() !== false;
                    if ($temPrice) {
                        $colunaPreco = 'preco_venda';
                    }
                }

                $colunaEstoque = $temStockQuantity ? 'stock_quantity' : 'quantidade';
                $whereType = $temType ? "AND p.type = 'produto'" : '';
                $whereCompany = $temCompanyId ? "WHERE p.company_id = :company_id" : 'WHERE 1=1';

                // Verificar se tabela estoque_movimentos existe
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'estoque_movimentos'");
                $temMovimentacoes = $stmtCheck->rowCount() > 0;

                // Verificar se tabela categorias existe
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'categorias'");
                $temCategorias = $stmtCheck->rowCount() > 0;

                if ($temCategorias) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM categorias LIKE 'id'");
                    $temCategoriaId = $stmtCheck->fetch() !== false;
                    $joinCategoria = $temCategoriaId ? "LEFT JOIN categorias c ON p.category_id = c.id" : "";
                    $colunaCategoria = $temCategoriaId ? "c.name as category_name" : "'' as category_name";
                } else {
                    $joinCategoria = "";
                    $colunaCategoria = "'' as category_name";
                }

                $selectMinStock = $temMinStock ? "{$colunaMin}" : "0";
                $selectMaxStock = $temMaxStock ? "{$colunaMax}" : "0";
                $selectPreco = $temPrice ? "{$colunaPreco}" : "0";

                // Calcular estoque a partir de estoque_movimentos
                if ($temMovimentacoes) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'product_id'");
                    $temProductId = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'company_id'");
                    $temMovCompanyId = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'type'");
                    $temMovType = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'quantity'");
                    $temMovQuantity = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'lote'");
                    $temLote = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'validade'");
                    $temValidade = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'fabricacao'");
                    $temFabricacao = $stmtCheck->fetch() !== false;

                    if ($temProductId && $temMovType && $temMovQuantity) {
                        // Construir WHERE clause
                        $whereParts = [];
                        $params = [];

                        // Se ambos têm company_id, usar apenas um filtro (em.company_id já filtra os produtos)
                        if ($temMovCompanyId) {
                            $whereParts[] = "em.company_id = :company_id";
                            $params['company_id'] = $companyId;
                        } elseif ($temCompanyId) {
                            // Se só produtos tem company_id, usar esse
                            $whereParts[] = "p.company_id = :company_id";
                            $params['company_id'] = $companyId;
                        }

                        $whereClause = !empty($whereParts) ? "WHERE " . implode(" AND ", $whereParts) : "WHERE 1=1";

                        // Agrupar por product_id, lote, fabricação e validade
                        // Cada combinação única será uma linha separada
                        $groupByCols = "em.product_id";
                        $selectCols = "p.name, p.sku";

                        // Sempre incluir lote, fabricação e validade no GROUP BY se existirem
                        if ($temLote) {
                            $groupByCols .= ", em.lote";
                            $selectCols .= ", COALESCE(em.lote, '') as lote";
                        } else {
                            $selectCols .= ", '' as lote";
                        }

                        if ($temFabricacao) {
                            $groupByCols .= ", em.fabricacao";
                            $selectCols .= ", em.fabricacao";
                        } else {
                            $selectCols .= ", NULL as fabricacao";
                        }

                        if ($temValidade) {
                            $groupByCols .= ", em.validade";
                            $selectCols .= ", em.validade";
                        } else {
                            $selectCols .= ", NULL as validade";
                        }

                        // Ordenar por produto, depois por validade, depois por lote
                        $orderBy = "p.name ASC";
                        if ($temValidade) {
                            $orderBy .= ", em.validade ASC";
                        }
                        if ($temLote) {
                            $orderBy .= ", em.lote ASC";
                        }

                        // Query para agrupar por produto, lote, fabricação e validade
                        // Cada combinação única de lote+fabricação+validade será uma linha separada
                        // IMPORTANTE: O GROUP BY deve incluir TODOS os campos que diferenciam os lotes
                        $stmt = $this->db->prepare("
                            SELECT {$selectCols},
                                   COALESCE(SUM(CASE
                                       WHEN em.type = 'entrada' THEN ABS(em.quantity)
                                       WHEN em.type = 'saida' THEN -ABS(em.quantity)
                                       ELSE em.quantity
                                   END), 0) as stock_quantity
                            FROM estoque_movimentos em
                            INNER JOIN produtos p ON em.product_id = p.id
                            {$whereClause}
                            {$whereType}
                            GROUP BY {$groupByCols}
                            HAVING stock_quantity > 0
                            ORDER BY {$orderBy}
                        ");
                    } else {
                        // Fallback: usar estoque direto da tabela produtos
                        $joinMov = "";
                        $whereMov = "";
                        $calcEstoque = $temStockQuantity ? "{$colunaEstoque} as stock_quantity" : "0 as stock_quantity";
                        $groupBy = "";

                        $stmt = $this->db->prepare("
                            SELECT p.name,
                                   p.sku,
                                   {$calcEstoque},
                                   NULL as lote,
                                   NULL as validade,
                                   NULL as fabricacao
                            FROM produtos p
                            {$joinCategoria}
                            {$joinMov}
                            {$whereCompany}
                            {$whereType}
                            {$whereMov}
                            {$groupBy}
                            ORDER BY p.name ASC
                        ");

                        $params = [];
                        if ($temCompanyId) {
                            $params['company_id'] = $companyId;
                        }
                    }
                } else {
                    // Tabela estoque_movimentos não existe, usar estoque direto da tabela produtos
                    $stmt = $this->db->prepare("
                        SELECT p.name,
                               p.sku,
                               " . ($temStockQuantity ? "{$colunaEstoque}" : "0") . " as stock_quantity,
                               NULL as lote,
                               NULL as validade,
                               NULL as fabricacao
                        FROM produtos p
                        {$joinCategoria}
                        {$whereCompany}
                        {$whereType}
                        ORDER BY p.name ASC
                    ");

                    $params = [];
                    if ($temCompanyId) {
                        $params['company_id'] = $companyId;
                    }
                }

                if (!isset($params)) {
                    $params = [];
                }

                if (!isset($stmt)) {
                    throw new \Exception("Erro: query não foi preparada corretamente");
                }

                try {
                    $stmt->execute($params);
                    $dados = $stmt->fetchAll() ?: [];
                } catch (\PDOException $e) {
                    error_log("Erro SQL no relatório de estoque atual: " . $e->getMessage());
                    error_log("Query: " . ($stmt->queryString ?? 'N/A'));
                    error_log("Params: " . json_encode($params));
                    if (isset($groupByCols)) {
                        error_log("GROUP BY usado: {$groupByCols}");
                    }
                    throw new \Exception("Erro ao executar query: " . $e->getMessage());
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/estoque-atual', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Estoque Atual'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de estoque atual: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de movimentação de estoque
     */
    public function movimentacaoEstoque(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');
            $produtoId = $this->request->get('produto_id', '');
            $lote = $this->request->get('lote', '');
            $dados = [];

            // Buscar lista de produtos para o filtro
            $produtos = [];
            try {
                $stmtProdutos = $this->db->prepare("
                    SELECT id, name, sku
                    FROM produtos
                    WHERE company_id = :company_id AND is_active = 1
                    ORDER BY name ASC
                ");
                $stmtProdutos->execute(['company_id' => $companyId]);
                $produtos = $stmtProdutos->fetchAll() ?: [];
            } catch (Exception $e) {
                error_log("Erro ao buscar produtos para filtro: " . $e->getMessage());
            }

            // Verificar se a tabela estoque_movimentos existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'estoque_movimentos'");
            $temMovimentos = $stmtCheck->rowCount() > 0;

            if ($temMovimentos) {
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'produtos'");
                $temProdutos = $stmtCheck->rowCount() > 0;

                if ($temProdutos) {
                    // Verificar colunas da tabela estoque_movimentos
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'product_id'");
                    $temProductId = $stmtCheck->fetch() !== false;

                    // Verificar se usa item_id em vez de product_id
                    $colunaProduto = null;
                    if ($temProductId) {
                        $colunaProduto = 'product_id';
                    } else {
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'item_id'");
                        $temItemId = $stmtCheck->fetch() !== false;
                        if ($temItemId) {
                            $colunaProduto = 'item_id';
                            $temProductId = true; // Usar item_id como product_id
                        }
                    }

                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'company_id'");
                    $temCompanyId = $stmtCheck->fetch() !== false;

                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'company_id'");
                    $temMovCompanyId = $stmtCheck->fetch() !== false;

                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'created_at'");
                    $temCreatedAt = $stmtCheck->fetch() !== false;
                    $colunaData = $temCreatedAt ? 'created_at' : 'updated_at';

                    if ($colunaProduto) {
                        $joinProduto = $temProductId ? "INNER JOIN produtos p ON em.{$colunaProduto} = p.id" : "LEFT JOIN produtos p ON em.{$colunaProduto} = p.id";

                        // Construir condições WHERE
                        $whereConditions = [];
                        $params = [
                            'data_inicio' => $dataInicio,
                            'data_fim' => $dataFim
                        ];

                        if ($temMovCompanyId) {
                            $whereConditions[] = "em.company_id = :company_id";
                            $params['company_id'] = $companyId;
                        } elseif ($temCompanyId) {
                            $whereConditions[] = "p.company_id = :company_id";
                            $params['company_id'] = $companyId;
                        }

                        $whereConditions[] = "DATE(em.{$colunaData}) BETWEEN :data_inicio AND :data_fim";

                        // Filtro por produto
                        if (!empty($produtoId) && is_numeric($produtoId)) {
                            $whereConditions[] = "em.{$colunaProduto} = :produto_id";
                            $params['produto_id'] = (int) $produtoId;
                        }

                        // Filtro por lote
                        if (!empty($lote)) {
                            $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'lote'");
                            $temLote = $stmtCheck->fetch() !== false;
                            if ($temLote) {
                                $whereConditions[] = "em.lote LIKE :lote";
                                $params['lote'] = "%{$lote}%";
                            }
                        }

                        $whereClause = !empty($whereConditions) ? "WHERE " . implode(" AND ", $whereConditions) : "";

                        // Verificar se existe coluna lote
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'lote'");
                        $temLoteCol = $stmtCheck->fetch() !== false;
                        $colunaLote = $temLoteCol ? "em.lote" : "NULL as lote";

                        $stmt = $this->db->prepare("
                            SELECT
                                COALESCE(p.name, 'Produto não encontrado') as produto,
                                COALESCE(em.type, '') as tipo,
                                COALESCE(em.quantity, 0) as quantidade,
                                COALESCE(em.reason,
                                    CASE
                                        WHEN em.reference_type IS NOT NULL AND em.reference_id IS NOT NULL
                                        THEN CONCAT(em.reference_type, ' #', em.reference_id)
                                        ELSE ''
                                    END, '') as referencia,
                                {$colunaLote} as lote,
                                em.{$colunaData} as data,
                                em.reference_type,
                                em.reference_id,
                                em.origem,
                                em.origem_id
                            FROM estoque_movimentos em
                            {$joinProduto}
                            {$whereClause}
                            ORDER BY em.{$colunaData} DESC
                            LIMIT 500
                        ");

                        $stmt->execute($params);
                        $dados = $stmt->fetchAll() ?: [];
                    }
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            // Buscar nome do produto selecionado se houver
            $produtoNome = '';
            if (!empty($produtoId) && is_numeric($produtoId)) {
                try {
                    $stmtProd = $this->db->prepare("SELECT name, sku FROM produtos WHERE id = :id AND company_id = :company_id LIMIT 1");
                    $stmtProd->execute(['id' => (int) $produtoId, 'company_id' => $companyId]);
                    $produtoSelecionado = $stmtProd->fetch();
                    if ($produtoSelecionado) {
                        $produtoNome = $produtoSelecionado['name'];
                        if (!empty($produtoSelecionado['sku'])) {
                            $produtoNome .= ' (' . $produtoSelecionado['sku'] . ')';
                        }
                    }
                } catch (Exception $e) {
                    error_log("Erro ao buscar produto selecionado: " . $e->getMessage());
                }
            }

            $this->view('relatorios/movimentacao-estoque', [
                'dados' => $dados,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'produtos' => $produtos,
                'produtoNome' => $produtoNome,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Movimentação de Estoque'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de movimentação de estoque: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de produtos em falta
     */
    public function produtosZerados(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dados = [];

            // Verificar se a tabela produtos existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'produtos'");
            if ($stmtCheck->rowCount() > 0) {
                // Verificar colunas
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'company_id'");
                $temCompanyId = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'type'");
                $temType = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'stock_quantity'");
                $temStockQuantity = $stmtCheck->fetch() !== false;
                if (!$temStockQuantity) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'quantidade'");
                    $temStockQuantity = $stmtCheck->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'min_stock'");
                $temMinStock = $stmtCheck->fetch() !== false;
                $colunaMin = 'min_stock';
                if (!$temMinStock) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'estoque_minimo'");
                    $temMinStock = $stmtCheck->fetch() !== false;
                    if ($temMinStock) {
                        $colunaMin = 'estoque_minimo';
                    }
                }

                $colunaEstoque = $temStockQuantity ? 'stock_quantity' : 'quantidade';
                $whereType = $temType ? "AND p.type = 'produto'" : '';
                $whereCompany = $temCompanyId ? "WHERE p.company_id = :company_id" : 'WHERE 1=1';
                $whereFalta = $temMinStock ? "AND ({$colunaEstoque} <= 0 OR {$colunaEstoque} <= {$colunaMin})" : "AND {$colunaEstoque} <= 0";

                // Verificar se tabela categorias existe
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'categorias'");
                $temCategorias = $stmtCheck->rowCount() > 0;

                if ($temCategorias) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM categorias LIKE 'id'");
                    $temCategoriaId = $stmtCheck->fetch() !== false;
                    $joinCategoria = $temCategoriaId ? "LEFT JOIN categorias c ON p.category_id = c.id" : "";
                    $colunaCategoria = $temCategoriaId ? "c.name as category_name" : "'' as category_name";
                } else {
                    $joinCategoria = "";
                    $colunaCategoria = "'' as category_name";
                }

                $selectMinStock = $temMinStock ? "{$colunaMin}" : "0";

                $stmt = $this->db->prepare("
                    SELECT p.name,
                           p.sku,
                           {$colunaEstoque} as stock_quantity,
                           {$selectMinStock} as min_stock,
                           {$colunaCategoria}
                    FROM produtos p
                    {$joinCategoria}
                    {$whereCompany}
                    {$whereType}
                    {$whereFalta}
                    ORDER BY {$colunaEstoque} ASC
                ");

                $params = [];
                if ($temCompanyId) {
                    $params['company_id'] = $companyId;
                }

                $stmt->execute($params);
                $dados = $stmt->fetchAll() ?: [];
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/produtos-zerados', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Produtos em Falta'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de produtos em falta: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de produtos próximos a vencer (até 120 dias)
     */
    public function produtosProximosVencer(): void
    {
        error_log("=== produtosProximosVencer chamado ===");
        try {
            $companyId = $this->getCompanyId();
            if (!$companyId) {
                throw new \Exception("Company ID não encontrado na sessão");
            }

            $dados = [];

            // Verificar se a tabela estoque_movimentos existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'estoque_movimentos'");
            $temMovimentos = $stmtCheck->rowCount() > 0;

            if ($temMovimentos) {
                // Verificar colunas
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'product_id'");
                $temProductId = $stmtCheck->fetch() !== false;
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'company_id'");
                $temMovCompanyId = $stmtCheck->fetch() !== false;
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'type'");
                $temMovType = $stmtCheck->fetch() !== false;
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'quantity'");
                $temMovQuantity = $stmtCheck->fetch() !== false;
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'validade'");
                $temValidade = $stmtCheck->fetch() !== false;
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'lote'");
                $temLote = $stmtCheck->fetch() !== false;
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM estoque_movimentos LIKE 'fabricacao'");
                $temFabricacao = $stmtCheck->fetch() !== false;

                // Verificar se tabela produtos existe
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'produtos'");
                $temProdutos = $stmtCheck->rowCount() > 0;

                if ($temProdutos && $temProductId && $temValidade) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'company_id'");
                    $temCompanyId = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'type'");
                    $temType = $stmtCheck->fetch() !== false;

                    // Construir WHERE clause
                    $whereParts = [];
                    $params = [];

                    if ($temMovCompanyId) {
                        $whereParts[] = "em.company_id = :company_id";
                        $params['company_id'] = $companyId;
                    } elseif ($temCompanyId) {
                        $whereParts[] = "p.company_id = :company_id";
                        $params['company_id'] = $companyId;
                    }

                    $whereClause = !empty($whereParts) ? "WHERE " . implode(" AND ", $whereParts) : "WHERE 1=1";
                    $whereProdCompany = "";
                    $whereType = $temType ? "AND p.type = 'produto'" : "";

                    // Agrupar por product_id, lote, fabricação e validade
                    $selectCols = "p.id, p.name, p.sku";
                    $groupByCols = "em.product_id";

                    if ($temLote) {
                        $selectCols .= ", COALESCE(em.lote, '') as lote";
                        $groupByCols .= ", em.lote";
                    } else {
                        $selectCols .= ", '' as lote";
                    }

                    if ($temFabricacao) {
                        $selectCols .= ", em.fabricacao";
                        $groupByCols .= ", em.fabricacao";
                    } else {
                        $selectCols .= ", NULL as fabricacao";
                    }

                    if ($temValidade) {
                        $selectCols .= ", em.validade";
                        $groupByCols .= ", em.validade";
                    } else {
                        $selectCols .= ", NULL as validade";
                    }

                    $stmt = $this->db->prepare("
                        SELECT {$selectCols},
                               COALESCE(SUM(CASE
                                   WHEN em.type = 'entrada' THEN ABS(em.quantity)
                                   WHEN em.type = 'saida' THEN -ABS(em.quantity)
                                   ELSE em.quantity
                               END), 0) as stock_quantity,
                               DATEDIFF(em.validade, CURDATE()) as dias_para_vencer
                        FROM estoque_movimentos em
                        INNER JOIN produtos p ON em.product_id = p.id
                        {$whereClause}
                        {$whereType}
                        AND em.validade IS NOT NULL
                        AND em.validade >= CURDATE()
                        AND em.validade <= DATE_ADD(CURDATE(), INTERVAL 120 DAY)
                        GROUP BY {$groupByCols}
                        HAVING stock_quantity > 0
                        ORDER BY validade ASC, p.name ASC
                    ");

                    try {
                        $stmt->execute($params);
                        $dados = $stmt->fetchAll() ?: [];
                    } catch (\PDOException $e) {
                        error_log("Erro SQL no relatório de produtos próximos a vencer: " . $e->getMessage());
                        error_log("Query: " . ($stmt->queryString ?? 'N/A'));
                        error_log("Params: " . json_encode($params));
                        throw new \Exception("Erro ao executar query: " . $e->getMessage());
                    }
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/produtos-proximos-vencer', [
                'dados' => $dados,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Produtos Próximos a Vencer'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de produtos próximos a vencer: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de inventário
     */
    public function inventario(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dados = [];
            $valorTotal = 0;

            // Verificar se a tabela produtos existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'produtos'");
            if ($stmtCheck->rowCount() > 0) {
                // Verificar colunas
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'company_id'");
                $temCompanyId = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'type'");
                $temType = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'stock_quantity'");
                $temStockQuantity = $stmtCheck->fetch() !== false;
                if (!$temStockQuantity) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'quantidade'");
                    $temStockQuantity = $stmtCheck->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'price'");
                $temPrice = $stmtCheck->fetch() !== false;
                $colunaPreco = 'price';
                if (!$temPrice) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'preco_venda'");
                    $temPrice = $stmtCheck->fetch() !== false;
                    if ($temPrice) {
                        $colunaPreco = 'preco_venda';
                    }
                }

                $colunaEstoque = $temStockQuantity ? 'stock_quantity' : 'quantidade';
                $whereType = $temType ? "AND p.type = 'produto'" : '';
                $whereCompany = $temCompanyId ? "WHERE p.company_id = :company_id" : 'WHERE 1=1';

                // Verificar se tabela categorias existe
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'categorias'");
                $temCategorias = $stmtCheck->rowCount() > 0;

                if ($temCategorias) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM categorias LIKE 'id'");
                    $temCategoriaId = $stmtCheck->fetch() !== false;
                    $joinCategoria = $temCategoriaId ? "LEFT JOIN categorias c ON p.category_id = c.id" : "";
                    $colunaCategoria = $temCategoriaId ? "c.name as category_name" : "'' as category_name";
                } else {
                    $joinCategoria = "";
                    $colunaCategoria = "'' as category_name";
                }

                $selectPreco = $temPrice ? "{$colunaPreco}" : "0";

                $stmt = $this->db->prepare("
                    SELECT p.name,
                           p.sku,
                           {$colunaEstoque} as stock_quantity,
                           {$selectPreco} as price,
                           ({$colunaEstoque} * {$selectPreco}) as valor_total,
                           {$colunaCategoria}
                    FROM produtos p
                    {$joinCategoria}
                    {$whereCompany}
                    {$whereType}
                    ORDER BY p.name ASC
                ");

                $params = [];
                if ($temCompanyId) {
                    $params['company_id'] = $companyId;
                }

                $stmt->execute($params);
                $dados = $stmt->fetchAll() ?: [];

                // Calcular total
                if ($temPrice && $temStockQuantity) {
                    $stmt = $this->db->prepare("
                        SELECT SUM({$colunaEstoque} * {$colunaPreco}) as valor_total_inventario
                        FROM produtos
                        {$whereCompany}
                        {$whereType}
                    ");
                    $stmt->execute($params);
                    $valorTotal = (float) ($stmt->fetchColumn() ?: 0);
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/inventario', [
                'dados' => $dados,
                'valorTotal' => $valorTotal,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Inventário'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de inventário: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de valorização de estoque (preço de custo)
     */
    public function valorizacaoEstoque(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dados = [];
            $valorTotal = 0;

            // Verificar se a tabela produtos existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'produtos'");
            if ($stmtCheck->rowCount() > 0) {
                // Verificar colunas
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'company_id'");
                $temCompanyId = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'type'");
                $temType = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'stock_quantity'");
                $temStockQuantity = $stmtCheck->fetch() !== false;
                if (!$temStockQuantity) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'quantidade'");
                    $temStockQuantity = $stmtCheck->fetch() !== false;
                }

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'cost_price'");
                $temCostPrice = $stmtCheck->fetch() !== false;
                $colunaCusto = 'cost_price';
                if (!$temCostPrice) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'preco_custo'");
                    $temCostPrice = $stmtCheck->fetch() !== false;
                    if ($temCostPrice) {
                        $colunaCusto = 'preco_custo';
                    }
                }

                $colunaEstoque = $temStockQuantity ? 'stock_quantity' : 'quantidade';
                $whereType = $temType ? "AND p.type = 'produto'" : '';
                $whereCompany = $temCompanyId ? "WHERE p.company_id = :company_id" : 'WHERE 1=1';

                // Verificar se tabela categorias existe
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'categorias'");
                $temCategorias = $stmtCheck->rowCount() > 0;

                if ($temCategorias) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM categorias LIKE 'id'");
                    $temCategoriaId = $stmtCheck->fetch() !== false;
                    $joinCategoria = $temCategoriaId ? "LEFT JOIN categorias c ON p.category_id = c.id" : "";
                    $colunaCategoria = $temCategoriaId ? "c.name as category_name" : "'' as category_name";
                } else {
                    $joinCategoria = "";
                    $colunaCategoria = "'' as category_name";
                }

                $selectCusto = $temCostPrice ? "{$colunaCusto}" : "0";

                $stmt = $this->db->prepare("
                    SELECT p.name,
                           p.sku,
                           {$colunaEstoque} as stock_quantity,
                           {$selectCusto} as cost_price,
                           ({$colunaEstoque} * {$selectCusto}) as valor_total,
                           {$colunaCategoria}
                    FROM produtos p
                    {$joinCategoria}
                    {$whereCompany}
                    {$whereType}
                    ORDER BY p.name ASC
                ");

                $params = [];
                if ($temCompanyId) {
                    $params['company_id'] = $companyId;
                }

                $stmt->execute($params);
                $dados = $stmt->fetchAll() ?: [];

                // Calcular total
                if ($temCostPrice && $temStockQuantity) {
                    $stmt = $this->db->prepare("
                        SELECT SUM({$colunaEstoque} * {$colunaCusto}) as valor_total_inventario
                        FROM produtos
                        {$whereCompany}
                        {$whereType}
                    ");
                    $stmt->execute($params);
                    $valorTotal = (float) ($stmt->fetchColumn() ?: 0);
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/valorizacao-estoque', [
                'dados' => $dados,
                'valorTotal' => $valorTotal,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Valorização de Estoque'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de valorização de estoque: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de comissões por vendedor
     */
    public function comissoesVendedor(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');

            // Verificar se a coluna existe
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'vendedor_id'");
            $temVendedorId = $stmtCheck->fetch() !== false;

            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'comissao'");
            $temComissao = $stmtCheck->fetch() !== false;

            if (!$temVendedorId || !$temComissao) {
                $dados = [];
                $totalComissao = 0;
            } else {
                $stmt = $this->db->prepare("
                    SELECT
                        u.id,
                        u.name as vendedor,
                        COUNT(DISTINCT vi.venda_id) as total_vendas,
                        COUNT(vi.id) as total_itens,
                        SUM(vi.total_price) as total_vendido,
                        SUM(COALESCE(vi.comissao, 0)) as total_comissao,
                        AVG(COALESCE(vi.comissao_percentual, 0)) as media_percentual
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    LEFT JOIN users u ON vi.vendedor_id = u.id
                    WHERE vi.company_id = :company_id
                    AND vi.vendedor_id IS NOT NULL
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    AND COALESCE(vi.comissao, 0) > 0
                    GROUP BY u.id, u.name
                    ORDER BY total_comissao DESC
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $dados = $stmt->fetchAll();

                $stmt = $this->db->prepare("
                    SELECT SUM(COALESCE(vi.comissao, 0)) as total
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE vi.company_id = :company_id
                    AND vi.vendedor_id IS NOT NULL
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $totalComissao = (float) ($stmt->fetchColumn() ?: 0);
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/comissoes-vendedor', [
                'dados' => $dados,
                'totalComissao' => $totalComissao,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Comissões por Vendedor'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao gerar relatório de comissões por vendedor: " . $e->getMessage());
            $this->error('Erro ao gerar relatório');
        }
    }

    /**
     * Relatório de comissões por profissional
     */
    public function comissoesProfissional(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');
            $profissionalId = $this->request->get('profissional_id');
            // Converter para int se não estiver vazio, caso contrário null
            $profissionalId = ($profissionalId !== null && $profissionalId !== '' && $profissionalId !== '0') ? (int) $profissionalId : null;

            // Buscar lista de profissionais
            try {
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM users LIKE 'type'");
                $temCampoType = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM users LIKE 'role'");
                $temCampoRole = $stmtCheck->fetch() !== false;
            } catch (\Exception $e) {
                $temCampoType = false;
                $temCampoRole = false;
            }

            if ($temCampoType) {
                $stmt = $this->db->prepare("
                    SELECT id, name FROM users
                    WHERE company_id = :company_id
                      AND type = 'vendedor'
                      AND is_active = 1
                    ORDER BY name ASC
                ");
            } elseif ($temCampoRole) {
                $stmt = $this->db->prepare("
                    SELECT id, name FROM users
                    WHERE company_id = :company_id
                      AND role = 'vendedor'
                      AND is_active = 1
                    ORDER BY name ASC
                ");
            } else {
                $stmt = $this->db->prepare("
                    SELECT id, name FROM users
                    WHERE company_id = :company_id
                      AND is_active = 1
                    ORDER BY name ASC
                ");
            }
            $stmt->execute(['company_id' => $companyId]);
            $profissionais = $stmt->fetchAll() ?: [];

            // Verificar se a coluna existe
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'profissional_id'");
            $temProfissionalId = $stmtCheck->fetch() !== false;

            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'comissao'");
            $temComissao = $stmtCheck->fetch() !== false;

            $dados = [];
            $dadosDetalhados = [];
            $totalComissao = 0;

            if ($temProfissionalId && $temComissao) {
                // Query base
                $whereProfissional = '';
                $params = [
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ];

                if ($profissionalId) {
                    $whereProfissional = 'AND vi.profissional_id = :profissional_id';
                    $params['profissional_id'] = (int) $profissionalId;
                }

                $stmt = $this->db->prepare("
                    SELECT
                        u.id,
                        u.name as profissional,
                        COUNT(DISTINCT vi.venda_id) as total_vendas,
                        COUNT(vi.id) as total_itens,
                        SUM(vi.total_price) as total_vendido,
                        SUM(COALESCE(vi.comissao, 0)) as total_comissao,
                        AVG(COALESCE(vi.comissao_percentual, 0)) as media_percentual
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    LEFT JOIN users u ON vi.profissional_id = u.id
                    WHERE vi.company_id = :company_id
                    AND vi.profissional_id IS NOT NULL
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    AND COALESCE(vi.comissao, 0) > 0
                    {$whereProfissional}
                    GROUP BY u.id, u.name
                    ORDER BY total_comissao DESC
                ");
                $stmt->execute($params);
                $dados = $stmt->fetchAll();

                // Calcular total
                $stmt = $this->db->prepare("
                    SELECT SUM(COALESCE(vi.comissao, 0)) as total
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE vi.company_id = :company_id
                    AND vi.profissional_id IS NOT NULL
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    {$whereProfissional}
                ");
                $stmt->execute($params);
                $totalComissao = (float) ($stmt->fetchColumn() ?: 0);

                // Buscar dados detalhados (itens por venda) - sempre buscar, com ou sem filtro de profissional
                $queryDetalhado = "
                    SELECT
                        vi.profissional_id,
                        u.name as profissional_nome,
                        v.id as venda_id,
                        v.sale_number as venda_numero,
                        DATE(v.created_at) as venda_data,
                        vi.product_name,
                        vi.product_sku,
                        vi.quantity,
                        vi.unit_price,
                        vi.total_price,
                        vi.comissao,
                        vi.comissao_percentual
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    LEFT JOIN users u ON vi.profissional_id = u.id
                    WHERE vi.company_id = :company_id
                    AND vi.profissional_id IS NOT NULL
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    AND COALESCE(vi.comissao, 0) > 0
                ";

                $paramsDetalhado = [
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ];

                // Se houver filtro de profissional, adicionar WHERE
                if ($profissionalId) {
                    $queryDetalhado .= " AND vi.profissional_id = :profissional_id";
                    $paramsDetalhado['profissional_id'] = (int) $profissionalId;
                }

                $queryDetalhado .= " ORDER BY u.name ASC, v.created_at DESC, v.id DESC, vi.id ASC";

                $stmt = $this->db->prepare($queryDetalhado);
                $stmt->execute($paramsDetalhado);
                $dadosDetalhados = $stmt->fetchAll() ?: [];
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = null;
            try {
                // Tentar buscar da tabela empresas primeiro
                $stmt = $this->db->prepare("
                    SELECT * FROM empresas
                    WHERE id = :id OR company_id = :company_id
                    LIMIT 1
                ");
                $stmt->execute(['id' => $companyId, 'company_id' => $companyId]);
                $empresa = $stmt->fetch();

                // Se não encontrou, tentar companies
                if (!$empresa) {
                    $stmt = $this->db->prepare("
                        SELECT * FROM companies
                        WHERE id = :id
                        LIMIT 1
                    ");
                    $stmt->execute(['id' => $companyId]);
                    $empresa = $stmt->fetch();
                }
            } catch (\Exception $e) {
                error_log("Erro ao buscar dados da empresa: " . $e->getMessage());
            }

            $this->view('relatorios/comissoes-profissional', [
                'dados' => $dados,
                'dadosDetalhados' => $dadosDetalhados,
                'totalComissao' => $totalComissao,
                'profissionais' => $profissionais,
                'profissionalId' => $profissionalId,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Comissões por Profissional'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao gerar relatório de comissões por profissional: " . $e->getMessage());
            $this->error('Erro ao gerar relatório');
        }
    }

    /**
     * Relatório de comissões por período
     */
    public function comissoesPeriodo(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');

            // Verificar se a coluna existe
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'comissao'");
            $temComissao = $stmtCheck->fetch() !== false;

            if (!$temComissao) {
                $dados = [];
                $totalComissao = 0;
            } else {
                $stmt = $this->db->prepare("
                    SELECT
                        DATE(v.created_at) as data,
                        COUNT(DISTINCT v.id) as total_vendas,
                        COUNT(vi.id) as total_itens,
                        SUM(vi.total_price) as total_vendido,
                        SUM(COALESCE(vi.comissao, 0)) as total_comissao
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE vi.company_id = :company_id
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    AND COALESCE(vi.comissao, 0) > 0
                    GROUP BY DATE(v.created_at)
                    ORDER BY data ASC
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $dados = $stmt->fetchAll();

                $stmt = $this->db->prepare("
                    SELECT SUM(COALESCE(vi.comissao, 0)) as total
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE vi.company_id = :company_id
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $totalComissao = (float) ($stmt->fetchColumn() ?: 0);
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/comissoes-periodo', [
                'dados' => $dados,
                'totalComissao' => $totalComissao,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Comissões por Período'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao gerar relatório de comissões por período: " . $e->getMessage());
            $this->error('Erro ao gerar relatório');
        }
    }

    /**
     * Relatório de comissões por produto
     */
    public function comissoesProduto(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');

            // Verificar se a coluna existe
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'comissao'");
            $temComissao = $stmtCheck->fetch() !== false;

            if (!$temComissao) {
                $dados = [];
                $totalComissao = 0;
            } else {
                $stmt = $this->db->prepare("
                    SELECT
                        vi.product_name,
                        vi.product_sku,
                        COUNT(DISTINCT vi.venda_id) as total_vendas,
                        SUM(vi.quantity) as total_quantidade,
                        SUM(vi.total_price) as total_vendido,
                        SUM(COALESCE(vi.comissao, 0)) as total_comissao,
                        AVG(COALESCE(vi.comissao_percentual, 0)) as media_percentual
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE vi.company_id = :company_id
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    AND COALESCE(vi.comissao, 0) > 0
                    GROUP BY vi.product_name, vi.product_sku
                    ORDER BY total_comissao DESC
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $dados = $stmt->fetchAll();

                $stmt = $this->db->prepare("
                    SELECT SUM(COALESCE(vi.comissao, 0)) as total
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE vi.company_id = :company_id
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $totalComissao = (float) ($stmt->fetchColumn() ?: 0);
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/comissoes-produto', [
                'dados' => $dados,
                'totalComissao' => $totalComissao,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Relatório de Comissões por Produto'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao gerar relatório de comissões por produto: " . $e->getMessage());
            $this->error('Erro ao gerar relatório');
        }
    }

    /**
     * Resumo de comissões
     */
    public function comissoesResumo(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');

            // Verificar se as colunas existem
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'comissao'");
            $temComissao = $stmtCheck->fetch() !== false;

            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'vendedor_id'");
            $temVendedorId = $stmtCheck->fetch() !== false;

            $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'profissional_id'");
            $temProfissionalId = $stmtCheck->fetch() !== false;

            $resumo = [
                'total_comissao' => 0,
                'total_vendas' => 0,
                'total_itens' => 0,
                'total_valor_vendido' => 0,
                'comissoes_por_vendedor' => 0,
                'comissoes_por_profissional' => 0,
                'media_percentual' => 0
            ];

            if ($temComissao) {
                $stmt = $this->db->prepare("
                    SELECT
                        COUNT(DISTINCT v.id) as total_vendas,
                        COUNT(vi.id) as total_itens,
                        SUM(vi.total_price) as total_valor_vendido,
                        SUM(COALESCE(vi.comissao, 0)) as total_comissao,
                        AVG(COALESCE(vi.comissao_percentual, 0)) as media_percentual
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    WHERE vi.company_id = :company_id
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    AND COALESCE(vi.comissao, 0) > 0
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);
                $resultado = $stmt->fetch();

                if ($resultado) {
                    $resumo['total_vendas'] = (int) $resultado['total_vendas'];
                    $resumo['total_itens'] = (int) $resultado['total_itens'];
                    $resumo['total_valor_vendido'] = (float) ($resultado['total_valor_vendido'] ?: 0);
                    $resumo['total_comissao'] = (float) ($resultado['total_comissao'] ?: 0);
                    $resumo['media_percentual'] = (float) ($resultado['media_percentual'] ?: 0);
                }

                if ($temVendedorId) {
                    $stmt = $this->db->prepare("
                        SELECT COUNT(DISTINCT vi.vendedor_id) as total
                        FROM vendas_itens vi
                        INNER JOIN vendas v ON vi.venda_id = v.id
                        WHERE vi.company_id = :company_id
                        AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                        AND vi.vendedor_id IS NOT NULL
                        AND COALESCE(vi.comissao, 0) > 0
                    ");
                    $stmt->execute([
                        'company_id' => $companyId,
                        'data_inicio' => $dataInicio,
                        'data_fim' => $dataFim
                    ]);
                    $resumo['comissoes_por_vendedor'] = (int) ($stmt->fetchColumn() ?: 0);
                }

                if ($temProfissionalId) {
                    $stmt = $this->db->prepare("
                        SELECT COUNT(DISTINCT vi.profissional_id) as total
                        FROM vendas_itens vi
                        INNER JOIN vendas v ON vi.venda_id = v.id
                        WHERE vi.company_id = :company_id
                        AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                        AND vi.profissional_id IS NOT NULL
                        AND COALESCE(vi.comissao, 0) > 0
                    ");
                    $stmt->execute([
                        'company_id' => $companyId,
                        'data_inicio' => $dataInicio,
                        'data_fim' => $dataFim
                    ]);
                    $resumo['comissoes_por_profissional'] = (int) ($stmt->fetchColumn() ?: 0);
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/comissoes-resumo', [
                'resumo' => $resumo,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Resumo de Comissões'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao gerar resumo de comissões: " . $e->getMessage());
            $this->error('Erro ao gerar relatório');
        }
    }

    /**
     * Relatório de Balanço Patrimonial
     */
    public function balanco(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $data = $this->request->get('data') ?: date('Y-m-d');
            $ano = date('Y', strtotime($data));

            // ATIVO
            $ativo = [
                'contas_receber' => 0,
                'estoque' => 0,
                'circulante' => 0,
                'nao_circulante' => 0,
                'total' => 0
            ];

            // Ativo Circulante - Contas a Receber
            try {
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'contas_receber'");
                if ($stmtCheck->rowCount() > 0) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'amount'");
                    $temAmount = $stmtCheck->fetch() !== false;
                    if (!$temAmount) {
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'valor'");
                        $temAmount = $stmtCheck->fetch() !== false;
                    }
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_receber LIKE 'status'");
                    $temStatus = $stmtCheck->fetch() !== false;

                    if ($temAmount) {
                        $colunaValor = $temAmount ? 'amount' : 'valor';
                        $whereStatus = $temStatus ? "AND status != 'pago'" : '';
                        $whereCompany = "WHERE company_id = :company_id";

                        $stmt = $this->db->prepare("
                            SELECT SUM({$colunaValor}) as total
                            FROM contas_receber
                            {$whereCompany}
                            {$whereStatus}
                        ");
                        $stmt->execute(['company_id' => $companyId]);
                        $ativo['contas_receber'] = (float) ($stmt->fetchColumn() ?: 0);
                        $ativo['circulante'] += $ativo['contas_receber'];
                    }
                }
            } catch (\Exception $e) {
                error_log("Erro ao buscar contas a receber no balanço: " . $e->getMessage());
            }

            // Ativo Circulante - Estoque
            try {
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'produtos'");
                if ($stmtCheck->rowCount() > 0) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'stock_quantity'");
                    $temStock = $stmtCheck->fetch() !== false;
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'cost_price'");
                    $temCostPrice = $stmtCheck->fetch() !== false;
                    if (!$temCostPrice) {
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM produtos LIKE 'preco_custo'");
                        $temCostPrice = $stmtCheck->fetch() !== false;
                    }

                    if ($temStock && $temCostPrice) {
                        $colunaCusto = $temCostPrice ? 'cost_price' : 'preco_custo';
                        $stmt = $this->db->prepare("
                            SELECT SUM(stock_quantity * {$colunaCusto}) as total
                            FROM produtos
                            WHERE company_id = :company_id
                            AND type = 'produto'
                        ");
                        $stmt->execute(['company_id' => $companyId]);
                        $ativo['estoque'] = (float) ($stmt->fetchColumn() ?: 0);
                        $ativo['circulante'] += $ativo['estoque'];
                    }
                }
            } catch (\Exception $e) {
                error_log("Erro ao buscar estoque no balanço: " . $e->getMessage());
            }

            $ativo['total'] = $ativo['circulante'] + $ativo['nao_circulante'];

            // PASSIVO
            $passivo = [
                'circulante' => 0,
                'nao_circulante' => 0,
                'total' => 0
            ];

            // Passivo Circulante - Contas a Pagar
            try {
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'contas_pagar'");
                if ($stmtCheck->rowCount() > 0) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'amount'");
                    $temAmount = $stmtCheck->fetch() !== false;
                    if (!$temAmount) {
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'valor'");
                        $temAmount = $stmtCheck->fetch() !== false;
                    }
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'status'");
                    $temStatus = $stmtCheck->fetch() !== false;

                    if ($temAmount) {
                        $colunaValor = $temAmount ? 'amount' : 'valor';
                        $whereStatus = $temStatus ? "AND status != 'pago'" : '';
                        $whereCompany = "WHERE company_id = :company_id";

                        $stmt = $this->db->prepare("
                            SELECT SUM({$colunaValor}) as total
                            FROM contas_pagar
                            {$whereCompany}
                            {$whereStatus}
                        ");
                        $stmt->execute(['company_id' => $companyId]);
                        $passivo['circulante'] += (float) ($stmt->fetchColumn() ?: 0);
                    }
                }
            } catch (\Exception $e) {
                error_log("Erro ao buscar contas a pagar no balanço: " . $e->getMessage());
            }

            $passivo['total'] = $passivo['circulante'] + $passivo['nao_circulante'];

            // PATRIMÔNIO LÍQUIDO
            // Calcular receitas e despesas do ano
            $receitas = 0;
            $despesas = 0;

            try {
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas LIKE 'status'");
                $temStatus = $stmtCheck->fetch() !== false;
                $whereStatus = $temStatus ? "AND (status = 'concluida' OR status = 'concluído' OR status = 'faturado' OR status = 'faturada')" : '';

                $stmt = $this->db->prepare("
                    SELECT SUM(total) as total
                    FROM vendas
                    WHERE company_id = :company_id
                    {$whereStatus}
                    AND YEAR(created_at) = :ano
                ");
                $stmt->execute(['company_id' => $companyId, 'ano' => $ano]);
                $receitas = (float) ($stmt->fetchColumn() ?: 0);
            } catch (\Exception $e) {
                error_log("Erro ao buscar receitas no balanço: " . $e->getMessage());
            }

            try {
                $stmtCheck = $this->db->query("SHOW TABLES LIKE 'contas_pagar'");
                if ($stmtCheck->rowCount() > 0) {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'amount'");
                    $temAmount = $stmtCheck->fetch() !== false;
                    if (!$temAmount) {
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'valor'");
                        $temAmount = $stmtCheck->fetch() !== false;
                    }

                    if ($temAmount) {
                        $colunaValor = $temAmount ? 'amount' : 'valor';
                        $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'due_date'");
                        $temDueDate = $stmtCheck->fetch() !== false;
                        if (!$temDueDate) {
                            $stmtCheck = $this->db->query("SHOW COLUMNS FROM contas_pagar LIKE 'data_vencimento'");
                            $temDueDate = $stmtCheck->fetch() !== false;
                        }

                        $colunaData = $temDueDate ? 'due_date' : 'data_vencimento';
                        $whereCompany = "WHERE company_id = :company_id";

                        $stmt = $this->db->prepare("
                            SELECT SUM({$colunaValor}) as total
                            FROM contas_pagar
                            {$whereCompany}
                            AND YEAR({$colunaData}) = :ano
                        ");
                        $stmt->execute(['company_id' => $companyId, 'ano' => $ano]);
                        $despesas = (float) ($stmt->fetchColumn() ?: 0);
                    }
                }
            } catch (\Exception $e) {
                error_log("Erro ao buscar despesas no balanço: " . $e->getMessage());
            }

            $resultadoExercicio = $receitas - $despesas;
            $patrimonioLiquido = $resultadoExercicio;

            // Total Passivo + Patrimônio Líquido
            $totalPassivoPL = $passivo['total'] + $patrimonioLiquido;

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/balanco', [
                'ativo' => $ativo,
                'passivo' => $passivo,
                'patrimonioLiquido' => $patrimonioLiquido,
                'resultadoExercicio' => $resultadoExercicio,
                'receitas' => $receitas,
                'despesas' => $despesas,
                'totalPassivoPL' => $totalPassivoPL,
                'data' => $data,
                'ano' => $ano,
                'empresa' => $empresa,
                'pageTitle' => 'Balanço Patrimonial'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar balanço patrimonial: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Relatório de Apuração de Impostos
     */
    public function apuracaoImpostos(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $dataInicio = $this->request->get('data_inicio') ?: date('Y-m-01');
            $dataFim = $this->request->get('data_fim') ?: date('Y-m-t');

            $dados = [];
            $totais = [
                'base_icms' => 0,
                'valor_icms' => 0,
                'base_pis' => 0,
                'valor_pis' => 0,
                'base_cofins' => 0,
                'valor_cofins' => 0,
                'valor_ipi' => 0,
                'total_vendas' => 0
            ];

            // Verificar se a tabela vendas_itens existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'vendas_itens'");
            if ($stmtCheck->rowCount() > 0) {
                // Verificar quais colunas de impostos existem
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'valor_icms'");
                $temIcms = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'valor_pis'");
                $temPis = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'valor_cofins'");
                $temCofins = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'valor_ipi'");
                $temIpi = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'base_calculo_icms'");
                $temBaseIcms = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'base_calculo_pis'");
                $temBasePis = $stmtCheck->fetch() !== false;

                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'base_calculo_cofins'");
                $temBaseCofins = $stmtCheck->fetch() !== false;

                // Verificar se vendas_itens tem company_id
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM vendas_itens LIKE 'company_id'");
                $temCompanyId = $stmtCheck->fetch() !== false;

                // Construir SELECT dinamicamente
                $selectFields = [
                    'DATE(v.created_at) as data',
                    'COUNT(DISTINCT v.id) as total_vendas',
                    'SUM(v.total) as total_faturamento'
                ];

                if ($temBaseIcms) {
                    $selectFields[] = 'SUM(COALESCE(vi.base_calculo_icms, 0)) as base_icms';
                } else {
                    $selectFields[] = '0 as base_icms';
                }

                if ($temIcms) {
                    $selectFields[] = 'SUM(COALESCE(vi.valor_icms, 0)) as valor_icms';
                } else {
                    $selectFields[] = '0 as valor_icms';
                }

                if ($temBasePis) {
                    $selectFields[] = 'SUM(COALESCE(vi.base_calculo_pis, 0)) as base_pis';
                } else {
                    $selectFields[] = '0 as base_pis';
                }

                if ($temPis) {
                    $selectFields[] = 'SUM(COALESCE(vi.valor_pis, 0)) as valor_pis';
                } else {
                    $selectFields[] = '0 as valor_pis';
                }

                if ($temBaseCofins) {
                    $selectFields[] = 'SUM(COALESCE(vi.base_calculo_cofins, 0)) as base_cofins';
                } else {
                    $selectFields[] = '0 as base_cofins';
                }

                if ($temCofins) {
                    $selectFields[] = 'SUM(COALESCE(vi.valor_cofins, 0)) as valor_cofins';
                } else {
                    $selectFields[] = '0 as valor_cofins';
                }

                if ($temIpi) {
                    $selectFields[] = 'SUM(COALESCE(vi.valor_ipi, 0)) as valor_ipi';
                } else {
                    $selectFields[] = '0 as valor_ipi';
                }

                $whereCompany = $temCompanyId
                    ? "WHERE vi.company_id = :company_id"
                    : "WHERE v.company_id = :company_id";

                $query = "
                    SELECT " . implode(', ', $selectFields) . "
                    FROM vendas_itens vi
                    INNER JOIN vendas v ON vi.venda_id = v.id
                    {$whereCompany}
                    AND DATE(v.created_at) BETWEEN :data_inicio AND :data_fim
                    GROUP BY DATE(v.created_at)
                    ORDER BY data ASC
                ";

                $stmt = $this->db->prepare($query);
                $stmt->execute([
                    'company_id' => $companyId,
                    'data_inicio' => $dataInicio,
                    'data_fim' => $dataFim
                ]);

                $dados = $stmt->fetchAll() ?: [];

                // Calcular totais
                foreach ($dados as $item) {
                    $totais['base_icms'] += (float) ($item['base_icms'] ?? 0);
                    $totais['valor_icms'] += (float) ($item['valor_icms'] ?? 0);
                    $totais['base_pis'] += (float) ($item['base_pis'] ?? 0);
                    $totais['valor_pis'] += (float) ($item['valor_pis'] ?? 0);
                    $totais['base_cofins'] += (float) ($item['base_cofins'] ?? 0);
                    $totais['valor_cofins'] += (float) ($item['valor_cofins'] ?? 0);
                    $totais['valor_ipi'] += (float) ($item['valor_ipi'] ?? 0);
                    $totais['total_vendas'] += (int) ($item['total_vendas'] ?? 0);
                }
            }

            // Buscar dados da empresa para o cabeçalho de impressão
            $empresa = $this->buscarDadosEmpresa($companyId);

            $this->view('relatorios/apuracao-impostos', [
                'dados' => $dados,
                'totais' => $totais,
                'dataInicio' => $dataInicio,
                'dataFim' => $dataFim,
                'empresa' => $empresa,
                'pageTitle' => 'Apuração de Impostos'
            ]);

        } catch (\Exception $e) {
            error_log("Erro ao gerar relatório de apuração de impostos: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao gerar relatório: ' . $e->getMessage());
        }
    }

    /**
     * Buscar dados da empresa para cabeçalhos de impressão
     */
    private function buscarDadosEmpresa(int $companyId): ?array
    {
        try {
            // Tentar buscar da tabela empresas primeiro
            $stmt = $this->db->prepare("
                SELECT * FROM empresas
                WHERE id = :id OR company_id = :company_id
                LIMIT 1
            ");
            $stmt->execute(['id' => $companyId, 'company_id' => $companyId]);
            $empresa = $stmt->fetch();

            // Se não encontrou, tentar companies
            if (!$empresa) {
                $stmt = $this->db->prepare("
                    SELECT * FROM companies
                    WHERE id = :id
                    LIMIT 1
                ");
                $stmt->execute(['id' => $companyId]);
                $empresa = $stmt->fetch();
            }

            return $empresa ?: null;
        } catch (\Exception $e) {
            error_log("Erro ao buscar dados da empresa: " . $e->getMessage());
            return null;
        }
    }
}
