<?php

declare(strict_types=1);

namespace App\Controllers;

use Exception;
use PDOException;
use App\Helpers\UrlHelper;

class UsuariosController extends BaseController
{
    public function index(): void
    {
        // Verificar permissão de visualização
        if (!$this->canView('usuarios')) {
            $this->response->forbidden('Você não tem permissão para visualizar usuários.');
            return;
        }

        try {
            $companyId = $this->getCompanyId();

            if (!$companyId) {
                $this->error('Sessão expirada. Por favor, faça login novamente.', [], 401);
                return;
            }

            // Verificar se há conexão com o banco de dados
            if (!$this->db) {
                error_log("[UsuariosController::index] Erro: Conexão com o banco de dados não estabelecida.");
                if ($this->request->isAjax()) {
                    $this->error('Erro de conexão com o banco de dados');
                } else {
                    $this->session->flash('error_message', 'Erro de conexão com o banco de dados.');
                    $this->redirect('/dashboard');
                }
                return;
            }

            $search = $this->request->get('search', '');
            $role = $this->request->get('role', '');

            $query = "
                SELECT * FROM users
                WHERE company_id = :company_id
            ";

            $params = ['company_id' => $companyId];

            if (!empty($search)) {
                $query .= " AND (name LIKE :search OR email LIKE :search)";
                $params['search'] = "%{$search}%";
            }

            if (!empty($role)) {
                $query .= " AND role = :role";
                $params['role'] = $role;
            }

            $query .= " ORDER BY name ASC";

            $stmt = $this->db->prepare($query);
            $stmt->execute($params);
            $usuarios = $stmt->fetchAll();

            $this->view('usuarios/index', [
                'usuarios' => $usuarios,
                'search' => $search,
                'role' => $role,
                'pageTitle' => 'Usuários',
                'activeMenu' => 'usuarios'
            ]);

        } catch (PDOException $e) {
            error_log("[UsuariosController::index] Erro PDO ao carregar usuários: " . $e->getMessage());
            error_log("[UsuariosController::index] Trace: " . $e->getTraceAsString());
            $this->session->flash('error_message', 'Erro ao carregar usuários. Verifique os logs para mais detalhes.');
            $this->view('usuarios/index', [
                'usuarios' => [],
                'search' => $search ?? '',
                'role' => $role ?? '',
                'pageTitle' => 'Usuários',
                'activeMenu' => 'usuarios'
            ]);
        } catch (Exception $e) {
            error_log("[UsuariosController::index] Erro ao carregar usuários: " . $e->getMessage());
            error_log("[UsuariosController::index] Trace: " . $e->getTraceAsString());
            $this->session->flash('error_message', 'Erro ao carregar usuários. Verifique os logs para mais detalhes.');
            $this->view('usuarios/index', [
                'usuarios' => [],
                'search' => $search ?? '',
                'role' => $role ?? '',
                'pageTitle' => 'Usuários',
                'activeMenu' => 'usuarios'
            ]);
        }
    }

    public function create(): void
    {
        // Verificar permissão de criação
        if (!$this->canCreate('usuarios')) {
            $this->response->forbidden('Você não tem permissão para criar usuários.');
            return;
        }

        $todasEmpresas = $this->getTodasEmpresas();

        // Buscar perfis de acesso disponíveis
        $perfisAcesso = $this->getPerfisAcesso();

        $this->view('usuarios/create', [
            'todasEmpresas' => $todasEmpresas,
            'empresasVinculadas' => [],
            'perfisAcesso' => $perfisAcesso,
            'pageTitle' => 'Novo Usuário',
            'activeMenu' => 'usuarios'
        ]);
    }

    public function store(): void
    {
        error_log("=== USUARIOS STORE CHAMADO ===");

        // Verificar permissão de criação
        $canCreate = $this->canCreate('usuarios');
        error_log("canCreate('usuarios'): " . ($canCreate ? 'true' : 'false'));

        if (!$canCreate) {
            error_log("ERRO: Sem permissão para criar usuários");
            $this->response->forbidden('Você não tem permissão para criar usuários.');
            return;
        }

        try {
            error_log("=== INÍCIO STORE USUÁRIO ===");
            error_log("POST recebido: " . json_encode($_POST));
            error_log("Content-Type: " . ($_SERVER['HTTP_CONTENT_TYPE'] ?? 'N/A'));
            error_log("Request Method: " . ($_SERVER['REQUEST_METHOD'] ?? 'N/A'));
            error_log("php://input length: " . strlen(file_get_contents('php://input')));

            // Se $_POST estiver vazio mas é POST, tentar ler de php://input
            if (empty($_POST) && $this->request->method() === 'POST') {
                $input = file_get_contents('php://input');
                if (!empty($input)) {
                    parse_str($input, $parsed);
                    error_log("Dados parseados de php://input: " . json_encode($parsed));
                    // Mesclar com $_POST para que o Request possa acessar
                    $_POST = array_merge($_POST, $parsed);
                }
            }

            $companyId = $this->getCompanyId();
            error_log("Company ID: " . ($companyId ?? 'NULL'));

            if (!$companyId) {
                error_log("ERRO: Company ID não encontrado");
                $this->error('Company ID não encontrado. Faça login novamente.', [], 401);
                return;
            }

            // Validações básicas
            $name = trim($this->request->post('name') ?? '');
            $email = trim($this->request->post('email') ?? '');
            $password = $this->request->post('password') ?? '';

            $role = $this->request->post('role') ?? '';
            $perfilAcessoIdPost = $this->request->post('perfil_acesso_id');
            // Converter 0 (sem perfil) para null, ou usar o valor se for maior que 0
            $perfilAcessoId = ($perfilAcessoIdPost !== null && $perfilAcessoIdPost !== '') ? ((int) $perfilAcessoIdPost > 0 ? (int) $perfilAcessoIdPost : null) : null;
            error_log("Dados recebidos - Nome: " . ($name ?: 'VAZIO') . ", Email: " . ($email ?: 'VAZIO') . ", Senha: " . ($password ? 'PRESENTE' : 'VAZIA') . ", Role: " . ($role ?: 'VAZIO') . ", Perfil Acesso ID: " . ($perfilAcessoId ?? 'NULL (sem perfil)'));

            if (empty($name)) {
                error_log("ERRO: Nome vazio");
                $this->error('O nome é obrigatório');
                return;
            }

            if (empty($email)) {
                error_log("ERRO: Email vazio");
                $this->error('O email é obrigatório');
                return;
            }

            if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                error_log("ERRO: Email inválido: " . $email);
                $this->error('Email inválido');
                return;
            }

            if (empty($password)) {
                error_log("ERRO: Senha vazia");
                $this->error('A senha é obrigatória');
                return;
            }

            // Verificar se o email já existe
            error_log("Verificando se email já existe...");
            try {
                $stmt = $this->db->prepare("SELECT id FROM users WHERE email = :email AND company_id = :company_id LIMIT 1");
                $stmt->execute(['email' => $email, 'company_id' => $companyId]);
                $usuarioExistente = $stmt->fetch();

                if ($usuarioExistente) {
                    error_log("ERRO: Email já cadastrado");
                    $this->error('Este email já está cadastrado');
                    return;
                }
                error_log("Email disponível");
            } catch (Exception $e) {
                error_log("ERRO ao verificar email: " . $e->getMessage());
                throw $e;
            }

            // Verificar se o campo notes existe na tabela
            try {
                $stmt = $this->db->query("SHOW COLUMNS FROM users LIKE 'notes'");
                $notesExists = $stmt->fetch() !== false;
            } catch (Exception $e) {
                error_log("Erro ao verificar coluna notes: " . $e->getMessage());
                $notesExists = false; // Assume que não existe se houver erro
            }

            // Verificar se o campo perfil_acesso_id existe na tabela
            try {
                $stmt = $this->db->query("SHOW COLUMNS FROM users LIKE 'perfil_acesso_id'");
                $perfilAcessoIdExists = $stmt->fetch() !== false;
            } catch (Exception $e) {
                error_log("Erro ao verificar coluna perfil_acesso_id: " . $e->getMessage());
                $perfilAcessoIdExists = false;
            }

            // Perfil de acesso é opcional (pode ser "sem perfil" = null)

            // Validar role
            if (empty($role)) {
                error_log("ERRO: Role vazio, usando padrão 'operador'");
                $role = 'operador';
            }

            // Validar valores permitidos para role
            $rolesPermitidos = ['admin', 'gerente', 'operador', 'vendedor', 'manager', 'operator', 'viewer'];
            if (!in_array($role, $rolesPermitidos)) {
                error_log("ERRO: Role inválido: " . $role . ", usando padrão 'operador'");
                $role = 'operador';
            }

            error_log("Role final a ser salvo: " . $role);

            // Verificar se os campos de tipo existem
            $camposTipo = ['is_vendedor', 'is_tecnico', 'is_usuario', 'is_funcionario'];
            $camposTipoExistentes = [];
            foreach ($camposTipo as $campo) {
                try {
                    $stmt = $this->db->query("SHOW COLUMNS FROM users LIKE '{$campo}'");
                    if ($stmt->fetch() !== false) {
                        $camposTipoExistentes[] = $campo;
                    }
                } catch (Exception $e) {
                    // Campo não existe, ignorar
                }
            }

            $data = [
                'company_id' => $companyId,
                'name' => $name,
                'email' => $email,
                'password' => password_hash($password, PASSWORD_DEFAULT),
                'role' => $role,
                'is_active' => $this->request->post('is_active') ? 1 : 0,
            ];

            if ($notesExists) {
                $data['notes'] = $this->request->post('notes') ?: null;
            }

            // Adicionar perfil_acesso_id se o campo existir (pode ser null para "sem perfil")
            if ($perfilAcessoIdExists) {
                $data['perfil_acesso_id'] = $perfilAcessoId; // null se "sem perfil", ou o ID do perfil
            }

            // Adicionar campos de tipo se existirem
            foreach ($camposTipoExistentes as $campo) {
                $data[$campo] = $this->request->post($campo) ? 1 : 0;
            }

            // Adicionar campos de vendedor se existirem
            foreach ($camposVendedorExistentes as $campo) {
                if ($campo === 'carteira') {
                    $data[$campo] = $this->request->post($campo) ? 1 : 0;
                } else {
                    $valor = $this->request->post($campo);
                    $data[$campo] = $valor !== null && $valor !== '' ? (float) $valor : 0;
                }
            }

            error_log("Iniciando transação...");
            $this->db->beginTransaction();

            // Construir query dinamicamente
            $campos = ['company_id', 'name', 'email', 'password', 'role', 'is_active'];
            $valores = [':company_id', ':name', ':email', ':password', ':role', ':is_active'];

            // Adicionar perfil_acesso_id se existir
            if ($perfilAcessoIdExists && isset($data['perfil_acesso_id'])) {
                $campos[] = 'perfil_acesso_id';
                $valores[] = ':perfil_acesso_id';
            }

            if ($notesExists) {
                $campos[] = 'notes';
                $valores[] = ':notes';
            }

            foreach ($camposTipoExistentes as $campo) {
                $campos[] = $campo;
                $valores[] = ':' . $campo;
            }

            foreach ($camposVendedorExistentes as $campo) {
                $campos[] = $campo;
                $valores[] = ':' . $campo;
            }

            $campos[] = 'created_at';
            $campos[] = 'updated_at';
            $valores[] = 'NOW()';
            $valores[] = 'NOW()';

            $sql = "INSERT INTO users (" . implode(', ', $campos) . ") VALUES (" . implode(', ', $valores) . ")";
            error_log("SQL: " . $sql);
            $stmt = $this->db->prepare($sql);

            error_log("Executando INSERT com dados: " . json_encode(array_merge($data, ['password' => '***HIDDEN***'])));
            $stmt->execute($data);
            $usuarioId = (int) $this->db->lastInsertId();
            error_log("Usuário criado com ID: " . $usuarioId);

            // Log de atividade (pode falhar silenciosamente se a tabela não existir)
            try {
                $this->logActivity('create', 'usuarios', $usuarioId, $data);
            } catch (Exception $e) {
                error_log("Erro ao registrar log de atividade: " . $e->getMessage());
                // Continua mesmo se o log falhar
            }

            // Salvar empresas vinculadas
            $empresasVinculadas = $this->request->post('empresas_vinculadas');
            if (!empty($empresasVinculadas)) {
                $empresasIds = json_decode($empresasVinculadas, true);
                if (is_array($empresasIds)) {
                    $this->salvarEmpresasVinculadas($usuarioId, $empresasIds);
                }
            }

            $this->db->commit();

            $this->success('Usuário criado com sucesso', [
                'id' => $usuarioId,
                'redirect' => '/usuarios'
            ]);

        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log("Erro PDO ao criar usuário: " . $e->getMessage());
            error_log("Código do erro: " . $e->getCode());
            error_log("Stack trace: " . $e->getTraceAsString());

            // Mensagem mais amigável para o usuário
            $mensagem = 'Erro ao criar usuário';
            if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
                $mensagem = 'Este email já está cadastrado';
            } elseif (strpos($e->getMessage(), 'Column') !== false && strpos($e->getMessage(), "doesn't exist") !== false) {
                $mensagem = 'Erro na estrutura do banco de dados. Entre em contato com o suporte.';
            }

            $this->error($mensagem . ': ' . $e->getMessage());
        } catch (Exception $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log("Erro ao criar usuário: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao criar usuário: ' . $e->getMessage());
        }
    }

    public function edit(): void
    {
        // Verificar permissão de edição
        if (!$this->canEdit('usuarios')) {
            $this->response->forbidden('Você não tem permissão para editar usuários.');
            return;
        }

        try {
            $id = (int) $this->request->get('id');
            $usuario = $this->getUsuario($id);

            if (!$usuario) {
                $this->response->notFound('Usuário não encontrado');
                return;
            }

            // Proteção: Usuário id = 1 só pode ser editado por ele mesmo
            if ($id === 1) {
                $loggedUserId = $this->getUserId();
                if ($loggedUserId !== 1) {
                    $this->error('Você não tem permissão para editar este usuário. Apenas o próprio usuário pode editar sua conta.');
                    return;
                }
            }

            // Carregar permissões do usuário
            $permissoes = $this->getPermissoes($id);

            // Buscar empresas vinculadas
            $todasEmpresas = $this->getTodasEmpresas();
            $empresasVinculadas = $this->getEmpresasVinculadas($id);

            // Buscar perfis de acesso disponíveis
            $perfisAcesso = $this->getPerfisAcesso();

            $this->view('usuarios/edit', [
                'usuario' => $usuario,
                'permissoes' => $permissoes,
                'todasEmpresas' => $todasEmpresas,
                'empresasVinculadas' => $empresasVinculadas,
                'perfisAcesso' => $perfisAcesso,
                'pageTitle' => 'Editar Usuário',
                'activeMenu' => 'usuarios'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao editar usuário: " . $e->getMessage());
            $this->error('Erro ao carregar formulário');
        }
    }

    public function update(): void
    {
        // Verificar permissão de edição
        if (!$this->canEdit('usuarios')) {
            $this->response->forbidden('Você não tem permissão para editar usuários.');
            return;
        }

        try {
            $id = (int) $this->request->post('id');
            $usuario = $this->getUsuario($id);

            if (!$usuario) {
                $this->error('Usuário não encontrado');
                return;
            }

            // Proteção: Usuário id = 1 só pode ser editado por ele mesmo
            if ($id === 1) {
                $loggedUserId = $this->getUserId();
                if ($loggedUserId !== 1) {
                    $this->error('Você não tem permissão para editar este usuário. Apenas o próprio usuário pode editar sua conta.');
                    return;
                }
            }

            // Verificar se o campo notes existe na tabela
            try {
                $stmt = $this->db->query("SHOW COLUMNS FROM users LIKE 'notes'");
                $notesExists = $stmt->fetch() !== false;
            } catch (Exception $e) {
                error_log("Erro ao verificar coluna notes: " . $e->getMessage());
                $notesExists = false; // Assume que não existe se houver erro
            }

            // Verificar se o campo perfil_acesso_id existe na tabela
            try {
                $stmt = $this->db->query("SHOW COLUMNS FROM users LIKE 'perfil_acesso_id'");
                $perfilAcessoIdExists = $stmt->fetch() !== false;
            } catch (Exception $e) {
                error_log("Erro ao verificar coluna perfil_acesso_id: " . $e->getMessage());
                $perfilAcessoIdExists = false;
            }

            // Verificar se os campos de tipo existem
            $camposTipo = ['is_vendedor', 'is_tecnico', 'is_usuario', 'is_funcionario'];
            $camposTipoExistentes = [];
            foreach ($camposTipo as $campo) {
                try {
                    $stmt = $this->db->query("SHOW COLUMNS FROM users LIKE '{$campo}'");
                    if ($stmt->fetch() !== false) {
                        $camposTipoExistentes[] = $campo;
                    }
                } catch (Exception $e) {
                    // Campo não existe, ignorar
                }
            }

            // Verificar se os campos de vendedor existem
            $camposVendedor = ['desconto', 'comissao', 'carteira'];
            $camposVendedorExistentes = [];
            foreach ($camposVendedor as $campo) {
                try {
                    $stmt = $this->db->query("SHOW COLUMNS FROM users LIKE '{$campo}'");
                    if ($stmt->fetch() !== false) {
                        $camposVendedorExistentes[] = $campo;
                    }
                } catch (Exception $e) {
                    // Campo não existe, ignorar
                }
            }

            $perfilAcessoIdPost = $this->request->post('perfil_acesso_id');
            // Converter 0 (sem perfil) para null, ou usar o valor se for maior que 0
            $perfilAcessoId = ($perfilAcessoIdPost !== null && $perfilAcessoIdPost !== '') ? ((int) $perfilAcessoIdPost > 0 ? (int) $perfilAcessoIdPost : null) : null;

            // Perfil de acesso é opcional (pode ser "sem perfil" = null)

            $role = $this->request->post('role') ?? '';

            // Validar role
            if (empty($role)) {
                error_log("ERRO: Role vazio no update, usando padrão 'operador'");
                $role = 'operador';
            }

            // Validar valores permitidos para role
            $rolesPermitidos = ['admin', 'gerente', 'operador', 'vendedor', 'manager', 'operator', 'viewer'];
            if (!in_array($role, $rolesPermitidos)) {
                error_log("ERRO: Role inválido no update: " . $role . ", usando padrão 'operador'");
                $role = 'operador';
            }

            error_log("Role final a ser atualizado: " . $role);

            $data = [
                'name' => $this->request->post('name'),
                'email' => $this->request->post('email'),
                'role' => $role,
                'is_active' => $this->request->post('is_active') ? 1 : 0,
                'id' => $id,
                'company_id' => $this->getCompanyId()
            ];

            // Adicionar perfil_acesso_id se o campo existir e foi informado
            if ($perfilAcessoIdExists && $perfilAcessoId) {
                $data['perfil_acesso_id'] = $perfilAcessoId;
            } elseif ($perfilAcessoIdExists && $perfilAcessoId === null) {
                // Se foi enviado vazio, definir como NULL
                $data['perfil_acesso_id'] = null;
            }

            if ($notesExists) {
                $data['notes'] = $this->request->post('notes') ?: null;
            }

            // Adicionar campos de tipo se existirem
            foreach ($camposTipoExistentes as $campo) {
                $data[$campo] = $this->request->post($campo) ? 1 : 0;
            }

            // Adicionar campos de vendedor se existirem
            foreach ($camposVendedorExistentes as $campo) {
                if ($campo === 'carteira') {
                    $data[$campo] = $this->request->post($campo) ? 1 : 0;
                } else {
                    $valor = $this->request->post($campo);
                    $data[$campo] = $valor !== null && $valor !== '' ? (float) $valor : 0;
                }
            }

            // Se uma nova senha foi fornecida, criptografa ela
            if (!empty($this->request->post('password'))) {
                $data['password'] = password_hash($this->request->post('password'), PASSWORD_DEFAULT);
            }

            $this->db->beginTransaction();

            // Construir query dinamicamente
            $sets = ['name = :name', 'email = :email', 'role = :role', 'is_active = :is_active'];

            // Adicionar perfil_acesso_id se existir
            if ($perfilAcessoIdExists && isset($data['perfil_acesso_id'])) {
                $sets[] = 'perfil_acesso_id = :perfil_acesso_id';
            }

            if (isset($data['password'])) {
                $sets[] = 'password = :password';
            }

            if ($notesExists) {
                $sets[] = 'notes = :notes';
            }

            foreach ($camposTipoExistentes as $campo) {
                $sets[] = $campo . ' = :' . $campo;
            }

            foreach ($camposVendedorExistentes as $campo) {
                $sets[] = $campo . ' = :' . $campo;
            }

            $sets[] = 'updated_at = NOW()';

            $sql = "UPDATE users SET " . implode(', ', $sets) . " WHERE id = :id AND company_id = :company_id";
            error_log("UPDATE SQL: " . $sql);
            $stmt = $this->db->prepare($sql);

            $stmt->execute($data);

            // Salvar permissões
            $this->salvarPermissoes($id, $this->request->post('permissoes', []));

            // Log de atividade (pode falhar silenciosamente se a tabela não existir)
            // Salvar empresas vinculadas
            $empresasVinculadas = $this->request->post('empresas_vinculadas');
            if (!empty($empresasVinculadas)) {
                $empresasIds = json_decode($empresasVinculadas, true);
                if (is_array($empresasIds)) {
                    $this->salvarEmpresasVinculadas($id, $empresasIds);
                }
            }

            try {
                $this->logActivity('update', 'usuarios', $id, $data);
            } catch (Exception $e) {
                error_log("Erro ao registrar log de atividade: " . $e->getMessage());
                // Continua mesmo se o log falhar
            }

            $this->db->commit();

            $this->success('Usuário atualizado com sucesso', [
                'redirect' => '/usuarios'
            ]);

        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log("Erro PDO ao atualizar usuário: " . $e->getMessage());
            error_log("Código do erro: " . $e->getCode());
            error_log("Stack trace: " . $e->getTraceAsString());

            // Mensagem mais amigável para o usuário
            $mensagem = 'Erro ao atualizar usuário';
            if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
                $mensagem = 'Este email já está cadastrado';
            } elseif (strpos($e->getMessage(), 'Column') !== false && strpos($e->getMessage(), "doesn't exist") !== false) {
                $mensagem = 'Erro na estrutura do banco de dados. Entre em contato com o suporte.';
            }

            $this->error($mensagem . ': ' . $e->getMessage());
        } catch (Exception $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log("Erro ao atualizar usuário: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            $this->error('Erro ao atualizar usuário: ' . $e->getMessage());
        }
    }

    public function delete(): void
    {
        // Verificar permissão de exclusão
        if (!$this->canDelete('usuarios')) {
            $this->response->forbidden('Você não tem permissão para excluir usuários.');
            return;
        }

        try {
            $id = (int) $this->request->post('id');
            $usuario = $this->getUsuario($id);

            if (!$usuario) {
                $this->error('Usuário não encontrado');
                return;
            }

            // Proteção: Usuário id = 1 não pode ser excluído
            if ($id === 1) {
                $this->error('Este usuário não pode ser excluído por questões de segurança.');
                return;
            }

            $this->db->beginTransaction();

            $stmt = $this->db->prepare("DELETE FROM users WHERE id = :id AND company_id = :company_id");
            $stmt->execute(['id' => $id, 'company_id' => $this->getCompanyId()]);

            $this->logActivity('delete', 'usuarios', $id, $usuario);
            $this->db->commit();

            $this->success('Usuário excluído com sucesso');

        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Erro ao excluir usuário: " . $e->getMessage());
            $this->error('Erro ao excluir usuário');
        }
    }

    private function getUsuario(int $id): ?array
    {
        $stmt = $this->db->prepare("SELECT * FROM users WHERE id = :id AND company_id = :company_id");
        $stmt->execute(['id' => $id, 'company_id' => $this->getCompanyId()]);
        return $stmt->fetch() ?: null;
    }

    /**
     * Busca permissões do usuário
     */
    private function getPermissoes(int $userId): array
    {
        try {
            // Verificar se a tabela existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'user_permissions'");
            if (!$stmt->fetch()) {
                return [];
            }

            $stmt = $this->db->prepare("
                SELECT module, can_view, can_create, can_edit, can_delete
                FROM user_permissions
                WHERE user_id = :user_id
            ");
            $stmt->execute(['user_id' => $userId]);
            return $stmt->fetchAll() ?: [];
        } catch (Exception $e) {
            error_log("Erro ao buscar permissões: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Salva permissões do usuário
     */
    private function salvarPermissoes(int $userId, array $permissoes): void
    {
        try {
            // Verificar se a tabela existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'user_permissions'");
            if (!$stmt->fetch()) {
                error_log("Tabela user_permissions não existe. Criando...");
                $this->criarTabelaPermissoes();
            }

            // Deletar permissões existentes
            $stmt = $this->db->prepare("DELETE FROM user_permissions WHERE user_id = :user_id");
            $stmt->execute(['user_id' => $userId]);

            // Inserir novas permissões
            if (!empty($permissoes)) {
                $stmt = $this->db->prepare("
                    INSERT INTO user_permissions (user_id, module, can_view, can_create, can_edit, can_delete)
                    VALUES (:user_id, :module, :can_view, :can_create, :can_edit, :can_delete)
                ");

                foreach ($permissoes as $module => $perms) {
                    $stmt->execute([
                        'user_id' => $userId,
                        'module' => $module,
                        'can_view' => isset($perms['can_view']) && $perms['can_view'] ? 1 : 0,
                        'can_create' => isset($perms['can_create']) && $perms['can_create'] ? 1 : 0,
                        'can_edit' => isset($perms['can_edit']) && $perms['can_edit'] ? 1 : 0,
                        'can_delete' => isset($perms['can_delete']) && $perms['can_delete'] ? 1 : 0,
                    ]);
                }
            }
        } catch (Exception $e) {
            error_log("Erro ao salvar permissões: " . $e->getMessage());
            // Não quebra o processo, apenas loga o erro
        }
    }

    /**
     * Cria a tabela de permissões se não existir
     */
    private function criarTabelaPermissoes(): void
    {
        try {
            $this->db->exec("
                CREATE TABLE IF NOT EXISTS user_permissions (
                    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                    user_id INT UNSIGNED NOT NULL,
                    module VARCHAR(100) NOT NULL COMMENT 'pessoas, vendas, compras, etc',
                    can_view BOOLEAN DEFAULT FALSE,
                    can_create BOOLEAN DEFAULT FALSE,
                    can_edit BOOLEAN DEFAULT FALSE,
                    can_delete BOOLEAN DEFAULT FALSE,
                    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
                    UNIQUE KEY unique_user_module (user_id, module)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ");
        } catch (Exception $e) {
            error_log("Erro ao criar tabela user_permissions: " . $e->getMessage());
        }
    }

    /**
     * Busca perfis de acesso disponíveis
     */
    private function getPerfisAcesso(): array
    {
        try {
            if (!$this->db) {
                return [];
            }

            // Verificar se a tabela existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'perfis_acesso'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $companyId = $this->getCompanyId();
            if (!$companyId) {
                return [];
            }

            // Buscar perfis ativos
            $stmt = $this->db->prepare("
                SELECT id, nome, descricao
                FROM perfis_acesso
                WHERE company_id = :company_id AND ativo = 1
                ORDER BY nome ASC
            ");
            $stmt->execute(['company_id' => $companyId]);
            return $stmt->fetchAll() ?: [];
        } catch (Exception $e) {
            error_log("Erro ao buscar perfis de acesso: " . $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 um usuário
     */
    private function getEmpresasVinculadas(int $userId): array
    {
        try {
            // Verificar se a tabela empresas_users existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'empresas_users'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            $stmt = $this->db->prepare("
                SELECT eu.empresa_id
                FROM empresas_users eu
                WHERE eu.user_id = :user_id
            ");
            $stmt->execute(['user_id' => $userId]);
            $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 um usuário
     */
    private function salvarEmpresasVinculadas(int $userId, array $empresaIds): void
    {
        try {
            // Verificar se a tabela empresas_users existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'empresas_users'");
            if ($stmt->rowCount() === 0) {
                return;
            }

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

            // Inserir novas vinculações
            if (!empty($empresaIds)) {
                $stmt = $this->db->prepare("INSERT INTO empresas_users (empresa_id, user_id) VALUES (:empresa_id, :user_id)");
                foreach ($empresaIds as $empresaId) {
                    $empresaId = (int) $empresaId;
                    if ($empresaId > 0) {
                        $stmt->execute([
                            'empresa_id' => $empresaId,
                            'user_id' => $userId
                        ]);
                    }
                }
            }
        } catch (Exception $e) {
            error_log("Erro ao salvar empresas vinculadas: " . $e->getMessage());
            // Não quebra o processo, apenas loga o erro
        }
    }
}