"use client"; import { useState } from "react"; import { useUploadContext } from "../_context/upload-context"; import uploadApi from "@/shared/services/map-upload"; // Sesuaikan path ini import * as XLSX from 'xlsx'; import { toast } from "sonner"; // Helper untuk load PDF.js via CDN (Bypassing Webpack) const loadPdfJs = async () => { return new Promise((resolve, reject) => { if ((window as any).pdfjsLib) { resolve((window as any).pdfjsLib); return; } const script = document.createElement("script"); script.src = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"; script.async = true; script.onload = () => { const pdfjsLib = (window as any).pdfjsLib; pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js"; resolve(pdfjsLib); }; script.onerror = (err) => reject(err); document.body.appendChild(script); }); }; export function useUploadLogic() { const { state, setState, goToStep } = useUploadContext(); const [loading, setLoading] = useState(false); const handleFileSelect = async (file: File) => { setState((prev) => ({ ...prev, file, sheetNames: [], selectedSheet: null, pdfPageCount: null, selectedPages: [] })); const ext = file.name.split(".").pop()?.toLowerCase(); // A. JIKA FILE EXCEL if (ext === "xlsx" || ext === "xls") { try { const data = await file.arrayBuffer(); const workbook = XLSX.read(data, { type: 'array' }); const sheetNames = workbook.SheetNames; setState((prev) => ({ ...prev, sheetNames: sheetNames, selectedSheet: sheetNames.length === 1 ? sheetNames[0] : null })); if (sheetNames.length > 1) toast.info("Pilih sheet excel."); } catch (error) { console.error(error); toast.error("Gagal membaca file Excel."); } } // B. JIKA FILE PDF -> LOAD VIA CDN RUNTIME else if (ext === "pdf") { try { const pdfjsLib = await loadPdfJs(); const arrayBuffer = await file.arrayBuffer(); const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise; setState((prev) => ({ ...prev, pdfPageCount: pdf.numPages })); // Opsional: Beri info jika halaman banyak if (pdf.numPages > 1) { toast.info(`PDF terdeteksi memiliki ${pdf.numPages} halaman.`); } } catch (error) { console.error("Gagal baca PDF:", error); toast.error("Gagal membaca file PDF atau memuat library."); } } }; const resetFile = () => { setState(prev => ({ ...prev, file: null, fileDesc: "", sheetNames: [], selectedSheet: null, pdfPageCount: null, selectedPages: [] })); }; // 3. Logic Upload ke Backend const handleUploadProcess = async (selectedSheet?: string) => { if (!state.file) return; // Validasi Deskripsi if (!state.fileDesc) { toast.warning("Mohon isi deskripsi file terlebih dahulu."); return; } // Validasi Excel Sheet const isExcel = state.file.name.match(/\.(xlsx|xls)$/i); if (isExcel && state.sheetNames.length > 1 && !selectedSheet) { toast.warning("Mohon pilih sheet yang akan diproses."); return; } // 🔥 LOGIKA BARU: INTERCEPSI PDF MULTIPAGE const isPdf = state.file.name.match(/\.(pdf)$/i); if (isPdf && state.pdfPageCount && state.pdfPageCount > 1) { // Jangan upload dulu, arahkan ke Step 2 (PDF Viewer) goToStep("PDF_VIEWER"); toast.info("File memiliki beberapa halaman. Silakan pilih halaman yang akan diproses."); return; // 🛑 BERHENTI DI SINI } // --- PROSES UPLOAD LANGSUNG (Untuk Excel, CSV, atau PDF 1 Halaman) --- setLoading(true); try { const res = await uploadApi.uploadFile( state.file, state.selectedPages.length > 0 ? state.selectedPages : null, selectedSheet || state.selectedSheet || null, state.fileDesc ); setState((prev) => ({ ...prev, result: res })); // Routing Logic setelah response backend (untuk kasus PDF 1 halaman atau file lain) if (res.file_type === ".pdf" && res.tables && res.tables.length > 1) { goToStep("TABLE_PICKER"); toast.success("Beberapa tabel terdeteksi. Silakan pilih tabel."); } else if (res.file_type === ".pdf" && (!res.tables || res.tables.length === 0)) { // Fallback jika PDF 1 halaman tapi tidak ada tabel goToStep("PDF_VIEWER"); toast.info("Tabel tidak terdeteksi otomatis. Silakan pilih area manual."); } else if (res.data) { goToStep("VALIDATE"); toast.success("File berhasil diproses. Silakan validasi data."); } else { console.log(res); toast.warning(res.message) } } catch (err: any) { console.error(err); toast.error(err.message || "Gagal mengunggah file."); } finally { setLoading(false); } }; // 4. Logic Upload ke Database const handleSaveToDatabase = async (payload: any) => { setLoading(true); try { // Panggil API const res = await uploadApi.saveToDatabase(payload); // Simpan hasil final ke context setState(prev => ({ ...prev, validatedData: res })); // Pindah ke halaman sukses goToStep("SUCCESS"); } catch (err: any) { console.error(err); toast.error(err.message || "Gagal menyimpan data ke database."); } finally { setLoading(false); } }; return { ...state, loading, handleFileSelect, handleUploadProcess, handleSaveToDatabase, resetFile, setState, setFileDesc: (desc: string) => setState(prev => ({...prev, fileDesc: desc})), setSelectedSheet: (sheet: string) => setState(prev => ({...prev, selectedSheet: sheet})), }; }