TransWar File Browser

Path: C:\

<!DOCTYPE html>
<html lang="pt-br" data-bs-theme="dark">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Trans War - Central de Crachás</title>

    <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
    <link href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.0.3/src/regular/style.css" rel="stylesheet">
    <link rel="icon" type="image/png" href="img/favicon.ico">

    <style>
        :root {
            --bg-color: #0b0f19;
            --glass-bg: rgba(18, 25, 38, 0.65);
            --glass-border: rgba(255, 255, 255, 0.08);
            --primary: #3b82f6;
            --primary-hover: #2563eb;
            --text-main: #f8fafc;
            --text-muted: #94a3b8;
        }

        body {
            font-family: 'Outfit', sans-serif;
            background: var(--bg-color);
            background-image:
                radial-gradient(circle at 15% 50%, rgba(59, 130, 246, 0.15), transparent 25%),
                radial-gradient(circle at 85% 30%, rgba(245, 158, 11, 0.08), transparent 25%);
            background-attachment: fixed;
            color: var(--text-main);
            min-height: 100vh;
        }

        .glass-card {
            background: var(--glass-bg);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            border: 1px solid var(--glass-border);
            border-radius: 16px;
            box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2);
        }

        .navbar-brand img {
            max-height: 50px;
        }

        /* Nav Pills */
        .nav-pills .nav-link {
            color: var(--text-muted);
            border-radius: 8px;
            padding: 12px 24px;
            font-weight: 500;
            transition: all 0.3s ease;
            margin-right: 10px;
        }

        .nav-pills .nav-link:hover {
            background: rgba(255, 255, 255, 0.05);
        }

        .nav-pills .nav-link.active {
            background: var(--primary);
            color: #fff;
            box-shadow: 0 4px 15px rgba(59, 130, 246, 0.4);
        }

        .btn-primary {
            background: var(--primary);
            border: none;
            box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3);
            transition: all 0.3s;
        }

        .btn-primary:hover {
            background: var(--primary-hover);
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(59, 130, 246, 0.5);
        }

        .form-control,
        .form-select {
            background-color: rgba(0, 0, 0, 0.2) !important;
            border: 1px solid var(--glass-border) !important;
            color: var(--text-main) !important;
        }

        .form-control:focus,
        .form-select:focus {
            border-color: var(--primary) !important;
            box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.15) !important;
        }

        /* Corrigir styling das opções nos selects */
        .form-select option {
            background-color: #1e293b;
            color: var(--text-main);
        }

        /* Select2 Dark/Premium Integration */
        .select2-container--default .select2-selection--single {
            background-color: rgba(0, 0, 0, 0.2);
            border: 1px solid var(--glass-border);
            border-radius: 8px;
            height: 52px;
            display: flex;
            align-items: center;
        }

        .select2-container--default .select2-selection--single .select2-selection__rendered {
            color: var(--text-main);
            padding-left: 15px;
            font-size: 1.05rem;
        }

        .select2-container--default .select2-selection--single .select2-selection__arrow {
            height: 50px;
            right: 15px;
        }

        .select2-dropdown {
            background-color: #1e293b;
            border: 1px solid var(--glass-border);
            border-radius: 8px;
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.4);
        }

        .select2-container--default .select2-search--dropdown .select2-search__field {
            background-color: rgba(0, 0, 0, 0.3);
            border: 1px solid var(--glass-border);
            color: #fff;
            border-radius: 6px;
            padding: 8px 12px;
        }

        .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
            background-color: var(--primary);
            border-radius: 6px;
            margin: 0 5px;
        }

        .select2-results__option {
            color: #fff;
            padding: 10px 15px;
        }

        /* Table Aesthetics */
        .table {
            color: var(--text-main);
            --bs-table-bg: transparent;
        }

        .table-hover tbody tr {
            transition: all 0.2s;
        }

        .table-hover tbody tr:hover {
            background-color: rgba(255, 255, 255, 0.03);
            color: #fff;
            transform: scale(1.005);
            box-shadow: inset 2px 0 0 var(--primary);
        }

        .table td,
        .table th {
            border-bottom-color: var(--glass-border);
            vertical-align: middle;
            padding: 15px;
        }

        #aqui {
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .empty-state {
            text-align: center;
            padding: 40px;
            color: var(--text-muted);
        }
    </style>
</head>

<body>

    <div class="container py-5">

        <!-- HEADER NAVBAR -->
        <div class="d-flex flex-column flex-md-row justify-content-between align-items-center mb-5 pb-4 border-bottom"
            style="border-color: var(--glass-border) !important;">
            <div class="navbar-brand mb-3 mb-md-0">
                <img src="img/logo.png" alt="Trans War Logo">
            </div>
            <h3 class="fw-bold mb-0"
                style="background: linear-gradient(90deg, #fff, #94a3b8); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
                Central de Gestão e Crachás Premium
            </h3>
        </div>

        <!-- TABS NAVIGATION -->
        <ul class="nav nav-pills mb-4 gap-2" id="pills-tab" role="tablist">
            <li class="nav-item" role="presentation">
                <button class="nav-link active d-flex align-items-center" id="pills-gerar-tab" data-bs-toggle="pill"
                    data-bs-target="#pills-gerar" type="button" role="tab">
                    <i class="ph ph-qr-code fs-4 me-2"></i>Gerar Crachá (Estação)
                </button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link d-flex align-items-center" id="pills-gerenciar-tab" data-bs-toggle="pill"
                    data-bs-target="#pills-gerenciar" type="button" role="tab">
                    <i class="ph ph-users fs-4 me-2"></i>Gestão de Colaboradores
                </button>
            </li>
        </ul>

        <!-- TABS CONTENT -->
        <div class="tab-content" id="pills-tabContent">

            <!-- GERAR CRACHÁ --->
            <div class="tab-pane fade show active" id="pills-gerar" role="tabpanel">
                <div class="row align-items-stretch">
                    <!-- COLUNA 1: DADOS -->
                    <div class="col-lg-5 mb-4 mb-lg-0">
                        <div class="glass-card p-4 h-100 position-relative">
                            <div class="position-absolute top-0 start-0 translate-middle"
                                style="width: 200px; height: 200px; background: rgba(59, 130, 246, 0.15); filter: blur(80px); border-radius: 50%;">
                            </div>

                            <h4 class="fw-bold mb-4 position-relative"><i
                                    class="ph ph-identification-card fs-3 text-primary me-2 align-middle"></i>Dados do
                                Crachá</h4>

                            <div class="mb-4 position-relative">
                                <label class="form-label text-muted fw-medium mb-3">Pesquisar Banco Local</label>
                                <select id="select-funcionario" class="form-control">
                                    <option value="">Pesquise por nome...</option>
                                </select>
                            </div>

                            <div class="d-flex align-items-center mb-4 position-relative">
                                <hr class="flex-grow-1" style="border-color: var(--glass-border)">
                                <span class="px-3 text-muted" style="font-size:0.75rem;">CONTEÚDO DO CARTÃO</span>
                                <hr class="flex-grow-1" style="border-color: var(--glass-border)">
                            </div>

                            <div class="mb-3 position-relative">
                                <label class="form-label text-muted fw-medium mb-1 small">Nome Formatado (QR Code) <span
                                        class="text-primary">*</span></label>
                                <input type="text" id="g-nome"
                                    class="form-control fw-bold fs-5 px-3 py-2 bg-dark bg-opacity-25 border-primary"
                                    style="height: 48px;" placeholder="Ex: SILVIO SANTOS">
                                <input type="hidden" id="g-valor-oculto">
                                <input type="hidden" id="g-id-oculto">
                            </div>

                            <div class="row g-3 mb-3 position-relative">
                                <div class="col-sm-6">
                                    <label class="form-label text-muted fw-medium mb-1 small">Tipo / Vínculo</label>
                                    <select id="g-vinculo" class="form-select bg-dark bg-opacity-25 border-secondary"
                                        style="font-size:0.9em;">
                                        <option value="">Não Especificado</option>
                                        <option value="Colaborador (Trans War)">Trans War ("Da Casa")</option>
                                        <option value="Motorista Terceiro">Motorista Terceiro</option>
                                        <option value="Agregado">Agregado</option>
                                    </select>
                                </div>
                                <div class="col-sm-6">
                                    <label class="form-label text-muted fw-medium mb-1 small">Função</label>
                                    <input type="text" id="g-funcao"
                                        class="form-control bg-dark bg-opacity-25 border-secondary"
                                        placeholder="Ex: Motorista" style="font-size:0.9em;">
                                </div>
                            </div>

                            <div class="row g-3 mb-4 position-relative">
                                <div class="col-sm-4">
                                    <label class="form-label text-muted fw-medium mb-1 small">RG</label>
                                    <input type="text" id="g-rg"
                                        class="form-control bg-dark bg-opacity-25 border-secondary"
                                        placeholder="...00-0" style="font-size:0.85em;">
                                </div>
                                <div class="col-sm-4">
                                    <label class="form-label text-muted fw-medium mb-1 small">CPF</label>
                                    <input type="text" id="g-cpf"
                                        class="form-control bg-dark bg-opacity-25 border-secondary"
                                        placeholder="...000-00" style="font-size:0.85em;">
                                </div>
                                <div class="col-sm-4">
                                    <label class="form-label text-muted fw-medium mb-1 small">PIS</label>
                                    <input type="text" id="g-pis"
                                        class="form-control bg-dark bg-opacity-25 border-secondary"
                                        placeholder="0000000" style="font-size:0.85em;">
                                </div>
                            </div>

                            <button id="btn-gerar" class="btn btn-primary w-100 py-3 fw-bold mt-auto position-relative"
                                style="font-size: 1.1rem; letter-spacing: 1px;">
                                <i class="ph ph-magic-wand fs-4 me-2 align-middle"></i>GERAR EM TEMPO REAL
                            </button>
                        </div>
                    </div>

                    <!-- COLUNA 2: PREVIEW -->
                    <div class="col-lg-7">
                        <div class="glass-card p-4 h-100 d-flex flex-column" style="background: rgba(18, 25, 38, 0.4);">
                            <h5 class="text-muted mb-4 opacity-50 fw-normal border-bottom border-secondary pb-3"><i
                                    class="ph ph-cube me-2"></i>Virtualizador de Arte Final</h5>

                            <div id="aqui" class="flex-grow-1 w-100 position-relative">
                                <div class="text-center opacity-25" style="margin-top:20%;">
                                    <i class="ph ph-identification-badge" style="font-size: 6rem;"></i>
                                    <p class="mt-2 text-uppercase tracking-widest small">Pronto para Renderização</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- GERENCIAR COLABORADORES --->
            <div class="tab-pane fade" id="pills-gerenciar" role="tabpanel">
                <div class="glass-card p-4 p-md-5 mt-3">
                    <div class="d-flex flex-column flex-md-row justify-content-between align-items-center mb-4 pb-3 border-bottom"
                        style="border-color: var(--glass-border) !important;">
                        <div class="d-flex align-items-center mb-3 mb-md-0">
                            <div class="bg-primary bg-opacity-10 p-3 rounded-circle me-3">
                                <i class="ph ph-users-three fs-3 text-primary"></i>
                            </div>
                            <div>
                                <h4 class="fw-bold mb-1">Base de Dados Integrada</h4>
                                <p class="text-muted small mb-0">Gestão centralizada do corpo de funcionários</p>
                            </div>
                        </div>

                        <div class="d-flex flex-column flex-md-row align-items-center gap-3 w-100"
                            style="max-width: 450px;">
                            <span class="text-muted small fw-medium text-nowrap"><i
                                    class="ph ph-funnel me-1"></i>Filtro:</span>
                            <select id="filtro-tabela-vinculo"
                                class="form-select bg-dark bg-opacity-50 border-secondary w-50 w-md-auto">
                                <option value="">Todos os Registros</option>
                                <option value="Colaborador (Trans War)">Apenas Trans War ("Da Casa")</option>
                                <option value="Motorista Terceiro">Apenas Terceiros</option>
                                <option value="Agregado">Apenas Agregados</option>
                            </select>
                            <button
                                class="btn btn-primary px-4 py-2 d-flex align-items-center fw-medium flex-shrink-0 w-md-auto"
                                onclick="abrirModalAdd()">
                                <i class="ph ph-plus-circle fs-4 me-2"></i>Inclusão
                            </button>
                        </div>
                    </div>

                    <div class="table-responsive">
                        <table class="table table-hover align-middle mb-0">
                            <thead style="background: rgba(0,0,0,0.15);">
                                <tr>
                                    <th class="text-muted fw-medium py-3 rounded-start px-4"># ID</th>
                                    <th class="text-muted fw-medium py-3">COLABORADOR / PROPRIEDADES</th>
                                    <th class="text-muted fw-medium py-3">INFORMAÇÃO EMBARCADA</th>
                                    <th class="text-muted fw-medium py-3 rounded-end text-end px-4"
                                        style="width: 200px;">AÇÕES MASTER</th>
                                </tr>
                            </thead>
                            <tbody id="tabela-funcionarios">
                                <tr>
                                    <td colspan="4" class="empty-state">Gerando Listagem...</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>

        </div>
    </div>

    <!-- MODAL CADASTRO / EDIÇÃO -->
    <div class="modal fade" id="funcModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
        <div class="modal-dialog modal-dialog-centered modal-lg">
            <div class="modal-content glass-card" style="background: #1e293b; border: 1px solid rgba(255,255,255,0.1);">
                <div class="modal-header border-bottom border-secondary border-opacity-25 pb-3">
                    <h5 class="modal-title fw-bold" id="funcModalTitle"><i
                            class="ph ph-user-circle-plus me-2 text-primary fs-4 align-middle"></i>Incluir Colaborador
                    </h5>
                    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"
                        aria-label="Close"></button>
                </div>
                <div class="modal-body p-4">
                    <input type="hidden" id="f-id">

                    <div class="row">
                        <div class="col-md-5 mb-4">
                            <label class="form-label fw-medium mb-2 opacity-75">Tipo / Vínculo</label>
                            <select id="f-vinculo" class="form-select p-3 bg-dark bg-opacity-50 border-secondary">
                                <option value="">Não Classificado</option>
                                <option value="Colaborador (Trans War)">Trans War ("Da Casa")</option>
                                <option value="Motorista Terceiro">Motorista Terceiro</option>
                                <option value="Agregado">Agregado</option>
                            </select>
                        </div>
                        <div class="col-md-7 mb-4">
                            <label class="form-label fw-medium mb-2 opacity-75">Nome Curto / Display</label>
                            <input type="text" id="f-nome"
                                class="form-control p-3 bg-dark bg-opacity-50 border-secondary"
                                placeholder="Ex: JOÃO SILVA">
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-md-12 mb-4 mt-n2">
                            <label class="form-label fw-medium mb-2 opacity-75">Função Ocupacional</label>
                            <input type="text" id="f-funcao"
                                class="form-control p-3 bg-dark bg-opacity-50 border-secondary"
                                placeholder="Ex: Motorista M1">
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-md-4 mb-4">
                            <label class="form-label fw-medium mb-2 opacity-75">RG</label>
                            <input type="text" id="f-rg" class="form-control p-3 bg-dark bg-opacity-50 border-secondary"
                                placeholder="00.000.000-0">
                        </div>
                        <div class="col-md-4 mb-4">
                            <label class="form-label fw-medium mb-2 opacity-75">CPF</label>
                            <input type="text" id="f-cpf"
                                class="form-control p-3 bg-dark bg-opacity-50 border-secondary"
                                placeholder="000.000.000-00">
                        </div>
                        <div class="col-md-4 mb-4">
                            <label class="form-label fw-medium mb-2 opacity-75">PIS</label>
                            <input type="text" id="f-pis"
                                class="form-control p-3 bg-dark bg-opacity-50 border-secondary" placeholder="00000000">
                        </div>
                    </div>

                    <!-- Bloco manual removido: Geração da matriz do QR Code (Tripa com separadores) ocorre de modo hidden/automático on-submit -->
                    <input type="hidden" id="f-valor">
                    
                    <button id="btn-save-func" class="btn btn-primary w-100 py-3 fw-bold fs-5 shadow-lg mt-2">
                        Sincronizar Arquivos no Banco Local
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- SCRIPTS E LIBS -->
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>

    <script>
        let funcionariosData = [];
        let modalInstancia = null;
        let filtroVinculoAtual = "";

        // Monta a string legada do leitor a partir dos campos atuais.
        // Usada tanto pelo modal de cadastro quanto pela aba de geração.
        function montarValorCracha(nome, funcao, rg, cpf, pis) {
            const partes = [nome];
            if (funcao) partes.push(funcao);
            if (rg) partes.push(rg);
            if (cpf) partes.push(cpf);
            if (pis) partes.push(pis);
            return nome + " | " + partes.join(" ; ");
        }

        // Grava (ou atualiza, se vier id) um colaborador. Devolve o registro salvo.
        function salvarFuncionario(payload) {
            return fetch('api.php?action=save', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            }).then(res => {
                if (!res.ok) throw new Error('HTTP ' + res.status);
                return res.json();
            }).then(res => {
                if (!res.success) throw new Error(res.error || 'Erro desconhecido');
                return res;
            });
        }

        $.fn.select2.defaults.set("theme", "default");

        function getModalInstancia() {
            if (!modalInstancia) {
                modalInstancia = new bootstrap.Modal(document.getElementById('funcModal'));
            }
            return modalInstancia;
        }

        // Listener Filter Bar
        $('#filtro-tabela-vinculo').on('change', function () {
            filtroVinculoAtual = $(this).val();
            renderTabela();
        });

        // preservarFormulario = true quando a recarga vem da própria aba de geração:
        // nesse caso não disparamos o change do select2, que zeraria os campos.
        function carregarDados(preservarFormulario) {
            return fetch('api.php?action=list')
                .then(res => res.json())
                .then(data => {
                    funcionariosData = data;

                    // Popula sempre o Select2 completo indepentente do filtro de Tabela
                    $('#select-funcionario').empty().append('<option value="">Selecione para auto-completação...</option>');
                    data.forEach(f => {
                        let badgeText = (f.vinculo && f.vinculo !== '') ? `[${f.vinculo.split(' ')[0]}] ` : '';
                        const option = new Option(badgeText + f.nome + (f.funcao ? " - " + f.funcao : ""), f.valor_cracha, false, false);
                        $(option).attr('data-id', f.id);
                        $('#select-funcionario').append(option);
                    });
                    if (!preservarFormulario) {
                        $('#select-funcionario').trigger('change');
                    }

                    renderTabela();
                });
        }

        function renderTabela() {
            const tbody = document.getElementById('tabela-funcionarios');
            tbody.innerHTML = '';

            let dadosParaTabela = funcionariosData;
            if (filtroVinculoAtual !== "") {
                dadosParaTabela = funcionariosData.filter(x => x.vinculo === filtroVinculoAtual);
            }

            if (dadosParaTabela.length === 0) {
                tbody.innerHTML = '<tr><td colspan="4" class="empty-state"><i class="ph ph-folder-open mb-3 fs-1 text-primary"></i><br>Nenhum colaborador preenchendo este requisito matriculado.</td></tr>';
                return;
            }

            dadosParaTabela.forEach(f => {
                let smallTags = '';
                if (f.funcao) smallTags += `<span class="badge bg-primary bg-opacity-25 border border-primary border-opacity-50 text-primary me-1 fw-normal">${f.funcao}</span>`;
                if (f.cpf) smallTags += `<span class="badge bg-secondary bg-opacity-25 border border-secondary border-opacity-50 text-secondary me-1 fw-normal">CPF ${f.cpf}</span>`;
                if (f.rg) smallTags += `<span class="badge bg-secondary bg-opacity-25 border border-secondary border-opacity-50 text-secondary fw-normal">RG ${f.rg}</span>`;

                let vinculoBadge = '';
                if (f.vinculo && f.vinculo !== '') {
                    let colorClass = 'bg-secondary border-secondary text-secondary';
                    if (f.vinculo.includes('Trans War')) colorClass = 'bg-success border-success text-success';
                    if (f.vinculo.includes('Terceiro')) colorClass = 'bg-warning border-warning text-warning';
                    if (f.vinculo.includes('Agregado')) colorClass = 'bg-info border-info text-info';
                    vinculoBadge = `<span class="badge ${colorClass} bg-opacity-25 border mb-2 px-2 py-1 fw-medium" style="font-size:0.65em; letter-spacing:1px; text-transform:uppercase;"><i class="ph ph-hard-drives me-1"></i>${f.vinculo}</span><br>`;
                }

                tbody.innerHTML += `
            <tr>
                <td class="text-secondary px-4">#${f.id}</td>
                <td>
                   ${vinculoBadge}
                   <div class="fw-bold text-white fs-6 mb-1">${f.nome}</div>
                   <div>${smallTags}</div>
                </td>
                <td class="font-monospace opacity-75" style="font-size:0.85em; color:#a7f3d0;">${f.valor_cracha}</td>
                <td class="px-4">
                    <div class="d-flex gap-2 justify-content-end">
                        <button class="btn btn-sm btn-dark border border-secondary border-opacity-25" onclick="editarFunc(${f.id})" title="Editar"><i class="ph ph-pencil-simple text-warning"></i> Editar</button>
                        <button class="btn btn-sm btn-dark border border-secondary border-opacity-25" onclick="excluirFunc(${f.id})" title="Remover"><i class="ph ph-trash text-danger"></i> Del</button>
                    </div>
                </td>
            </tr>
        `;
            });
        }

        // Init Libs
        $(document).ready(function () {
            
            // Formatador dinâmico global: Trim automático em todos inputs de texto do painel
            $('input[type="text"]').on('blur', function() {
                $(this).val($(this).val().trim());
            });

            $('#select-funcionario').select2({
                placeholder: "Pesquise usando nome ou cargo...",
                allowClear: true,
                width: '100%'
            });
            carregarDados();

            // Auto-populamento interativo inteligente
            $('#select-funcionario').on('change', function () {
                const id = $(this).find(':selected').attr('data-id');
                if (id) {
                    const func = funcionariosData.find(x => x.id == id);
                    if (func) {
                        let parsedFuncao = func.funcao || '';
                        let parsedRg = func.rg || '';
                        let parsedCpf = func.cpf || '';
                        let parsedPis = func.pis || '';

                        // Extrair dados do valor_cracha legado caso os campos estejam vazios
                        if (func.valor_cracha && !parsedFuncao && !parsedRg && !parsedCpf && !parsedPis) {
                            let separator = func.valor_cracha.includes(';') ? ';' : (func.valor_cracha.includes(' | ') ? ' | ' : null);
                            if (separator) {
                                let parts = func.valor_cracha.split(separator);
                                // O split no legacy é quase sempre [Nome, Função, RG, CPF, PIS]
                                if (parts.length > 1 && parts[1].trim() !== '') parsedFuncao = parts[1].trim();
                                if (parts.length > 2 && parts[2].trim() !== '') parsedRg = parts[2].trim();
                                if (parts.length > 3 && parts[3].trim() !== '') parsedCpf = parts[3].trim();
                                if (parts.length > 4 && parts[4].trim() !== '') parsedPis = parts[4].trim();
                            }
                        }

                        $('#g-nome').val(func.nome);
                        $('#g-valor-oculto').val(func.valor_cracha);
                        $('#g-id-oculto').val(func.id);
                        $('#g-vinculo').val(func.vinculo || '');
                        $('#g-funcao').val(parsedFuncao);
                        $('#g-rg').val(parsedRg);
                        $('#g-cpf').val(parsedCpf);
                        $('#g-pis').val(parsedPis);
                    }
                } else {
                    $('#g-nome').val('');
                    $('#g-valor-oculto').val('');
                    $('#g-id-oculto').val('');
                    $('#g-vinculo').val('');
                    $('#g-funcao').val('');
                    $('#g-rg').val('');
                    $('#g-cpf').val('');
                    $('#g-pis').val('');
                }
            });
        });

        // FUNÇÕES CRUD
        function abrirModalAdd() {
            document.getElementById('funcModalTitle').innerHTML = '<i class="ph ph-user-circle-plus me-2 text-primary fs-4 align-middle"></i>Inclusão de Funcionário';
            document.getElementById('f-id').value = '';
            document.getElementById('f-vinculo').value = '';
            document.getElementById('f-nome').value = '';
            document.getElementById('f-funcao').value = '';
            document.getElementById('f-rg').value = '';
            document.getElementById('f-cpf').value = '';
            document.getElementById('f-pis').value = '';
            document.getElementById('f-valor').value = '';
            getModalInstancia().show();
        }

        function editarFunc(id) {
            const f = funcionariosData.find(x => x.id === id);
            if (f) {
                document.getElementById('funcModalTitle').innerHTML = '<i class="ph ph-pencil-line me-2 text-warning fs-4 align-middle"></i>Alteração de Registro';
                document.getElementById('f-id').value = f.id;
                document.getElementById('f-vinculo').value = f.vinculo || '';
                document.getElementById('f-nome').value = f.nome || '';
                document.getElementById('f-valor').value = f.valor_cracha || '';

                let parsedFuncao = f.funcao || '';
                let parsedRg = f.rg || '';
                let parsedCpf = f.cpf || '';
                let parsedPis = f.pis || '';

                // Extrai dados da string caso os campos isolados não existam na base (legado)
                if (f.valor_cracha && !parsedFuncao && !parsedRg && !parsedCpf && !parsedPis) {
                    let separator = f.valor_cracha.includes(';') ? ';' : (f.valor_cracha.includes(' | ') ? ' | ' : null);
                    if (separator) {
                        let parts = f.valor_cracha.split(separator);
                        if (parts.length > 1 && parts[1].trim() !== '') parsedFuncao = parts[1].trim();
                        if (parts.length > 2 && parts[2].trim() !== '') parsedRg = parts[2].trim();
                        if (parts.length > 3 && parts[3].trim() !== '') parsedCpf = parts[3].trim();
                        if (parts.length > 4 && parts[4].trim() !== '') parsedPis = parts[4].trim();
                    }
                }

                document.getElementById('f-funcao').value = parsedFuncao;
                document.getElementById('f-rg').value = parsedRg;
                document.getElementById('f-cpf').value = parsedCpf;
                document.getElementById('f-pis').value = parsedPis;
                
                getModalInstancia().show();
            }
        }

        document.getElementById('btn-save-func').addEventListener('click', function (e) {
            let btnOrig = this.innerHTML;
            this.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Processando...';

            const id = document.getElementById('f-id').value;
            const nome = document.getElementById('f-nome').value.trim();
            const f_vinculo = document.getElementById('f-vinculo').value.trim();
            const f_funcao = document.getElementById('f-funcao').value.trim();
            const f_rg = document.getElementById('f-rg').value.trim();
            const f_cpf = document.getElementById('f-cpf').value.trim();
            const f_pis = document.getElementById('f-pis').value.trim();

            if (!nome) {
                alert("Preencha ao menos o Nome Curto/Display para gerar o crachá.");
                this.innerHTML = btnOrig;
                return;
            }

            // Geração da matriz do leitor silenciosa (montagem de legacy string com ;)
            const valorAutoGerado = montarValorCracha(nome, f_funcao, f_rg, f_cpf, f_pis);

            const payload = {
                nome: nome,
                valor_cracha: valorAutoGerado,
                vinculo: f_vinculo,
                funcao: f_funcao,
                rg: f_rg,
                cpf: f_cpf,
                pis: f_pis
            };
            if (id) payload.id = id;

            salvarFuncionario(payload).then(() => {
                this.innerHTML = btnOrig;
                getModalInstancia().hide();
                carregarDados();
            }).catch(err => {
                this.innerHTML = btnOrig;
                alert("Operação Abortada: " + err.message);
            });
        });

        function excluirFunc(id) {
            if (confirm("Confirmar exclusão definitiva?")) {
                fetch('api.php?action=delete', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ id: id })
                }).then(res => res.json()).then(res => {
                    if (res.success) carregarDados();
                });
            }
        }

        // MOTOR DO CRACHA - Geração Via JS -> AJAX PHP Render
        $('#btn-gerar').click(function (e) {
            e.preventDefault();

            const pNome = $('#g-nome').val().trim();
            const pId = $('#g-id-oculto').val().trim();
            const pVinculo = $('#g-vinculo').val().trim();
            const pFuncao = $('#g-funcao').val().trim();
            const pRg = $('#g-rg').val().trim();
            const pCpf = $('#g-cpf').val().trim();
            const pPis = $('#g-pis').val().trim();

            if (!pNome) {
                alert("O Nome Master do Crachá é obrigatório.");
                return;
            }

            // Sempre remonta a string a partir do que está na tela, senão uma
            // correção feita aqui (RG, CPF...) ficaria de fora do registro.
            const urlPayload = montarValorCracha(pNome, pFuncao, pRg, pCpf, pPis);

            $('#aqui').html(`
        <div class="text-center py-5">
            <div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status"></div>
            <p class="mt-4 fw-bold text-primary tracking-widest">Injetando Matriz Gráfica...</p>
        </div>
    `);

            function renderizarCracha() {
                $.ajax({
                    type: 'POST',
                    url: "geraQRcode.php",
                    data: {
                        texto: urlPayload,
                        arq: pNome,
                        vinculo: pVinculo,
                        funcao: pFuncao,
                        rg: pRg,
                        cpf: pCpf,
                        pis: pPis
                    },
                    success: function (data) {
                        $('#aqui').html(data);
                    },
                    error: function () {
                        $('#aqui').html('<div class="alert alert-danger shadow"><i class="ph ph-warning-circle fs-4 me-2 align-middle"></i>Falha no renderizador BaconQrCode.</div>');
                    }
                });
            }

            // Gerar também grava: registro selecionado é atualizado, nome novo
            // vira um cadastro novo. Antes essa aba não persistia nada.
            const payload = {
                nome: pNome,
                valor_cracha: urlPayload,
                vinculo: pVinculo,
                funcao: pFuncao,
                rg: pRg,
                cpf: pCpf,
                pis: pPis
            };

            let idAlvo = pId;
            if (!idAlvo) {
                // Evita duplicar quem já existe com o mesmo nome
                const existente = funcionariosData.find(x => (x.nome || '').trim().toUpperCase() === pNome.toUpperCase());
                if (existente) idAlvo = existente.id;
            }
            if (idAlvo) payload.id = idAlvo;

            salvarFuncionario(payload).then(res => {
                if (res.id) $('#g-id-oculto').val(res.id);
                carregarDados(true);
                renderizarCracha();
            }).catch(err => {
                $('#aqui').html('<div class="alert alert-danger shadow"><i class="ph ph-warning-circle fs-4 me-2 align-middle"></i>Não foi possível gravar no banco: ' + err.message + '</div>');
            });
        });

    </script>
</body>

</html>