<?php

declare(strict_types=1);

namespace App\Controllers;

use Exception;

/**
 * Controller de Pessoas (Clientes, Fornecedores, Funcionários)
 */
class PessoasController extends BaseController
{
    /**
     * Lista clientes, fornecedores e funcionários separados por abas
     */
    public function index(): void
    {
        try {
            // Verificar permissão de visualização ANTES de qualquer processamento
            if (!$this->canView('pessoas')) {
                $this->response->forbidden('Você não tem permissão para visualizar pessoas.');
                return;
            }

            $companyId = $this->getCompanyId();
            $perPage = 40; // Itens por página

            // Verificar permissões
            $canCreate = $this->canCreate('pessoas');
            $canEdit = $this->canEdit('pessoas');
            $canDelete = $this->canDelete('pessoas');

            // Páginas específicas para cada tipo (ou usar página geral)
            $pageClientes = max(1, (int) ($this->request->get('page_clientes') ?? $this->request->get('page') ?? 1));
            $pageFornecedores = max(1, (int) ($this->request->get('page_fornecedores') ?? $this->request->get('page') ?? 1));
            $pageTransportadoras = max(1, (int) ($this->request->get('page_transportadoras') ?? $this->request->get('page') ?? 1));

            // Buscar clientes com paginação
            $clientesData = $this->getPessoasByTypePaginated($companyId, 'cliente', $pageClientes, $perPage);

            // Buscar fornecedores com paginação
            $fornecedoresData = $this->getPessoasByTypePaginated($companyId, 'fornecedor', $pageFornecedores, $perPage);

            // Buscar transportadoras com paginação
            $transportadorasData = $this->getPessoasByTypePaginated($companyId, 'transportadora', $pageTransportadoras, $perPage);

            $this->view('pessoas/index', [
                'clientes' => $clientesData['data'],
                'clientesTotal' => $clientesData['total'],
                'clientesPage' => $clientesData['page'],
                'clientesPerPage' => $clientesData['perPage'],
                'clientesTotalPages' => $clientesData['totalPages'],
                'fornecedores' => $fornecedoresData['data'],
                'fornecedoresTotal' => $fornecedoresData['total'],
                'fornecedoresPage' => $fornecedoresData['page'],
                'fornecedoresPerPage' => $fornecedoresData['perPage'],
                'fornecedoresTotalPages' => $fornecedoresData['totalPages'],
                'transportadoras' => $transportadorasData['data'],
                'transportadorasTotal' => $transportadorasData['total'],
                'transportadorasPage' => $transportadorasData['page'],
                'transportadorasPerPage' => $transportadorasData['perPage'],
                'transportadorasTotalPages' => $transportadorasData['totalPages'],
                'canCreate' => $canCreate,
                'canEdit' => $canEdit,
                'canDelete' => $canDelete,
                'pageTitle' => 'Pessoas',
                'activeMenu' => 'pessoas'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao listar pessoas: " . $e->getMessage());
            $this->error('Erro ao carregar pessoas');
        }
    }

    /**
     * Busca pessoas por tipo (cliente, fornecedor, transportadora) com paginação
     */
    private function getPessoasByTypePaginated(int $companyId, string $type, int $page = 1, int $perPage = 20): array
    {
        try {
            $campo = 'tipo_' . $type; // tipo_cliente, tipo_fornecedor, tipo_transportadora
            $offset = ($page - 1) * $perPage;

            // Contar total de registros
            $stmtCount = $this->db->prepare("
                SELECT COUNT(DISTINCT p.id) as total
                FROM pessoas p
                WHERE p.company_id = :company_id
                AND p.{$campo} = 1
            ");
            $stmtCount->execute([
                'company_id' => $companyId
            ]);
            $total = (int) $stmtCount->fetch()['total'];
            $totalPages = max(1, (int) ceil($total / $perPage));

            // Buscar dados paginados
            $stmt = $this->db->prepare("
                SELECT p.*,
                    GROUP_CONCAT(g.name SEPARATOR ', ') as grupos
                FROM pessoas p
                LEFT JOIN pessoa_grupo pg ON p.id = pg.pessoa_id
                LEFT JOIN grupos g ON pg.grupo_id = g.id
                WHERE p.company_id = :company_id
                AND p.{$campo} = 1
                GROUP BY p.id
                ORDER BY p.name ASC
                LIMIT :limit OFFSET :offset
            ");
            $stmt->bindValue(':company_id', $companyId, \PDO::PARAM_INT);
            $stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
            $stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
            $stmt->execute();
            $data = $stmt->fetchAll();

            return [
                'data' => $data,
                'total' => $total,
                'page' => $page,
                'perPage' => $perPage,
                'totalPages' => $totalPages
            ];
        } catch (Exception $e) {
            error_log("Erro ao buscar pessoas do tipo {$type}: " . $e->getMessage());
            return [
                'data' => [],
                'total' => 0,
                'page' => 1,
                'perPage' => $perPage,
                'totalPages' => 1
            ];
        }
    }

    /**
     * Busca pessoas por tipo (cliente, fornecedor, transportadora) - método legado
     */
    private function getPessoasByType(int $companyId, string $type): array
    {
        $result = $this->getPessoasByTypePaginated($companyId, $type, 1, 1000);
        return $result['data'];
    }

    /**
     * Exibe formulário de criação
     */
    public function create(): void
    {
        $companyId = $this->getCompanyId();
        $grupos = $this->getGruposPessoas($companyId);
        $subgrupos = $this->getSubgruposPessoas($companyId);
        $tabelasPreco = $this->getTabelasPreco($companyId);
        $todasEmpresas = $this->getTodasEmpresas();
        $vendedores = $this->getVendedores($companyId);
        $areas = $this->getAreas($companyId);

        $this->view('pessoas/create', [
            'grupos' => $grupos,
            'subgrupos' => $subgrupos,
            'tabelasPreco' => $tabelasPreco,
            'pessoaVeiculos' => [],
            'todasEmpresas' => $todasEmpresas,
            'empresasVinculadas' => [],
            'vendedores' => $vendedores,
            'areas' => $areas,
            'pageTitle' => 'Nova Pessoa'
        ]);
    }

    /**
     * Salva nova pessoa
     */
    public function store(): void
    {
        $companyId = $this->getCompanyId();

        if (!$companyId) {
            $companyId = 1;
        }

        $personType = $this->request->post('person_type');
        $name = $this->request->post('name_pf') ?: $this->request->post('name_pj');
        $document = $this->request->post('document_pf') ?: $this->request->post('document_pj');

        $data = [
            'company_id' => $companyId,
            'tipo_cliente' => $this->request->post('tipo_cliente') ? 1 : 0,
            'tipo_fornecedor' => $this->request->post('tipo_fornecedor') ? 1 : 0,
            'tipo_transportadora' => $this->request->post('tipo_transportadora') ? 1 : 0,
            'person_type' => $personType,
            'name' => $name,
            'trade_name' => $this->request->post('trade_name'),
            'document' => $document,
            'rg_ie' => $this->request->post('rg_ie'),
            'inscricao_municipal' => $this->request->post('inscricao_municipal'),
            'inscricao_suframa' => $this->request->post('inscricao_suframa'),
            'passaporte' => $this->request->post('passaporte'),
            'cnh' => $this->request->post('cnh'),
            'email' => $this->request->post('email'),
            'phone' => $this->request->post('phone'),
            'mobile' => $this->request->post('mobile'),
            'website' => $this->request->post('website'),
            'whatsapp' => $this->request->post('whatsapp'),
            'address' => $this->request->post('address'),
            'numero' => $this->request->post('numero'),
            'complemento' => $this->request->post('complemento'),
            'bairro' => $this->request->post('bairro'),
            'city' => $this->request->post('city'),
            'state' => $this->request->post('state'),
            'zip_code' => $this->request->post('zip_code'),
            'notes' => $this->request->post('notes'),
            'credit_limit' => $this->request->post('credit_limit') ?: 0.00,
            'payment_terms' => $this->request->post('payment_terms') ?: 30,
            'tabela_preco_id' => $this->request->post('tabela_preco_id') ?: null,
            'send_email' => $this->request->post('send_email') ? 1 : 0,
            'send_sms' => $this->request->post('send_sms') ? 1 : 0,
            'is_vip' => $this->request->post('is_vip') ? 1 : 0,
            'is_active' => $this->request->post('is_active') ? 1 : 0,
            'grupo_id' => $this->request->post('grupo_id') ?: null,
            'subgrupo_id' => $this->request->post('subgrupo_id') ?: null,
            'vendedor_id' => $this->request->post('vendedor_id') ?: null,
            'vendedor_auxiliar_id' => $this->request->post('vendedor_auxiliar_id') ?: null,
            'area_comercial_id' => $this->request->post('area_comercial_id') ?: null,
        ];

        // Verificar se colunas de licenças existem
        $camposLicencas = ['data_anvisa', 'data_conselho_farmacia', 'data_vigilancia_sanitaria', 'data_alvara_localizacao'];
        $camposLicencasExistentes = [];
        foreach ($camposLicencas as $campo) {
            try {
                $stmtCheck = $this->db->query("SHOW COLUMNS FROM pessoas LIKE '{$campo}'");
                if ($stmtCheck->rowCount() > 0) {
                    $camposLicencasExistentes[] = $campo;
                    $valor = $this->request->post($campo);
                    $data[$campo] = !empty($valor) ? $valor : null;
                }
            } catch (Exception $e) {
                // Campo não existe, ignorar
            }
        }

        // Validação customizada: pelo menos um tipo deve ser marcado
        if (!$data['tipo_cliente'] && !$data['tipo_fornecedor'] && !$data['tipo_transportadora']) {
            $this->error('Selecione pelo menos um tipo (Cliente, Fornecedor ou Transportadora)');
            return;
        }

        $errors = $this->validate([
            'person_type' => 'required',
        ]);

        // Validação customizada para nome
        if (empty($name) || strlen($name) < 3) {
            $errors['name'] = 'Nome é obrigatório e deve ter pelo menos 3 caracteres';
        }

        if (!empty($errors)) {
            $this->error('Dados inválidos', $errors);
            return;
        }

        try {
            if (!$this->db) {
                $this->error('Erro de conexão com banco de dados');
                return;
            }

            $this->db->beginTransaction();

            $colunasLicencas = '';
            $valoresLicencas = '';
            if (!empty($camposLicencasExistentes)) {
                $colunasLicencas = ', ' . implode(', ', $camposLicencasExistentes);
                $valoresLicencas = ', :' . implode(', :', $camposLicencasExistentes);
            }

            $stmt = $this->db->prepare("
                INSERT INTO pessoas (
                    company_id, tipo_cliente, tipo_fornecedor, tipo_transportadora, person_type, name, trade_name, document, rg_ie,
                    inscricao_municipal, inscricao_suframa, passaporte, cnh,
                    email, phone, mobile, website, whatsapp,
                    address, numero, complemento, bairro, city, state, zip_code,
                    notes, credit_limit, payment_terms, tabela_preco_id, send_email, send_sms, is_vip, is_active, grupo_id, subgrupo_id, vendedor_id, vendedor_auxiliar_id, area_comercial_id{$colunasLicencas}
                ) VALUES (
                    :company_id, :tipo_cliente, :tipo_fornecedor, :tipo_transportadora, :person_type, :name, :trade_name, :document, :rg_ie,
                    :inscricao_municipal, :inscricao_suframa, :passaporte, :cnh,
                    :email, :phone, :mobile, :website, :whatsapp,
                    :address, :numero, :complemento, :bairro, :city, :state, :zip_code,
                    :notes, :credit_limit, :payment_terms, :tabela_preco_id, :send_email, :send_sms, :is_vip, :is_active, :grupo_id, :subgrupo_id, :vendedor_id, :vendedor_auxiliar_id, :area_comercial_id{$valoresLicencas}
                )
            ");

            $stmt->execute($data);
            $pessoaId = (int) $this->db->lastInsertId();

            // Associa grupos
            $grupos = $this->request->post('grupos', []);
            if (!empty($grupos)) {
                $this->associateGroups($pessoaId, $grupos);
            }

            $veiculosPayload = $this->parseVeiculosPayload($this->request->post('veiculos_data'));
            $this->salvarVeiculos($pessoaId, $veiculosPayload);

            $contatosPayload = $this->parseContatosPayload($this->request->post('contatos_data'));
            $this->salvarContatos($pessoaId, $contatosPayload);

            // Salvar empresas vinculadas
            $empresasVinculadas = json_decode($this->request->post('empresas_vinculadas', '[]'), true);
            if (is_array($empresasVinculadas)) {
                $this->salvarEmpresasVinculadas($pessoaId, $empresasVinculadas);
            }

            $this->db->commit();

            $this->logActivity('create', 'pessoas', $pessoaId, $data);

            $this->success('Pessoa cadastrada com sucesso', [
                'id' => $pessoaId,
                'redirect' => '/pessoas'
            ]);

        } catch (Exception $e) {
            if ($this->db) {
                $this->db->rollBack();
            }
            error_log("Erro ao criar pessoa: " . $e->getMessage());
            $this->error('Erro ao cadastrar pessoa');
        }
    }

    /**
     * Exibe detalhes de uma pessoa (ficha)
     */
    public function show(): void
    {
        try {
            $id = (int) $this->request->get('id');
            $pessoa = $this->getPessoa($id);

            if (!$pessoa) {
                $this->response->notFound('Pessoa não encontrada');
                return;
            }

            // Busca grupos associados
            $stmt = $this->db->prepare("
                SELECT g.* FROM grupos g
                INNER JOIN pessoa_grupo pg ON g.id = pg.grupo_id
                WHERE pg.pessoa_id = :pessoa_id
            ");
            $stmt->execute(['pessoa_id' => $id]);
            $grupos = $stmt->fetchAll();

            $this->view('pessoas/show', [
                'pessoa' => $pessoa,
                'grupos' => $grupos,
                'pageTitle' => 'Ficha - ' . $pessoa['name'],
                'activeMenu' => 'pessoas'
            ]);

        } catch (\Throwable $e) {
            error_log("Erro ao exibir ficha: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao carregar ficha: ' . $e->getMessage());
        }
    }

    /**
     * Exibe formulário de edição
     */
    public function edit(): void
    {
        try {
            $id = (int) $this->request->get('id');

            if ($id <= 0) {
                $this->response->notFound('ID inválido');
                return;
            }

            $pessoa = $this->getPessoa($id);

            if (!$pessoa) {
                $this->response->notFound('Pessoa não encontrada');
                return;
            }

            $companyId = $this->getCompanyId();

            // Buscar grupos e subgrupos com tratamento de erro
            $grupos = [];
            $subgrupos = [];
            try {
                $grupos = $this->getGruposPessoas($companyId);
            } catch (Exception $e) {
                error_log("Erro ao buscar grupos: " . $e->getMessage());
                $grupos = [];
            }

            try {
                $subgrupos = $this->getSubgruposPessoas($companyId);
            } catch (Exception $e) {
                error_log("Erro ao buscar subgrupos: " . $e->getMessage());
                $subgrupos = [];
            }

            // Buscar tabelas de preço
            $tabelasPreco = [];
            try {
                $tabelasPreco = $this->getTabelasPreco($companyId);
            } catch (Exception $e) {
                error_log("Erro ao buscar tabelas de preço: " . $e->getMessage());
                $tabelasPreco = [];
            }

            // Buscar veículos com tratamento de erro
            $pessoaVeiculos = [];
            $pessoaContatos = [];
            try {
                $pessoaId = (int) ($pessoa['id'] ?? 0);
                if ($pessoaId > 0) {
                    $pessoaVeiculos = $this->getPessoaVeiculos($pessoaId);
                    $pessoaContatos = $this->getPessoaContatos($pessoaId);
                }
            } catch (Exception $e) {
                error_log("Erro ao buscar veículos: " . $e->getMessage());
                $pessoaVeiculos = [];
                $pessoaContatos = [];
            }

            // Buscar empresas vinculadas
            $empresasVinculadas = [];
            try {
                $pessoaId = (int) ($pessoa['id'] ?? 0);
                if ($pessoaId > 0) {
                    $empresasVinculadas = $this->getEmpresasVinculadas($pessoaId);
                }
            } catch (Exception $e) {
                error_log("Erro ao buscar empresas vinculadas: " . $e->getMessage());
                $empresasVinculadas = [];
            }

            // Buscar todas as empresas
            $todasEmpresas = $this->getTodasEmpresas();

            // Buscar vendedores
            $vendedores = $this->getVendedores($companyId);

            // Buscar áreas comerciais
            $areas = $this->getAreas($companyId);

            $this->view('pessoas/edit', [
                'pessoa' => $pessoa,
                'grupos' => $grupos,
                'subgrupos' => $subgrupos,
                'tabelasPreco' => $tabelasPreco,
                'pessoaVeiculos' => $pessoaVeiculos,
                'pessoaContatos' => $pessoaContatos ?? [],
                'todasEmpresas' => $todasEmpresas,
                'empresasVinculadas' => $empresasVinculadas,
                'vendedores' => $vendedores,
                'areas' => $areas,
                'pageTitle' => 'Editar ' . ($pessoa['name'] ?? 'Pessoa')
            ]);

        } catch (Exception $e) {
            error_log("Erro ao exibir formulário de edição: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao carregar formulário: ' . $e->getMessage());
        }
    }

    /**
     * Atualiza uma pessoa
     */
    public function update(): void
    {
        try {
            $id = (int) $this->request->post('id');
            $pessoa = $this->getPessoa($id);

            if (!$pessoa) {
                $this->error('Pessoa não encontrada');
                return;
            }

            $personType = $this->request->post('person_type');
            $name = $this->request->post('name_pf') ?: $this->request->post('name_pj');
            $document = $this->request->post('document_pf') ?: $this->request->post('document_pj');

            $data = [
                'tipo_cliente' => $this->request->post('tipo_cliente') ? 1 : 0,
                'tipo_fornecedor' => $this->request->post('tipo_fornecedor') ? 1 : 0,
                'tipo_transportadora' => $this->request->post('tipo_transportadora') ? 1 : 0,
                'person_type' => $personType,
                'name' => $name,
                'trade_name' => $this->request->post('trade_name'),
                'document' => $document,
                'rg_ie' => $this->request->post('rg_ie'),
                'inscricao_municipal' => $this->request->post('inscricao_municipal'),
                'inscricao_suframa' => $this->request->post('inscricao_suframa'),
                'passaporte' => $this->request->post('passaporte'),
                'cnh' => $this->request->post('cnh'),
                'email' => $this->request->post('email'),
                'phone' => $this->request->post('phone'),
                'mobile' => $this->request->post('mobile'),
                'website' => $this->request->post('website'),
                'whatsapp' => $this->request->post('whatsapp'),
                'address' => $this->request->post('address'),
                'numero' => $this->request->post('numero'),
                'complemento' => $this->request->post('complemento'),
                'bairro' => $this->request->post('bairro'),
                'city' => $this->request->post('city'),
                'state' => $this->request->post('state'),
                'zip_code' => $this->request->post('zip_code'),
                'notes' => $this->request->post('notes'),
                'credit_limit' => $this->request->post('credit_limit') ?: 0.00,
                'payment_terms' => $this->request->post('payment_terms') ?: 30,
                'tabela_preco_id' => $this->request->post('tabela_preco_id') ?: null,
                'send_email' => $this->request->post('send_email') ? 1 : 0,
                'send_sms' => $this->request->post('send_sms') ? 1 : 0,
                'is_vip' => $this->request->post('is_vip') ? 1 : 0,
                'is_active' => $this->request->post('is_active') ? 1 : 0,
                'grupo_id' => $this->request->post('grupo_id') ?: null,
                'subgrupo_id' => $this->request->post('subgrupo_id') ?: null,
                'vendedor_id' => $this->request->post('vendedor_id') ?: null,
                'vendedor_auxiliar_id' => $this->request->post('vendedor_auxiliar_id') ?: null,
                'area_comercial_id' => $this->request->post('area_comercial_id') ?: null,
                'id' => $id
            ];

            // Verificar se colunas de licenças existem
            $camposLicencas = ['data_anvisa', 'data_conselho_farmacia', 'data_vigilancia_sanitaria', 'data_alvara_localizacao'];
            $camposLicencasExistentes = [];
            $colunasLicencasUpdate = '';
            foreach ($camposLicencas as $campo) {
                try {
                    $stmtCheck = $this->db->query("SHOW COLUMNS FROM pessoas LIKE '{$campo}'");
                    if ($stmtCheck->rowCount() > 0) {
                        $camposLicencasExistentes[] = $campo;
                        $valor = $this->request->post($campo);
                        $data[$campo] = !empty($valor) ? $valor : null;
                    }
                } catch (Exception $e) {
                    // Campo não existe, ignorar
                }
            }
            if (!empty($camposLicencasExistentes)) {
                $setsLicencas = [];
                foreach ($camposLicencasExistentes as $campo) {
                    $setsLicencas[] = $campo . ' = :' . $campo;
                }
                $colunasLicencasUpdate = ', ' . implode(', ', $setsLicencas);
            }

            $this->db->beginTransaction();

            $stmt = $this->db->prepare("
                UPDATE pessoas SET
                    tipo_cliente = :tipo_cliente,
                    tipo_fornecedor = :tipo_fornecedor,
                    tipo_transportadora = :tipo_transportadora,
                    person_type = :person_type,
                    name = :name,
                    trade_name = :trade_name,
                    document = :document,
                    rg_ie = :rg_ie,
                    inscricao_municipal = :inscricao_municipal,
                    inscricao_suframa = :inscricao_suframa,
                    passaporte = :passaporte,
                    cnh = :cnh,
                    email = :email,
                    phone = :phone,
                    mobile = :mobile,
                    website = :website,
                    whatsapp = :whatsapp,
                    address = :address,
                    numero = :numero,
                    complemento = :complemento,
                    bairro = :bairro,
                    city = :city,
                    state = :state,
                    zip_code = :zip_code,
                    notes = :notes,
                    credit_limit = :credit_limit,
                    payment_terms = :payment_terms,
                    tabela_preco_id = :tabela_preco_id,
                    send_email = :send_email,
                    send_sms = :send_sms,
                    is_vip = :is_vip,
                    is_active = :is_active,
                    grupo_id = :grupo_id,
                    subgrupo_id = :subgrupo_id,
                    vendedor_id = :vendedor_id,
                    vendedor_auxiliar_id = :vendedor_auxiliar_id,
                    area_comercial_id = :area_comercial_id{$colunasLicencasUpdate}
                WHERE id = :id AND company_id = :company_id
            ");

            $data['company_id'] = $this->getCompanyId();
            $stmt->execute($data);

            // Atualiza grupos
            $this->db->exec("DELETE FROM pessoa_grupo WHERE pessoa_id = {$id}");
            $grupos = $this->request->post('grupos', []);
            if (!empty($grupos)) {
                $this->associateGroups($id, $grupos);
            }

            $veiculosPayload = $this->parseVeiculosPayload($this->request->post('veiculos_data'));
            $this->salvarVeiculos($id, $veiculosPayload);

            $contatosPayload = $this->parseContatosPayload($this->request->post('contatos_data'));
            $this->salvarContatos($id, $contatosPayload);

            // Salvar empresas vinculadas
            $empresasVinculadas = json_decode($this->request->post('empresas_vinculadas', '[]'), true);
            if (is_array($empresasVinculadas)) {
                $this->salvarEmpresasVinculadas($id, $empresasVinculadas);
            }

            $this->db->commit();

            $this->logActivity('update', 'pessoas', $id, $data);

            $this->success('Pessoa atualizada com sucesso', [
                'redirect' => '/pessoas'
            ]);

        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Erro ao atualizar pessoa: " . $e->getMessage());
            $this->error('Erro ao atualizar pessoa');
        }
    }

    /**
     * Deleta uma pessoa
     */
    public function delete(): void
    {
        try {
            $id = (int) $this->request->post('id');
            $pessoa = $this->getPessoa($id);

            if (!$pessoa) {
                $this->error('Pessoa não encontrada');
                return;
            }

            // Verifica se pode deletar (não tem vendas/compras associadas)
            $stmt = $this->db->prepare("
                SELECT COUNT(*) as count FROM vendas WHERE customer_id = :id AND company_id = :company_id
            ");
            $stmt->execute(['id' => $id, 'company_id' => $this->getCompanyId()]);
            $vendasCount = $stmt->fetch()['count'];

            // Verifica compras associadas (se a tabela existir)
            $comprasCount = 0;
            try {
                $stmt = $this->db->prepare("
                    SELECT COUNT(*) as count FROM compras
                    WHERE fornecedor_id = :id AND company_id = :company_id
                ");
                $stmt->execute(['id' => $id, 'company_id' => $this->getCompanyId()]);
                $comprasCount = $stmt->fetch()['count'];
            } catch (Exception $e) {
                // Tabela compras pode não existir, ignorar erro
                error_log("Tabela compras não encontrada ou erro ao verificar: " . $e->getMessage());
            }

            if ($vendasCount > 0 || $comprasCount > 0) {
                $this->error('Não é possível excluir esta pessoa pois possui vendas ou compras associadas');
                return;
            }

            $stmt = $this->db->prepare("
                DELETE FROM pessoas WHERE id = :id AND company_id = :company_id
            ");

            $stmt->execute([
                'id' => $id,
                'company_id' => $this->getCompanyId()
            ]);

            $this->logActivity('delete', 'pessoas', $id);

            $this->success('Pessoa excluída com sucesso');

        } catch (Exception $e) {
            error_log("Erro ao deletar pessoa: " . $e->getMessage());
            $this->error('Erro ao excluir pessoa');
        }
    }

    /**
     * Busca uma pessoa por ID
     */
    private function getPessoa(int $id): ?array
    {
        try {
            $companyId = $this->getCompanyId();

            // Verificar se a tabela pessoas tem company_id
            $stmt = $this->db->query("SHOW COLUMNS FROM pessoas LIKE 'company_id'");
            $temCompanyId = $stmt->rowCount() > 0;

            if ($temCompanyId && $companyId) {
                $stmt = $this->db->prepare("
                    SELECT * FROM pessoas
                    WHERE id = :id AND company_id = :company_id
                    LIMIT 1
                ");
                $stmt->execute([
                    'id' => $id,
                    'company_id' => $companyId
                ]);
            } else {
                $stmt = $this->db->prepare("
                    SELECT * FROM pessoas
                    WHERE id = :id
                    LIMIT 1
                ");
                $stmt->execute(['id' => $id]);
            }

            $pessoa = $stmt->fetch();
            return $pessoa ?: null;
        } catch (Exception $e) {
            error_log("Erro ao buscar pessoa #{$id}: " . $e->getMessage());
            return null;
        }
    }

    /**
     * Busca grupos por tipo
     */
    private function getGrupos(string $type): array
    {
        $stmt = $this->db->prepare("
            SELECT * FROM grupos
            WHERE type = :type AND company_id = :company_id AND is_active = 1
            ORDER BY name ASC
        ");

        $stmt->execute([
            'type' => $type,
            'company_id' => $this->getCompanyId()
        ]);

        return $stmt->fetchAll();
    }

    /**
     * Associa grupos a uma pessoa
     */
    private function associateGroups(int $pessoaId, array $grupos): void
    {
        $stmt = $this->db->prepare("
            INSERT INTO pessoa_grupo (pessoa_id, grupo_id) VALUES (:pessoa_id, :grupo_id)
        ");

        foreach ($grupos as $grupoId) {
            $stmt->execute([
                'pessoa_id' => $pessoaId,
                'grupo_id' => $grupoId
            ]);
        }
    }

    /**
     * Busca grupos de pessoas do banco de dados
     */
    private function getGruposPessoas(int $companyId): array
    {
        try {
            // Verificar se a tabela existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'grupos_pessoas'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $stmt = $this->db->prepare("
                SELECT *
                FROM grupos_pessoas
                WHERE company_id = :company_id
                  AND ativo = 1
                  AND tipo = 'pessoas'
                ORDER BY ordem ASC, nome ASC
            ");
            $stmt->execute(['company_id' => $companyId]);
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar grupos de pessoas: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Busca subgrupos de pessoas do banco de dados
     */
    private function getSubgruposPessoas(int $companyId, ?int $grupoId = null): array
    {
        try {
            // Verificar se a tabela existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'subgrupos_pessoas'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            if ($grupoId) {
                $stmt = $this->db->prepare("
                    SELECT sp.*
                    FROM subgrupos_pessoas sp
                    INNER JOIN grupos_pessoas gp ON gp.id = sp.grupo_id
                    WHERE sp.company_id = :company_id
                      AND sp.grupo_id = :grupo_id
                      AND sp.ativo = 1
                      AND gp.tipo = 'pessoas'
                    ORDER BY sp.ordem ASC, sp.nome ASC
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'grupo_id' => $grupoId
                ]);
            } else {
                $stmt = $this->db->prepare("
                    SELECT sp.*
                    FROM subgrupos_pessoas sp
                    INNER JOIN grupos_pessoas gp ON gp.id = sp.grupo_id
                    WHERE sp.company_id = :company_id
                      AND sp.ativo = 1
                      AND gp.tipo = 'pessoas'
                    ORDER BY sp.ordem ASC, sp.nome ASC
                ");
                $stmt->execute(['company_id' => $companyId]);
            }
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar subgrupos de pessoas: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Busca áreas comerciais
     */
    private function getAreas(int $companyId): array
    {
        try {
            // Verificar se a tabela areas existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'areas'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $stmt = $this->db->prepare("
                SELECT id, name, description
                FROM areas
                WHERE company_id = :company_id
                  AND is_active = 1
                ORDER BY name ASC
            ");
            $stmt->execute(['company_id' => $companyId]);
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar áreas comerciais: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Busca vendedores (usuários com role ou type = 'vendedor')
     */
    private function getVendedores(int $companyId): array
    {
        try {
            // Verificar se a tabela users existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'users'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            // Verificar se o campo é 'type' ou 'role'
            $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;

            // Buscar vendedores - tentar type primeiro, depois role
            if ($temCampoType) {
                $stmt = $this->db->prepare("
                    SELECT id, name FROM users
                    WHERE company_id = :company_id
                      AND is_vendedor = 1
                      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 is_vendedor = 1
                      AND is_active = 1
                    ORDER BY name ASC
                ");
            } else {
                // Se não tiver nenhum dos campos, buscar todos os usuários ativos
                $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]);
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar vendedores: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Busca todas as empresas
     */
    private function getTodasEmpresas(): array
    {
        try {
            // Verificar se a tabela empresas existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'empresas'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $stmt = $this->db->prepare("
                SELECT id, razao_social, nome_fantasia, cnpj
                FROM empresas
                ORDER BY razao_social ASC
            ");
            $stmt->execute();
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar empresas: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Busca empresas vinculadas a uma pessoa
     */
    private function getEmpresasVinculadas(int $pessoaId): array
    {
        try {
            // Verificar se a tabela empresas_pessoas existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'empresas_pessoas'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $stmt = $this->db->prepare("
                SELECT ep.empresa_id
                FROM empresas_pessoas ep
                WHERE ep.pessoa_id = :pessoa_id
            ");
            $stmt->execute(['pessoa_id' => $pessoaId]);
            $result = $stmt->fetchAll();

            // Retornar apenas os IDs das empresas
            return array_column($result, 'empresa_id');
        } catch (Exception $e) {
            error_log("Erro ao buscar empresas vinculadas: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Salva empresas vinculadas a uma pessoa
     */
    private function salvarEmpresasVinculadas(int $pessoaId, array $empresaIds): void
    {
        try {
            // Verificar se a tabela empresas_pessoas existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'empresas_pessoas'");
            if ($stmt->rowCount() === 0) {
                return;
            }

            // Remover todas as vinculações existentes
            $stmt = $this->db->prepare("DELETE FROM empresas_pessoas WHERE pessoa_id = :pessoa_id");
            $stmt->execute(['pessoa_id' => $pessoaId]);

            // Inserir novas vinculações
            if (!empty($empresaIds)) {
                $stmt = $this->db->prepare("INSERT INTO empresas_pessoas (empresa_id, pessoa_id) VALUES (:empresa_id, :pessoa_id)");
                foreach ($empresaIds as $empresaId) {
                    $empresaId = (int) $empresaId;
                    if ($empresaId > 0) {
                        $stmt->execute([
                            'empresa_id' => $empresaId,
                            'pessoa_id' => $pessoaId
                        ]);
                    }
                }
            }
        } catch (Exception $e) {
            error_log("Erro ao salvar empresas vinculadas: " . $e->getMessage());
            // Não lançar exceção para não quebrar o fluxo principal
        }
    }

    /**
     * Busca tabelas de preço disponíveis
     */
    private function getTabelasPreco(int $companyId): array
    {
        try {
            // Verificar se a tabela tabela_preco existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'tabela_preco'");
            if ($stmt->rowCount() === 0) {
                // Fallback para tabela antiga se existir
                $stmt = $this->db->query("SHOW TABLES LIKE 'catalogo_tabelas_preco'");
                if ($stmt->rowCount() === 0) {
                    return [];
                }
                $stmt = $this->db->prepare("
                    SELECT id, nome, descricao
                    FROM catalogo_tabelas_preco
                    WHERE company_id = :company_id AND ativo = 1
                    ORDER BY ordem ASC, nome ASC
                ");
                $stmt->execute(['company_id' => $companyId]);
                return $stmt->fetchAll();
            }

            $stmt = $this->db->prepare("
                SELECT id, nome, descricao
                FROM tabela_preco
                WHERE company_id = :company_id AND ativo = 1
                ORDER BY ordem ASC, nome ASC
            ");
            $stmt->execute(['company_id' => $companyId]);
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar tabelas de preço: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Retorna veículos e motoristas associados à pessoa
     */
    private function getPessoaVeiculos(int $pessoaId): array
    {
        try {
            // Verificar se a tabela existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'pessoa_veiculos'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $companyId = $this->getCompanyId();

            $stmt = $this->db->prepare("
                SELECT *
                FROM pessoa_veiculos
                WHERE pessoa_id = :pessoa_id AND company_id = :company_id
                ORDER BY id ASC
            ");
            $stmt->execute([
                'pessoa_id' => $pessoaId,
                'company_id' => $companyId
            ]);
            $veiculos = $stmt->fetchAll();

            if (empty($veiculos)) {
                return [];
            }

            $ids = array_column($veiculos, 'id');
            if (empty($ids)) {
                return [];
            }

            $placeholders = implode(',', array_fill(0, count($ids), '?'));
            $stmtMotoristas = $this->db->prepare("
                SELECT *
                FROM pessoa_veiculo_motoristas
                WHERE pessoa_veiculo_id IN ($placeholders)
                ORDER BY id ASC
            ");
            $stmtMotoristas->execute($ids);
            $motoristas = $stmtMotoristas->fetchAll();

            $motoristasPorVeiculo = [];
            foreach ($motoristas as $motorista) {
                $motoristasPorVeiculo[$motorista['pessoa_veiculo_id']][] = $motorista;
            }

            foreach ($veiculos as &$veiculo) {
                $veiculo['motoristas'] = $motoristasPorVeiculo[$veiculo['id']] ?? [];
            }

            return $veiculos;
        } catch (Exception $e) {
            error_log('Erro ao buscar veículos da pessoa: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Persiste veículos e motoristas vinculados à pessoa
     */
    private function salvarVeiculos(int $pessoaId, array $veiculos): void
    {
        $companyId = $this->getCompanyId();

        $stmtIds = $this->db->prepare("
            SELECT id FROM pessoa_veiculos
            WHERE pessoa_id = :pessoa_id AND company_id = :company_id
        ");
        $stmtIds->execute([
            'pessoa_id' => $pessoaId,
            'company_id' => $companyId
        ]);
        $idsExistentes = $stmtIds->fetchAll(\PDO::FETCH_COLUMN);

        if (!empty($idsExistentes)) {
            $placeholders = implode(',', array_fill(0, count($idsExistentes), '?'));
            $stmtDelMotoristas = $this->db->prepare("
                DELETE FROM pessoa_veiculo_motoristas
                WHERE pessoa_veiculo_id IN ($placeholders)
            ");
            $stmtDelMotoristas->execute($idsExistentes);
        }

        $stmtDelVeiculos = $this->db->prepare("
            DELETE FROM pessoa_veiculos
            WHERE pessoa_id = :pessoa_id AND company_id = :company_id
        ");
        $stmtDelVeiculos->execute([
            'pessoa_id' => $pessoaId,
            'company_id' => $companyId
        ]);

        if (empty($veiculos)) {
            return;
        }

        $stmtVeiculo = $this->db->prepare("
            INSERT INTO pessoa_veiculos (
                company_id, pessoa_id, apelido, placa, tipo, marca, modelo, ano, cor,
                renavam, chassi, capacidade, observacoes, created_at, updated_at
            ) VALUES (
                :company_id, :pessoa_id, :apelido, :placa, :tipo, :marca, :modelo, :ano, :cor,
                :renavam, :chassi, :capacidade, :observacoes, NOW(), NOW()
            )
        ");

        $stmtMotorista = $this->db->prepare("
            INSERT INTO pessoa_veiculo_motoristas (
                pessoa_veiculo_id, nome, documento, cnh, categoria_cnh,
                validade_cnh, telefone, email, observacoes, created_at, updated_at
            ) VALUES (
                :pessoa_veiculo_id, :nome, :documento, :cnh, :categoria_cnh,
                :validade_cnh, :telefone, :email, :observacoes, NOW(), NOW()
            )
        ");

        foreach ($veiculos as $veiculo) {
            $apelido = trim($veiculo['apelido'] ?? '');
            $placa = trim($veiculo['placa'] ?? '');
            $modelo = trim($veiculo['modelo'] ?? '');

            if ($apelido === '' && $placa === '' && $modelo === '') {
                continue;
            }

            $stmtVeiculo->execute([
                'company_id' => $companyId,
                'pessoa_id' => $pessoaId,
                'apelido' => $apelido ?: null,
                'placa' => $placa ?: null,
                'tipo' => trim($veiculo['tipo'] ?? '') ?: null,
                'marca' => trim($veiculo['marca'] ?? '') ?: null,
                'modelo' => $modelo ?: null,
                'ano' => trim($veiculo['ano'] ?? '') ?: null,
                'cor' => trim($veiculo['cor'] ?? '') ?: null,
                'renavam' => trim($veiculo['renavam'] ?? '') ?: null,
                'chassi' => trim($veiculo['chassi'] ?? '') ?: null,
                'capacidade' => trim($veiculo['capacidade'] ?? '') ?: null,
                'observacoes' => trim($veiculo['observacoes'] ?? '') ?: null,
            ]);

            $veiculoId = (int) $this->db->lastInsertId();

            $motoristas = $veiculo['motoristas'] ?? [];
            foreach ($motoristas as $motorista) {
                $nomeMotorista = trim($motorista['nome'] ?? '');
                if ($nomeMotorista === '') {
                    continue;
                }

                $stmtMotorista->execute([
                    'pessoa_veiculo_id' => $veiculoId,
                    'nome' => $nomeMotorista,
                    'documento' => trim($motorista['documento'] ?? '') ?: null,
                    'cnh' => trim($motorista['cnh'] ?? '') ?: null,
                    'categoria_cnh' => trim($motorista['categoria_cnh'] ?? '') ?: null,
                    'validade_cnh' => !empty($motorista['validade_cnh']) ? $motorista['validade_cnh'] : null,
                    'telefone' => trim($motorista['telefone'] ?? '') ?: null,
                    'email' => trim($motorista['email'] ?? '') ?: null,
                    'observacoes' => trim($motorista['observacoes'] ?? '') ?: null,
                ]);
            }
        }
    }

    /**
     * Retorna dados rápidos de uma pessoa (para uso no modal)
     */
    public function dadosRapidos(): void
    {
        try {
            $id = (int) $this->request->get('id');
            $companyId = $this->getCompanyId();

            if ($id <= 0) {
                $this->jsonResponse([
                    'success' => false,
                    'message' => 'ID inválido'
                ], 400);
                return;
            }

            $stmt = $this->db->prepare("
                SELECT id, name, whatsapp, mobile, phone
                FROM pessoas
                WHERE id = :id AND company_id = :company_id
                LIMIT 1
            ");
            $stmt->execute([
                'id' => $id,
                'company_id' => $companyId
            ]);

            $pessoa = $stmt->fetch();

            if (!$pessoa) {
                $this->jsonResponse([
                    'success' => false,
                    'message' => 'Pessoa não encontrada'
                ], 404);
                return;
            }

            $this->jsonResponse([
                'success' => true,
                'data' => [
                    'id' => $pessoa['id'],
                    'name' => $pessoa['name'],
                    'whatsapp' => $pessoa['whatsapp'] ?? null,
                    'mobile' => $pessoa['mobile'] ?? null,
                    'phone' => $pessoa['phone'] ?? null
                ]
            ]);

        } catch (Exception $e) {
            error_log("Erro ao buscar dados rápidos da pessoa: " . $e->getMessage());
            $this->jsonResponse([
                'success' => false,
                'message' => 'Erro ao buscar dados'
            ], 500);
        }
    }

    /**
     * Normaliza payload de veículos
     */
    private function parseVeiculosPayload(?string $json): array
    {
        if (!$json) {
            return [];
        }

        $dados = json_decode($json, true);
        if (!is_array($dados)) {
            return [];
        }

        return $dados;
    }

    /**
     * Normaliza payload de contatos
     */
    private function parseContatosPayload(?string $json): array
    {
        if (!$json) {
            return [];
        }

        $dados = json_decode($json, true);
        if (!is_array($dados)) {
            return [];
        }

        return $dados;
    }

    /**
     * Busca contatos de uma pessoa
     */
    private function getPessoaContatos(int $pessoaId): array
    {
        try {
            // Verificar se a tabela pessoas_contatos existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'pessoas_contatos'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $companyId = $this->getCompanyId();
            $stmt = $this->db->prepare("
                SELECT id, nome, telefone, cargo
                FROM pessoas_contatos
                WHERE pessoa_id = :pessoa_id AND (company_id = :company_id OR company_id IS NULL)
                ORDER BY nome ASC
            ");
            $stmt->execute([
                'pessoa_id' => $pessoaId,
                'company_id' => $companyId
            ]);

            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar contatos da pessoa #{$pessoaId}: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Salva contatos de uma pessoa
     */
    private function salvarContatos(int $pessoaId, array $contatos): void
    {
        try {
            // Verificar se a tabela pessoas_contatos existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'pessoas_contatos'");
            if ($stmt->rowCount() === 0) {
                return;
            }

            $companyId = $this->getCompanyId();

            // Remover todos os contatos existentes
            $stmt = $this->db->prepare("
                DELETE FROM pessoas_contatos
                WHERE pessoa_id = :pessoa_id AND (company_id = :company_id OR company_id IS NULL)
            ");
            $stmt->execute([
                'pessoa_id' => $pessoaId,
                'company_id' => $companyId
            ]);

            if (empty($contatos)) {
                return;
            }

            // Inserir novos contatos
            $stmt = $this->db->prepare("
                INSERT INTO pessoas_contatos (company_id, pessoa_id, nome, telefone, cargo, created_at, updated_at)
                VALUES (:company_id, :pessoa_id, :nome, :telefone, :cargo, NOW(), NOW())
            ");

            foreach ($contatos as $contato) {
                $nome = trim($contato['nome'] ?? '');
                $telefone = trim($contato['telefone'] ?? '');
                $cargo = trim($contato['cargo'] ?? '');

                // Só salva se tiver pelo menos o nome
                if (!empty($nome)) {
                    $stmt->execute([
                        'company_id' => $companyId,
                        'pessoa_id' => $pessoaId,
                        'nome' => $nome,
                        'telefone' => $telefone,
                        'cargo' => $cargo
                    ]);
                }
            }
        } catch (Exception $e) {
            error_log("Erro ao salvar contatos da pessoa #{$pessoaId}: " . $e->getMessage());
            // Não lança exceção para não interromper o fluxo principal
        }
    }

    /**
     * Exibe extrato do cliente (vendas + contas a receber)
     */
    public function extrato(): void
    {
        try {
            $id = (int) $this->request->get('id');
            error_log("Extrato: ID recebido = {$id}");

            $pessoa = $this->getPessoa($id);
            error_log("Extrato: Pessoa encontrada = " . ($pessoa ? 'sim' : 'não'));

            if (!$pessoa) {
                $this->response->notFound('Pessoa não encontrada');
                return;
            }

            $companyId = $this->getCompanyId();
            error_log("Extrato: Company ID = {$companyId}");

            // Buscar vendas do cliente (baseado no customer_id) agrupadas por empresa
            error_log("Extrato: Buscando vendas para customer_id={$id}");
            $stmt = $this->db->prepare("
                SELECT
                    v.*,
                    mp.name as payment_method_name,
                    e.id as empresa_id,
                    COALESCE(e.nome_fantasia, e.razao_social, 'Empresa Principal') as empresa_nome
                FROM vendas v
                LEFT JOIN metodos_pagamento mp ON v.payment_method_id = mp.id
                LEFT JOIN empresas e ON v.company_id = e.id
                WHERE v.customer_id = :customer_id
                ORDER BY e.nome_fantasia ASC, e.razao_social ASC, v.sale_date DESC, v.id DESC
            ");
            $stmt->execute(['customer_id' => $id]);
            $vendas = $stmt->fetchAll();
            error_log("Extrato: Total de vendas encontradas = " . count($vendas));

            // Buscar itens de cada venda para a aba detalhada
            $vendasDetalhadas = [];
            foreach ($vendas as $venda) {
                $stmtItens = $this->db->prepare("
                    SELECT
                        id, venda_id, product_id, product_name, product_sku,
                        quantity, unit_price, discount, discount_type, total_price, notes
                    FROM vendas_itens
                    WHERE venda_id = :venda_id
                    ORDER BY id ASC
                ");
                $stmtItens->execute(['venda_id' => $venda['id']]);
                $itens = $stmtItens->fetchAll();

                $venda['itens'] = $itens;
                $vendasDetalhadas[] = $venda;
            }
            error_log("Extrato: Vendas detalhadas preparadas");

            // Buscar contas a receber do cliente (usa customer_id) agrupadas por empresa
            error_log("Extrato: Buscando contas a receber para cliente ID={$id}");
            $stmt = $this->db->prepare("
                SELECT
                    cr.*,
                    e.id as empresa_id,
                    COALESCE(e.nome_fantasia, e.razao_social, 'Empresa Principal') as empresa_nome
                FROM contas_receber cr
                LEFT JOIN empresas e ON cr.company_id = e.id
                WHERE cr.customer_id = :customer_id
                ORDER BY e.nome_fantasia ASC, e.razao_social ASC, cr.due_date DESC, cr.id DESC
            ");
            $stmt->execute(['customer_id' => $id]);
            $contasReceber = $stmt->fetchAll();
            error_log("Extrato: Total de contas a receber encontradas = " . count($contasReceber));

            // Calcular totais
            $totalVendas = 0;
            foreach ($vendas as $venda) {
                $totalVendas += (float) ($venda['total'] ?? 0);
            }

            $totalReceber = 0;
            $totalPago = 0;
            $totalRestante = 0;
            $totalVencido = 0;
            $contasVencidas = 0;
            $hoje = strtotime(date('Y-m-d'));

            foreach ($contasReceber as $conta) {
                $totalReceber += (float) ($conta['amount'] ?? 0);
                $totalPago += (float) ($conta['amount_received'] ?? 0);
                $restante = (float) ($conta['amount_remaining'] ?? 0);
                $totalRestante += $restante;

                // Calcular inadimplência
                $vencimento = strtotime($conta['due_date']);
                if ($vencimento < $hoje && $restante > 0) {
                    $totalVencido += $restante;
                    $contasVencidas++;
                }
            }

            // Limite de crédito
            $limiteCredito = (float) ($pessoa['credit_limit'] ?? 0);
            $limiteUtilizado = $totalRestante;
            $limiteDisponivel = $limiteCredito - $limiteUtilizado;

            error_log("Extrato: Totais calculados - Vendas: {$totalVendas}, Receber: {$totalReceber}, Pago: {$totalPago}, Restante: {$totalRestante}");

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

            error_log("Extrato: Renderizando view...");

            $this->view('pessoas/extrato', [
                'pessoa' => $pessoa,
                'vendas' => $vendas,
                'vendasDetalhadas' => $vendasDetalhadas,
                'contasReceber' => $contasReceber,
                'totalVendas' => $totalVendas,
                'totalReceber' => $totalReceber,
                'totalPago' => $totalPago,
                'totalRestante' => $totalRestante,
                'totalVencido' => $totalVencido,
                'contasVencidas' => $contasVencidas,
                'limiteCredito' => $limiteCredito,
                'limiteUtilizado' => $limiteUtilizado,
                'limiteDisponivel' => $limiteDisponivel,
                'empresa' => $empresa,
                'pageTitle' => 'Extrato - ' . $pessoa['name'],
                'activeMenu' => 'pessoas'
            ]);

        } catch (\Throwable $e) {
            error_log("ERRO ao exibir extrato: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao carregar extrato: ' . $e->getMessage());
        }
    }
}

