    </main>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://unpkg.com/filepond@4/dist/filepond.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script src="<?= base_url('assets/vendor/datatables/jquery.dataTables.min.js') ?>"></script>
<script src="<?= base_url('assets/vendor/datatables/dataTables.bootstrap5.min.js') ?>"></script>
<script>
    const appSidebar = document.getElementById('appSidebar');
    const sidebarCollapseToggle = document.getElementById('sidebarCollapseToggle');
    const sidebarToggle = document.getElementById('sidebarToggle');
    const sidebarMenu = document.getElementById('sidebarMenu');
    let sidebarTooltips = [];

    const destroySidebarTooltips = function () {
        sidebarTooltips.forEach(function (tooltip) {
            tooltip.dispose();
        });
        sidebarTooltips = [];
    };

    const initSidebarTooltips = function () {
        destroySidebarTooltips();

        if (! appSidebar || ! appSidebar.classList.contains('is-collapsed') || ! window.bootstrap) {
            return;
        }

        sidebarTooltips = Array.from(appSidebar.querySelectorAll('.sidebar-link[data-bs-toggle="tooltip"]')).map(function (element) {
            return new bootstrap.Tooltip(element, {
                boundary: document.body,
                trigger: 'hover focus'
            });
        });
    };

    const setSidebarCollapsed = function (collapsed) {
        if (! appSidebar) {
            return;
        }

        appSidebar.classList.toggle('is-collapsed', collapsed);

        if (sidebarCollapseToggle) {
            const icon = sidebarCollapseToggle.querySelector('i');
            sidebarCollapseToggle.setAttribute('aria-label', collapsed ? 'Perbesar sidebar' : 'Perkecil sidebar');
            sidebarCollapseToggle.setAttribute('title', collapsed ? 'Perbesar sidebar' : 'Perkecil sidebar');

            if (icon) {
                icon.className = collapsed ? 'bi bi-layout-sidebar-inset-reverse' : 'bi bi-layout-sidebar-inset';
            }
        }

        initSidebarTooltips();
    };

    if (appSidebar) {
        setSidebarCollapsed(localStorage.getItem('sidebarCollapsed') === '1');
    }

    if (window.bootstrap) {
        document.querySelectorAll('[data-bs-toggle="popover"]').forEach(function (element) {
            new bootstrap.Popover(element);
        });
    }

    if (window.jQuery && $.fn.select2) {
        $('.select2').each(function () {
            const placeholder = this.dataset.placeholder || 'Pilih data';
            const modalParent = $(this).closest('.modal');
            const options = {
                width: '100%',
                placeholder: placeholder,
                allowClear: this.dataset.allowClear !== 'false'
            };

            if (modalParent.length) {
                options.dropdownParent = modalParent;
            }

            $(this).select2(options);
        });
    }

    if (sidebarCollapseToggle && appSidebar) {
        sidebarCollapseToggle.addEventListener('click', function () {
            const collapsed = ! appSidebar.classList.contains('is-collapsed');
            localStorage.setItem('sidebarCollapsed', collapsed ? '1' : '0');
            setSidebarCollapsed(collapsed);
        });
    }

    if (sidebarToggle && sidebarMenu) {
        sidebarToggle.addEventListener('click', function () {
            sidebarMenu.classList.toggle('show');
        });
    }

    if (window.FilePond) {
        const uploadStates = new WeakMap();

        const getFormState = function (form) {
            if (! uploadStates.has(form)) {
                uploadStates.set(form, new Map());
            }

            return uploadStates.get(form);
        };

        const updateSubmitState = function (form) {
            const hasBlockedUpload = Array.from(getFormState(form).values()).some(function (state) {
                return state === 'uploading' || state === 'error';
            });

            form.querySelectorAll('button[type="submit"]').forEach(function (button) {
                button.disabled = hasBlockedUpload;

                if (! button.dataset.originalText) {
                    button.dataset.originalText = button.innerHTML;
                }

                button.innerHTML = hasBlockedUpload ? 'Menunggu upload...' : button.dataset.originalText;
            });
        };

        const setUploadState = function (input, state) {
            const form = input.form;

            if (! form) {
                return;
            }

            getFormState(form).set(input, state);
            updateSubmitState(form);
        };

        document.querySelectorAll('input.filepond-upload').forEach(function (input) {
            if (input.disabled || ! input.form) {
                return;
            }

            const temporaryField = input.form.querySelector('input[name="' + input.dataset.tempField + '"]');
            const initialState = temporaryField && temporaryField.value ? 'ready' : 'idle';
            setUploadState(input, initialState);

            FilePond.create(input, {
                allowMultiple: false,
                instantUpload: true,
                labelIdle: 'Seret file atau <span class="filepond--label-action">pilih file</span>',
                labelFileProcessing: 'Mengupload',
                labelFileProcessingComplete: 'Upload selesai',
                labelFileProcessingError: 'Upload gagal',
                labelTapToCancel: 'batal',
                labelTapToRetry: 'ulangi',
                labelTapToUndo: 'hapus',
                server: {
                    process: function (fieldName, file, metadata, load, error, progress, abort) {
                        const request = new XMLHttpRequest();
                        const data = new FormData();

                        setUploadState(input, 'uploading');
                        data.append('upload', file, file.name);

                        request.open('POST', input.dataset.uploadUrl);
                        request.upload.onprogress = function (event) {
                            progress(event.lengthComputable, event.loaded, event.total);
                        };
                        request.onload = function () {
                            let response = {};

                            try {
                                response = JSON.parse(request.responseText);
                            } catch (parseError) {
                                response = {};
                            }

                            if (request.status >= 200 && request.status < 300 && response.token) {
                                if (temporaryField) {
                                    temporaryField.value = response.token;
                                }

                                setUploadState(input, 'ready');
                                load(response.token);
                                return;
                            }

                            if (temporaryField) {
                                temporaryField.value = '';
                            }

                            setUploadState(input, 'error');
                            error(response.message || 'Upload file gagal.');
                        };
                        request.onerror = function () {
                            if (temporaryField) {
                                temporaryField.value = '';
                            }

                            setUploadState(input, 'error');
                            error('Koneksi upload gagal.');
                        };
                        request.send(data);

                        return {
                            abort: function () {
                                request.abort();
                                setUploadState(input, 'idle');
                                abort();
                            }
                        };
                    },
                    revert: null,
                    restore: null,
                    load: null,
                    fetch: null
                },
                onprocessfilestart: function () {
                    setUploadState(input, 'uploading');
                },
                onprocessfiles: function () {
                    setUploadState(input, temporaryField && temporaryField.value ? 'ready' : 'idle');
                },
                onaddfilestart: function () {
                    setUploadState(input, 'uploading');
                },
                onprocessfile: function (error) {
                    setUploadState(input, error ? 'error' : 'ready');
                },
                onprocessfileabort: function () {
                    if (temporaryField) {
                        temporaryField.value = '';
                    }

                    setUploadState(input, 'idle');
                },
                onremovefile: function () {
                    if (temporaryField) {
                        temporaryField.value = '';
                    }

                    setUploadState(input, 'idle');
                }
            });
        });
    }

    if (window.jQuery && $.fn.DataTable) {
        try {
            $('table.datatable').each(function () {
                const table = this;
                const lastHeader = table.querySelector('thead th:last-child');
                const hasActionColumn = lastHeader && lastHeader.textContent.trim().toLowerCase() === 'aksi';
                const isReportTable = table.classList.contains('datatable-report');
                const columnDefs = [];

                if (hasActionColumn) {
                    columnDefs.push({
                        targets: -1,
                        searchable: false
                    });
                }

                const dataTableOptions = {
                    pageLength: 10,
                    ordering: false,
                    order: [],
                    paging: ! isReportTable,
                    searching: ! isReportTable,
                    info: ! isReportTable,
                    lengthMenu: [
                        [10, 25, 50, -1],
                        [10, 25, 50, 'Semua']
                    ],
                    columnDefs: columnDefs,
                    language: {
                        emptyTable: 'Belum ada data.',
                        info: 'Menampilkan _START_ sampai _END_ dari _TOTAL_ data',
                        infoEmpty: 'Menampilkan 0 data',
                        infoFiltered: '(difilter dari _MAX_ total data)',
                        lengthMenu: 'Tampilkan _MENU_ data',
                        loadingRecords: 'Memuat...',
                        processing: 'Memproses...',
                        search: 'Cari:',
                        zeroRecords: 'Data tidak ditemukan',
                        paginate: {
                            first: 'Pertama',
                            last: 'Terakhir',
                            next: 'Berikutnya',
                            previous: 'Sebelumnya'
                        }
                    }
                };

                $(table).DataTable(dataTableOptions);
            });
        } catch (error) {
            console.warn('DataTables gagal dimuat:', error);
        }
    }

    document.addEventListener('submit', function (event) {
        const form = event.target;

        if (! form || form.tagName !== 'FORM' || ! form.dataset.confirm) {
            return;
        }

        if (! window.confirm(form.dataset.confirm)) {
            event.preventDefault();
            event.stopImmediatePropagation();
        }
    });

</script>
</body>
</html>
